/*
* Copyright 2017 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.thoughtworks.go.domain;
import com.thoughtworks.go.config.CaseInsensitiveString;
import com.thoughtworks.go.config.materials.Filter;
import com.thoughtworks.go.config.materials.Materials;
import com.thoughtworks.go.config.materials.svn.SvnMaterial;
import com.thoughtworks.go.domain.materials.Modification;
import com.thoughtworks.go.domain.materials.Modifications;
import com.thoughtworks.go.domain.materials.ModifiedAction;
import com.thoughtworks.go.helper.MaterialsMother;
import com.thoughtworks.go.helper.ModificationsMother;
import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
import java.util.Map;
import static com.thoughtworks.go.helper.ModificationsMother.*;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
public class MaterialRevisionsTest {
private Modification yesterdayMod;
private Modification oneHourAgoMod;
private Modification nowMod;
private SvnMaterial material;
private static final String MOD_USER_COMMITTER = "committer";
private static final Filter FILTER_DOC_PDF = Filter.create("*.doc", "*.pdf");
@Before
public void setUp() {
nowMod = new Modification("user3", "fixed the build.", null, new DateTime().toDate(), "100");
nowMod.createModifiedFile("foo.java", ".", ModifiedAction.modified);
oneHourAgoMod = new Modification("user2", "fixed the build.", null, new DateTime().minusHours(1).toDate(), "89");
oneHourAgoMod.createModifiedFile("foo.java", ".", ModifiedAction.modified);
yesterdayMod = new Modification("user1", "fixed the build.", null, new DateTime().minusDays(1).toDate(), "9");
yesterdayMod.createModifiedFile("foo.java", ".", ModifiedAction.modified);
material = MaterialsMother.svnMaterial("foo");
material.setName(new CaseInsensitiveString("Foo"));
}
@Test
public void shouldReturnModificationsForAGivenMaterial() {
MaterialRevisions oneMaterialRevision = new MaterialRevisions(new MaterialRevision(material, yesterdayMod));
assertThat(oneMaterialRevision.getModifications(material), is(new Modifications(yesterdayMod)));
MaterialRevisions emptyMaterialRevision = new MaterialRevisions();
assertThat(emptyMaterialRevision.getModifications(material).isEmpty(), is(true));
MaterialRevisions differentMaterialRevision = new MaterialRevisions(new MaterialRevision(MaterialsMother.hgMaterial(), yesterdayMod));
assertThat(differentMaterialRevision.getModifications(material).isEmpty(), is(true));
}
@Test
public void shouldKnowDateOfLatestModification() {
//modifications are ordered, the first modification is the latest one
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(yesterdayMod, oneHourAgoMod)
);
assertThat(materialRevisions.getDateOfLatestModification(), is(yesterdayMod.getModifiedTime()));
}
@Test
public void shouldReturnMostRecentModifiedTimeIfExist() {
MaterialRevisions materialRevisions = multipleModifications();
assertThat(materialRevisions.getDateOfLatestModification(), is(ModificationsMother.TODAY_CHECKIN));
}
@Test
public void shouldReturnNullIfMostRecentModifiedTimeNotExist() {
MaterialRevisions materialRevisions = empty();
assertThat(materialRevisions.getDateOfLatestModification(), is(nullValue()));
}
@Test
public void shouldReturnOrginalChangeSet() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision("folder1", FILTER_DOC_PDF, aCheckIn("99", "/a.java")),
svnMaterialRevision("folder2", FILTER_DOC_PDF, aCheckIn("99", "/b.java"))
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision("folder1", FILTER_DOC_PDF, aCheckIn("100", "/a.doc"), aCheckIn("100", "/b.doc")),
svnMaterialRevision("folder2", FILTER_DOC_PDF, aCheckIn("100", "/a.pdf"))
);
assertThat(second.hasChangedSince(first), is(false));
}
@Test
public void shouldReturnLatestChangeSetForDependencyMaterial() {
Materials materials = new Materials(MaterialsMother.dependencyMaterial());
MaterialRevisions original = modifyOneFile(materials, "1");
MaterialRevisions newRevisions = modifyOneFile(materials, "2");
assertThat(newRevisions.hasChangedSince(original), is(true));
}
@Test
// #3122
public void shouldNotIgnoreChangesInUpstreamPipeline() {
MaterialRevisions original = new MaterialRevisions(dependencyMaterialRevision("cruise", 365, "1.3-365", "dist-zip", 1, new Date()));
MaterialRevisions current = new MaterialRevisions(dependencyMaterialRevision("cruise", 370, "1.3-370", "dist-zip", 1, new Date()));
assertThat(current.hasChangedSince(original), is(true));
}
@Test
public void shouldReturnLatestChangeSetIfAnyChangeSetShouldNotIgnore() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision("folder1", FILTER_DOC_PDF, aCheckIn("99", "/b.java")),
svnMaterialRevision("folder2", FILTER_DOC_PDF, aCheckIn("5", "/a.html"))
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision("folder1", FILTER_DOC_PDF, aCheckIn("100", "/a.doc"), aCheckIn("100", "/b.doc")),
svnMaterialRevision("folder2", FILTER_DOC_PDF, aCheckIn("5", "/a.html"))
);
assertThat(second.hasChangedSince(first), is(false));
}
@Test
public void shouldBeAbleToDetectWhenMaterialRevisionsHaveChanged() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision(oneHourAgoMod, yesterdayMod)
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision(nowMod)
);
assertThat(second.hasChangedSince(first), is(true));
}
@Test
public void shouldBeAbleToDetectWhenMaterialsDontMatch() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision("1", FILTER_DOC_PDF, oneHourAgoMod, yesterdayMod),
svnMaterialRevision("2", FILTER_DOC_PDF, nowMod)
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision("1", FILTER_DOC_PDF, oneHourAgoMod, yesterdayMod),
svnMaterialRevision("3", FILTER_DOC_PDF, nowMod)
);
assertThat(second.hasChangedSince(first), is(true));
}
@Test
public void shouldBeAbleToDetectWhenThereAreMultipleMaterials() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision(oneHourAgoMod, yesterdayMod)
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision(oneHourAgoMod, yesterdayMod),
svnMaterialRevision(nowMod)
);
assertThat(second.hasChangedSince(first), is(true));
}
@Test
public void shouldBeAbleToDetectWhenThereAreMultipleMaterialsInADifferentOrder() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision("1", FILTER_DOC_PDF, oneHourAgoMod, yesterdayMod),
svnMaterialRevision("2", FILTER_DOC_PDF, nowMod)
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision("2", FILTER_DOC_PDF, nowMod),
svnMaterialRevision("1", FILTER_DOC_PDF, oneHourAgoMod, yesterdayMod)
);
assertThat(second.hasChangedSince(first), is(false));
}
@Test
public void shouldNotBeAbleToAddANullModification() {
MaterialRevisions materialRevisions = empty();
try {
materialRevisions.addRevision(MaterialsMother.svnMaterial(), (Modification) null);
Assert.fail("Should not be able to add a null modification");
} catch (Exception ignored) {
}
}
@Test
public void shouldMatchByComment() {
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(aCheckIn("100", "README"))
);
assertThat(materialRevisions.containsMyCheckin(new Matcher("readme")), is(false));
}
@Test
public void shouldMatchCommentWhenCaseAreSame() {
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(aCheckIn("100", "README"))
);
assertThat(materialRevisions.containsMyCheckin(new Matcher("README")), is(true));
}
@Test
public void shouldMatchMultiLineComment() {
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(checkinWithComment("100", "Line1\nLine2\nLine3", "Committer1", EMAIL_ADDRESS, TODAY_CHECKIN, "README"))
);
assertThat(materialRevisions.containsMyCheckin(new Matcher("Committer1")), is(true));
assertThat(materialRevisions.containsMyCheckin(new Matcher("Line1")), is(true));
}
@Test
public void shouldMatchByUserName() {
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(aCheckIn("100", "README"))
);
assertThat(materialRevisions.containsMyCheckin(new Matcher(MOD_USER_COMMITTER)), is(true));
}
@Test
public void shouldNotMatchWhenUserNameDoesNotMatch() {
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(aCheckIn("100", "README"))
);
assertThat(materialRevisions.containsMyCheckin(new Matcher("someone")), is(false));
}
@Test
public void shouldNotMatchWhenMatcherIsNull() throws Exception {
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(aCheckIn("100", "README"))
);
assertThat(materialRevisions.containsMyCheckin(new Matcher((String) null)), is(false));
}
@Test
public void shouldReturnTrueIfOneUsernameMatchesInMutipleModifications() throws Exception {
MaterialRevisions materialRevisions = multipleModifications();
assertThat(materialRevisions.containsMyCheckin(new Matcher(MOD_USER_COMMITTER)), is(true));
}
@Test
public void shouldReturnTrueIfUsernameMatchesInOneOfMaterialRevisions() throws Exception {
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(aCheckIn("100", "test.txt")),
svnMaterialRevision(oneModifiedFile("revision"))
);
assertThat(materialRevisions.containsMyCheckin(new Matcher("Fixing")), is(true));
}
@Test
public void shouldReturnFalseWhenMatcherIsNotAlphaNumberic() throws Exception {
MaterialRevisions materialRevisions = multipleModifications();
assertThat(materialRevisions.containsMyCheckin(new Matcher("committer.*")), is(false));
}
@Test
public void shouldNotMatchMaterialRevisionsWhenEmailMeIsDisabled() throws Exception {
MaterialRevisions materialRevisions = multipleModifications();
assertThat(materialRevisions.containsMyCheckin(new Matcher(MOD_USER_COMMITTER)), is(true));
}
@Test
public void shouldBeSameIfHasSameHeads() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision(oneModifiedFile("revision2"), oneModifiedFile("revision1"))
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision(oneModifiedFile("revision2"))
);
assertThat(first.isSameAs(second), is(true));
}
@Test
public void shouldBeTheSameIfCurrentHasNoChanges() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision(oneModifiedFile("svn revision 2")),
hgMaterialRevision(oneModifiedFile("hg revision 1"))
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision(false, oneModifiedFile("svn revision 2")),
hgMaterialRevision(false, oneModifiedFile("hg revision 1"))
);
assertThat(first.isSameAs(second), is(true));
}
@Test public void shouldNotBeSameIfOneMaterialRevisionIsNew() throws Exception {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision(oneModifiedFile("svn revision 2"), oneModifiedFile("svn revision 1")),
hgMaterialRevision(oneModifiedFile("hg revision 1"))
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision(oneModifiedFile("svn revision 2")),
hgMaterialRevision(oneModifiedFile("hg revision 2"))
);
assertThat(first.isSameAs(second), is(false));
}
@Test public void shouldNotBeSameIfOneMaterialRevisionIsNewAndOldOneHadOnlyOneRevision() throws Exception {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision(oneModifiedFile("svn revision 2")),
hgMaterialRevision(oneModifiedFile("hg revision 1"))
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision(oneModifiedFile("svn revision 2")),
hgMaterialRevision(oneModifiedFile("hg revision 2"))
);
assertThat(first.isSameAs(second), is(false));
}
@Test
public void shouldNotBeSameOnNewModification() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision(oneModifiedFile("revision1"))
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision(oneModifiedFile("revision2"))
);
assertThat(first.isSameAs(second), is(false));
}
@Test
public void shouldNotBeSameIfMaterialsAreDifferent() {
MaterialRevisions first = new MaterialRevisions(
svnMaterialRevision("folder1", FILTER_DOC_PDF, oneModifiedFile("revision1"))
);
MaterialRevisions second = new MaterialRevisions(
svnMaterialRevision("folder2", FILTER_DOC_PDF, oneModifiedFile("revision1"))
);
assertThat(first.isSameAs(second), is(false));
}
@Test
public void shouldUseFirstMaterialAsBuildCauseMessage() throws Exception {
MaterialRevisions materialRevisions = madeChanges(new boolean[] {true, true},
oneModifiedFile("user1", "svnRev", TWO_DAYS_AGO_CHECKIN),
oneModifiedFile("user2", "hgRev", new Date()));
assertThat(materialRevisions.buildCauseMessage(), is("modified by user1"));
}
@Test
public void shouldUseFirstChangedMaterialAsBuildCauseMessage() throws Exception {
MaterialRevisions materialRevisions = madeChanges(new boolean[] {false, true},
oneModifiedFile("user1", "svnRev", TWO_DAYS_AGO_CHECKIN),
oneModifiedFile("user2", "hgRev", new Date()));
assertThat(materialRevisions.buildCauseMessage(), is("modified by user2"));
}
@Test
public void shouldUseFirstMaterialAsbuildCausedBy() throws Exception {
MaterialRevisions materialRevisions = madeChanges(new boolean[] {true, true},
oneModifiedFile("user1", "svnRev", TWO_DAYS_AGO_CHECKIN),
oneModifiedFile("user2", "hgRev", new Date()));
assertThat(materialRevisions.buildCausedBy(), is("user1"));
}
@Test
public void shouldUseFirstChangedMaterialAsbuildCausedBy() throws Exception {
MaterialRevisions materialRevisions = madeChanges(new boolean[] {false, true},
oneModifiedFile("user1", "svnRev", TWO_DAYS_AGO_CHECKIN),
oneModifiedFile("user2", "hgRev", new Date()));
assertThat(materialRevisions.buildCausedBy(), is("user2"));
}
@Test
public void shouldUseFirstMaterialAsbuildDate() throws Exception {
MaterialRevisions materialRevisions = madeChanges(new boolean[] {true, true},
oneModifiedFile("user1", "svnRev", TWO_DAYS_AGO_CHECKIN),
oneModifiedFile("user2", "hgRev", new Date()));
assertThat(materialRevisions.getDateOfLatestModification(), is(TWO_DAYS_AGO_CHECKIN));
}
@Test
public void shouldUseFirstChangedMaterialAsDate() throws Exception {
Date now = new Date();
MaterialRevisions materialRevisions = madeChanges(new boolean[] {false, true},
oneModifiedFile("user1", "svnRev", TWO_DAYS_AGO_CHECKIN),
oneModifiedFile("user2", "hgRev", now));
assertThat(materialRevisions.getDateOfLatestModification(), is(now));
}
@Test
public void shouldUseFirstMaterialAsLatestRevision() throws Exception {
MaterialRevisions materialRevisions = madeChanges(new boolean[] {true, true},
oneModifiedFile("user1", "Rev.1", TWO_DAYS_AGO_CHECKIN),
oneModifiedFile("user2", "Rev.2", new Date()));
assertThat(materialRevisions.latestRevision(), is("Rev.1"));
}
@Test
public void shouldUseFirstChangedMaterialAsLatestRevision() throws Exception {
Date now = new Date();
MaterialRevisions materialRevisions = madeChanges(new boolean[] {false, true},
oneModifiedFile("user1", "Rev.1", TWO_DAYS_AGO_CHECKIN),
oneModifiedFile("user2", "Rev.2", now));
assertThat(materialRevisions.latestRevision(), is("Rev.2"));
}
@Test
public void shouldReturnFirstLatestRevisionIfNoChanged() throws Exception {
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(yesterdayMod, oneHourAgoMod),
svnMaterialRevision(nowMod)
);
assertThat(materialRevisions.latestRevision(), is(yesterdayMod.getRevision()));
}
@Test
public void shouldReturnMapKeyedByGivenMaterialName() {
MaterialRevisions materialRevisions = new MaterialRevisions(
svnMaterialRevision(yesterdayMod, oneHourAgoMod)
);
assertThat(materialRevisions.getNamedRevisions().size(), is(1));
assertThat(materialRevisions.getNamedRevisions().get(new CaseInsensitiveString("Foo")), is("9"));
}
@Test
public void shouldNotAddMaterialWithEmptyNameIntoNamedRevisions() {
MaterialRevisions materialRevisions = new MaterialRevisions(
hgMaterialRevision(oneModifiedFile("hg revision 1"))
);
assertThat(materialRevisions.getNamedRevisions().size(), is(0));
}
@Test
public void shouldFindDependencyMaterialRevisionByPipelineName() {
MaterialRevision revision1 = dependencyMaterialRevision("cruise", 365, "1.3-365", "dist-zip", 1, new Date());
MaterialRevision revision2 = dependencyMaterialRevision("mingle", 370, "2.3-370", "dist-zip", 1, new Date());
MaterialRevisions materialRevisions = new MaterialRevisions(revision1, revision2);
assertThat(materialRevisions.findDependencyMaterialRevision("cruise"), is(revision1.getRevision()));
}
@Test
public void shouldFindDependencyMaterialRevisionByPipelineNameWhenCaseDoNotMatch() {
MaterialRevision revision1 = dependencyMaterialRevision("cruise", 365, "1.3-365", "dist-zip", 1, new Date());
MaterialRevision revision2 = dependencyMaterialRevision("mingle", 370, "2.3-370", "dist-zip", 1, new Date());
MaterialRevisions materialRevisions = new MaterialRevisions(revision1, revision2);
assertThat(materialRevisions.findDependencyMaterialRevision("cruise"), is(revision1.getRevision()));
assertThat(materialRevisions.findDependencyMaterialRevision("Cruise"), is(revision1.getRevision()));
assertThat(materialRevisions.findDependencyMaterialRevision("CRUISE"), is(revision1.getRevision()));
}
@Test
public void shouldReturnTrueForMissingModificationsForEmptyList() {
assertThat(new MaterialRevisions().isMissingModifications(),is(true));
}
@Test
public void shouldUseUpstreamPipelineLabelForDependencyMaterial() {
CaseInsensitiveString pipelineName = new CaseInsensitiveString("upstream");
String pipelineLabel = "1.3.0-1234";
MaterialRevision materialRevision = ModificationsMother.dependencyMaterialRevision(pipelineName.toString(), 2, pipelineLabel, "dev", 1, new Date());
MaterialRevisions materialRevisions = new MaterialRevisions(materialRevision);
Map<CaseInsensitiveString, String> namedRevisions = materialRevisions.getNamedRevisions();
assertThat(namedRevisions.get(pipelineName), is(pipelineLabel));
}
private MaterialRevisions madeChanges(boolean[] changed, Modification... modifications) {
MaterialRevisions materialRevisions = new MaterialRevisions();
for (int i = 0; i < modifications.length; i++) {
Modification modification = modifications[i];
materialRevisions.addRevision(new MaterialRevision(MaterialsMother.svnMaterial(), changed[i], modification));
}
return materialRevisions;
}
private MaterialRevision hgMaterialRevision(Modification... modifications) {
return new MaterialRevision(MaterialsMother.hgMaterial(), modifications);
}
private MaterialRevision hgMaterialRevision(boolean changed, Modification... modifications) {
return new MaterialRevision(MaterialsMother.hgMaterial(), changed, modifications);
}
private MaterialRevision svnMaterialRevision(Modification... modifications) {
return new MaterialRevision(material, modifications);
}
private MaterialRevision svnMaterialRevision(boolean changed, Modification... modifications) {
return new MaterialRevision(material, changed, modifications);
}
private MaterialRevision svnMaterialRevision(String folder, Filter filter, Modification... modifications) {
return new MaterialRevision(svnMaterial(folder, filter), modifications);
}
private SvnMaterial svnMaterial(String folder, Filter filter) {
SvnMaterial material = MaterialsMother.svnMaterial();
material.setFolder(folder);
material.setFilter(filter);
return material;
}
}