@@ -30,8 +30,13 @@ class AffectedModuleDetectorImplTest {
3030 @JvmField
3131 val tmpFolder2 = TemporaryFolder ()
3232
33+ @Rule
34+ @JvmField
35+ val tmpFolder3 = TemporaryFolder ()
36+
3337 private lateinit var root: Project
3438 private lateinit var root2: Project
39+ private lateinit var root3: Project
3540 private lateinit var p1: Project
3641 private lateinit var p2: Project
3742 private lateinit var p3: Project
@@ -44,6 +49,10 @@ class AffectedModuleDetectorImplTest {
4449 private lateinit var p10: Project
4550 private lateinit var p12: Project
4651 private lateinit var p13: Project
52+ private lateinit var p16: Project
53+ private lateinit var p17: Project
54+ private lateinit var p18: Project
55+ private lateinit var p19: Project
4756 private val pathsAffectingAllModules = setOf (
4857 convertToFilePath(" tools" , " android" , " buildSrc" ),
4958 convertToFilePath(" android" , " gradlew" ),
@@ -56,6 +65,7 @@ class AffectedModuleDetectorImplTest {
5665 fun init () {
5766 val tmpDir = tmpFolder.root
5867 val tmpDir2 = tmpFolder2.root
68+ val tmpDir3 = tmpFolder3.root
5969
6070 pathsAffectingAllModules.forEach {
6171 File (tmpDir, it).mkdirs()
@@ -66,21 +76,21 @@ class AffectedModuleDetectorImplTest {
6676 p: Gradle projects
6777
6878 Dummy project file tree:
69- "library modules" "UI modules"
70- tmpDir -------------- tmpDir2
71- / | \ | | | / \
72- d1 d7 d2 d8 d9 d10 d12 d13 (d10)
73- / \
74- d3 d5
79+ "library modules" "UI modules" "quixotic project "
80+ tmpDir -------------- tmpDir2 tmpDir3
81+ / | \ | | | / \ / | \
82+ d1 d7 d2 d8 d9 d10 d12 d13 (d10) d14 root3 d15
83+ / \ / / | \
84+ d3 d5 d16 d17 d18 d19
7585 / \
7686 d4 d6
7787
7888 Dependency forest:
79- root ------------------- root2
80- / \ | | | | / \
81- p1 p2 p7 p8 p9 p10 p12 p13
82- / / \
83- p3 --- p5 p6
89+ root ------------------- root2 root3 --------
90+ / \ | | | | / \ / | \ |
91+ p1 p2 p7 p8 p9 p10 p12 p13 p16 - | - p18 - p19
92+ / / \ \ |
93+ p3 --- p5 p6 p17
8494 /
8595 p4
8696
@@ -99,6 +109,12 @@ class AffectedModuleDetectorImplTest {
99109 .build()
100110 // Project Graph expects supportRootFolder.
101111 (root2.properties[" ext" ] as ExtraPropertiesExtension ).set(" supportRootFolder" , tmpDir2)
112+ root3 = ProjectBuilder .builder()
113+ .withProjectDir(tmpDir3.resolve(" root3" ))
114+ .withName(" root3" )
115+ .build()
116+ // Project Graph expects supportRootFolder.
117+ (root3.properties[" ext" ] as ExtraPropertiesExtension ).set(" supportRootFolder" , tmpDir3)
102118
103119 // Library modules
104120 p1 = ProjectBuilder .builder()
@@ -174,6 +190,36 @@ class AffectedModuleDetectorImplTest {
174190 .withParent(root2)
175191 .build()
176192
193+ // The quixotic project is a valid but highly unusual project set up consisting of common
194+ // modules and project flavours all (effectively) at the same level as the root project
195+ // directory and dependencies between them.
196+ p16 = ProjectBuilder .builder()
197+ .withProjectDir(tmpDir3.resolve(" d14/d16" ))
198+ .withName(" p16" )
199+ .withParent(root3)
200+ .build()
201+ p17 = ProjectBuilder .builder()
202+ .withProjectDir(tmpDir3.resolve(" d15/d17" ))
203+ .withName(" p17" )
204+ .withParent(root3)
205+ .build()
206+ val p17config = p17.configurations.create(" p17config" )
207+ p17config.dependencies.add(p17.dependencies.project(mutableMapOf (" path" to " :p16" )))
208+ p18 = ProjectBuilder .builder()
209+ .withProjectDir(tmpDir3.resolve(" d15/d18" ))
210+ .withName(" p18" )
211+ .withParent(root3)
212+ .build()
213+ val p18config = p18.configurations.create(" p18config" )
214+ p18config.dependencies.add(p18.dependencies.project(mutableMapOf (" path" to " :p16" )))
215+ p19 = ProjectBuilder .builder()
216+ .withProjectDir(tmpDir3.resolve(" d15/d19" ))
217+ .withName(" p19" )
218+ .withParent(root3)
219+ .build()
220+ val p19config = p19.configurations.create(" p19config" )
221+ p19config.dependencies.add(p19.dependencies.project(mutableMapOf (" path" to " :p18" )))
222+
177223 affectedModuleConfiguration = AffectedModuleConfiguration ().also {
178224 it.baseDir = tmpDir.absolutePath
179225 it.pathsAffectingAllModules = pathsAffectingAllModules
@@ -1005,7 +1051,14 @@ class AffectedModuleDetectorImplTest {
10051051 ignoreUnknownProjects = false ,
10061052 projectSubset = ProjectSubset .ALL_AFFECTED_PROJECTS ,
10071053 injectedGitClient = MockGitClient (
1008- changedFiles = listOf (convertToFilePath(" tools" , " android" , " buildSrc" , " sample.thing?" )),
1054+ changedFiles = listOf (
1055+ convertToFilePath(
1056+ " tools" ,
1057+ " android" ,
1058+ " buildSrc" ,
1059+ " sample.thing?"
1060+ )
1061+ ),
10091062 tmpFolder = tmpFolder.root
10101063 ),
10111064 config = affectedModuleConfiguration
@@ -1147,6 +1200,132 @@ class AffectedModuleDetectorImplTest {
11471200 )
11481201 }
11491202
1203+ @Test
1204+ fun noChangeCLs_quixotic () {
1205+ val detector = AffectedModuleDetectorImpl (
1206+ rootProject = root3,
1207+ logger = logger,
1208+ ignoreUnknownProjects = false ,
1209+ projectSubset = ProjectSubset .ALL_AFFECTED_PROJECTS ,
1210+ injectedGitClient = MockGitClient (
1211+ changedFiles = emptyList(),
1212+ tmpFolder = root3.projectDir
1213+ ),
1214+ config = affectedModuleConfiguration
1215+ )
1216+ MatcherAssert .assertThat(
1217+ detector.affectedProjects,
1218+ CoreMatchers .`is `(
1219+ setOf (p16, p17, p18, p19)
1220+ )
1221+ )
1222+ }
1223+
1224+ @Test
1225+ fun noChangeCLsOnlyDependent_quixotic () {
1226+ val detector = AffectedModuleDetectorImpl (
1227+ rootProject = root3,
1228+ logger = logger,
1229+ ignoreUnknownProjects = false ,
1230+ projectSubset = ProjectSubset .DEPENDENT_PROJECTS ,
1231+ injectedGitClient = MockGitClient (
1232+ changedFiles = emptyList(),
1233+ tmpFolder = root3.projectDir
1234+ ),
1235+ config = affectedModuleConfiguration
1236+ )
1237+ MatcherAssert .assertThat(
1238+ detector.affectedProjects,
1239+ CoreMatchers .`is `(
1240+ setOf (p16, p17, p18, p19)
1241+ )
1242+ )
1243+ }
1244+
1245+ @Test
1246+ fun noChangeCLsOnlyChanged_quixotic () {
1247+ val detector = AffectedModuleDetectorImpl (
1248+ rootProject = root3,
1249+ logger = logger,
1250+ ignoreUnknownProjects = false ,
1251+ projectSubset = ProjectSubset .CHANGED_PROJECTS ,
1252+ injectedGitClient = MockGitClient (
1253+ changedFiles = emptyList(),
1254+ tmpFolder = root3.projectDir
1255+ ),
1256+ config = affectedModuleConfiguration
1257+ )
1258+ MatcherAssert .assertThat(
1259+ detector.affectedProjects,
1260+ CoreMatchers .`is `(
1261+ emptySet()
1262+ )
1263+ )
1264+ }
1265+
1266+ @Test
1267+ fun changeInOne_quixotic_main_module () {
1268+ val detector = AffectedModuleDetectorImpl (
1269+ rootProject = root3,
1270+ logger = logger,
1271+ ignoreUnknownProjects = false ,
1272+ projectSubset = ProjectSubset .ALL_AFFECTED_PROJECTS ,
1273+ injectedGitClient = MockGitClient (
1274+ changedFiles = listOf (convertToFilePath(" d14" , " d16" , " foo.java" )),
1275+ tmpFolder = root3.projectDir
1276+ ),
1277+ config = affectedModuleConfiguration
1278+ )
1279+ MatcherAssert .assertThat(
1280+ detector.affectedProjects,
1281+ CoreMatchers .`is `(
1282+ setOf (p16, p17, p18, p19)
1283+ )
1284+ )
1285+ }
1286+
1287+ @Test
1288+ fun changeInOne_quixotic_common_module_with_a_dependency () {
1289+ val detector = AffectedModuleDetectorImpl (
1290+ rootProject = root3,
1291+ logger = logger,
1292+ ignoreUnknownProjects = false ,
1293+ projectSubset = ProjectSubset .ALL_AFFECTED_PROJECTS ,
1294+ injectedGitClient = MockGitClient (
1295+ changedFiles = listOf (convertToFilePath(" d15" , " d18" , " foo.java" )),
1296+ tmpFolder = root3.projectDir
1297+ ),
1298+ config = affectedModuleConfiguration
1299+ )
1300+ MatcherAssert .assertThat(
1301+ detector.affectedProjects,
1302+ CoreMatchers .`is `(
1303+ setOf (p18, p19)
1304+ )
1305+ )
1306+ }
1307+
1308+ @Test
1309+ fun changeInOne_quixotic_common_module_without_a_dependency () {
1310+ val detector = AffectedModuleDetectorImpl (
1311+ rootProject = root3,
1312+ logger = logger,
1313+ ignoreUnknownProjects = false ,
1314+ projectSubset = ProjectSubset .ALL_AFFECTED_PROJECTS ,
1315+ injectedGitClient = MockGitClient (
1316+ changedFiles = listOf (convertToFilePath(" d15" , " d19" , " foo.java" )),
1317+ tmpFolder = root3.projectDir
1318+ ),
1319+ config = affectedModuleConfiguration
1320+ )
1321+ MatcherAssert .assertThat(
1322+ detector.affectedProjects,
1323+ CoreMatchers .`is `(
1324+ setOf (p19)
1325+ )
1326+ )
1327+ }
1328+
11501329 @Test
11511330 fun `GIVEN affected module configuration WHEN invalid path THEN throw exception` () {
11521331 // GIVEN
@@ -1163,7 +1342,8 @@ class AffectedModuleDetectorImplTest {
11631342 fail(" Invalid state, should have thrown exception" )
11641343 } catch (e: IllegalArgumentException ) {
11651344 // THEN
1166- Truth .assertThat(" Could not find expected path in pathsAffectingAllModules: invalid" ).isEqualTo(e.message)
1345+ Truth .assertThat(" Could not find expected path in pathsAffectingAllModules: invalid" )
1346+ .isEqualTo(e.message)
11671347 }
11681348 }
11691349
0 commit comments