kintsugi 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -34,7 +34,6 @@ describe Kintsugi, :apply_change_to_project do
34
34
  changes_to_apply = get_diff(theirs_project, base_project)
35
35
 
36
36
  described_class.apply_change_to_project(base_project, changes_to_apply)
37
- base_project.save
38
37
 
39
38
  expect(base_project).to be_equivalent_to_project(theirs_project)
40
39
  end
@@ -46,7 +45,6 @@ describe Kintsugi, :apply_change_to_project do
46
45
  changes_to_apply = get_diff(theirs_project, base_project)
47
46
 
48
47
  described_class.apply_change_to_project(base_project, changes_to_apply)
49
- base_project.save
50
48
 
51
49
  expect(base_project).to be_equivalent_to_project(theirs_project)
52
50
  end
@@ -60,7 +58,6 @@ describe Kintsugi, :apply_change_to_project do
60
58
  changes_to_apply = get_diff(theirs_project, base_project)
61
59
 
62
60
  described_class.apply_change_to_project(base_project, changes_to_apply)
63
- base_project.save
64
61
 
65
62
  expect(base_project).to be_equivalent_to_project(theirs_project)
66
63
  end
@@ -72,29 +69,29 @@ describe Kintsugi, :apply_change_to_project do
72
69
  changes_to_apply = get_diff(theirs_project, base_project)
73
70
 
74
71
  described_class.apply_change_to_project(base_project, changes_to_apply)
75
- base_project.save
76
72
 
77
73
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
78
74
  end
79
75
 
80
- it "adds subproject that already exists" do
81
- theirs_project = create_copy_of_project(base_project.path, "theirs")
76
+ it "removes reference proxy from subproject with the same display name as another reference proxy" do
77
+ framework_filename = "baz"
78
+ subproject = add_new_subproject_to_project(base_project, "subproj", framework_filename)
82
79
 
83
- subproject = add_new_subproject_to_project(theirs_project, "foo", "foo")
84
- theirs_project.save
80
+ subproject.new_target("com.apple.product-type.library.static", framework_filename, :ios)
81
+ base_project.root_object.project_references[0][:product_group] <<
82
+ create_reference_proxy_from_product_reference(base_project,
83
+ base_project.root_object.project_references[0][:project_ref],
84
+ subproject.products_group.files[-1])
85
+ base_project.save
85
86
 
86
- ours_project = create_copy_of_project(base_project.path, "ours")
87
- add_existing_subproject_to_project(ours_project, subproject, "foo")
87
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
88
+ theirs_project.root_object.project_references[0][:product_group].children[-1].remove_from_project
88
89
 
89
90
  changes_to_apply = get_diff(theirs_project, base_project)
90
91
 
91
- described_class.apply_change_to_project(ours_project, changes_to_apply)
92
- ours_project.save
92
+ described_class.apply_change_to_project(base_project, changes_to_apply)
93
93
 
94
- expect(ours_project.root_object.project_references[0][:project_ref].uuid)
95
- .not_to equal(ours_project.root_object.project_references[1][:project_ref].uuid)
96
- expect(ours_project.root_object.project_references[0][:project_ref].proxy_containers).not_to be_empty
97
- expect(ours_project.root_object.project_references[1][:project_ref].proxy_containers).not_to be_empty
94
+ expect(base_project).to be_equivalent_to_project(theirs_project)
98
95
  end
99
96
 
100
97
  # Checks that the order the changes are applied in is correct.
@@ -110,7 +107,6 @@ describe Kintsugi, :apply_change_to_project do
110
107
  changes_to_apply = get_diff(theirs_project, base_project)
111
108
 
112
109
  described_class.apply_change_to_project(base_project, changes_to_apply)
113
- base_project.save
114
110
 
115
111
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
116
112
  end
@@ -152,11 +148,28 @@ describe Kintsugi, :apply_change_to_project do
152
148
  changes_to_apply = get_diff(theirs_project, base_project)
153
149
 
154
150
  described_class.apply_change_to_project(base_project, changes_to_apply)
155
- base_project.save
156
151
 
157
152
  expect(base_project).to be_equivalent_to_project(theirs_project)
158
153
  end
159
154
 
155
+ it "raises when a file is split into two" do
156
+ base_project.main_group.find_subpath("new_group", true)
157
+ base_project.main_group.find_subpath("new_group2", true)
158
+ base_project.save
159
+
160
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
161
+ new_group = theirs_project.main_group.find_subpath("new_group")
162
+ file_reference = theirs_project.main_group.find_file_by_path(filepath)
163
+ file_reference.move(new_group)
164
+ theirs_project.main_group.find_subpath("new_group2").new_reference(filepath)
165
+
166
+ changes_to_apply = get_diff(theirs_project, base_project)
167
+
168
+ expect {
169
+ described_class.apply_change_to_project(base_project, changes_to_apply)
170
+ }.to raise_error(Kintsugi::MergeError)
171
+ end
172
+
160
173
  it "adds file to new group" do
161
174
  theirs_project = create_copy_of_project(base_project.path, "theirs")
162
175
 
@@ -165,8 +178,21 @@ describe Kintsugi, :apply_change_to_project do
165
178
  changes_to_apply = get_diff(theirs_project, base_project)
166
179
 
167
180
  described_class.apply_change_to_project(base_project, changes_to_apply)
181
+
182
+ expect(base_project).to be_equivalent_to_project(theirs_project)
183
+ end
184
+
185
+ it "removes group" do
186
+ base_project.main_group.find_subpath("new_group", true)
168
187
  base_project.save
169
188
 
189
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
190
+ theirs_project["new_group"].remove_from_project
191
+
192
+ changes_to_apply = get_diff(theirs_project, base_project)
193
+
194
+ described_class.apply_change_to_project(base_project, changes_to_apply)
195
+
170
196
  expect(base_project).to be_equivalent_to_project(theirs_project)
171
197
  end
172
198
 
@@ -179,7 +205,6 @@ describe Kintsugi, :apply_change_to_project do
179
205
  changes_to_apply = get_diff(theirs_project, base_project)
180
206
 
181
207
  described_class.apply_change_to_project(base_project, changes_to_apply)
182
- base_project.save
183
208
 
184
209
  expect(base_project).to be_equivalent_to_project(theirs_project)
185
210
  end
@@ -203,7 +228,6 @@ describe Kintsugi, :apply_change_to_project do
203
228
  changes_to_apply = get_diff(theirs_project, base_project)
204
229
 
205
230
  described_class.apply_change_to_project(base_project, changes_to_apply)
206
- base_project.save
207
231
 
208
232
  expect(base_project).to be_equivalent_to_project(theirs_project)
209
233
  end
@@ -225,6 +249,22 @@ describe Kintsugi, :apply_change_to_project do
225
249
  expect(base_project).to be_equivalent_to_project(theirs_project)
226
250
  end
227
251
 
252
+ it "ignores removal of a non-existent group" do
253
+ base_project.main_group.find_subpath("new_group", true)
254
+ base_project.save
255
+
256
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
257
+ theirs_project.main_group.children.delete_at(-1)
258
+
259
+ changes_to_apply = get_diff(theirs_project, base_project)
260
+
261
+ base_project.main_group.children.delete_at(-1)
262
+
263
+ described_class.apply_change_to_project(base_project, changes_to_apply)
264
+
265
+ expect(base_project).to be_equivalent_to_project(theirs_project)
266
+ end
267
+
228
268
  it "removes build files of a removed file" do
229
269
  target = base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
230
270
  target.source_build_phase.add_file_reference(
@@ -244,7 +284,6 @@ describe Kintsugi, :apply_change_to_project do
244
284
  changes_to_apply = get_diff(theirs_project, base_project)
245
285
 
246
286
  described_class.apply_change_to_project(base_project, changes_to_apply)
247
- base_project.save
248
287
 
249
288
  expect(base_project).to be_equivalent_to_project(theirs_project)
250
289
  end
@@ -260,7 +299,6 @@ describe Kintsugi, :apply_change_to_project do
260
299
  changes_to_apply = get_diff(theirs_project, base_project)
261
300
 
262
301
  described_class.apply_change_to_project(base_project, changes_to_apply)
263
- base_project.save
264
302
 
265
303
  expect(base_project).to be_equivalent_to_project(theirs_project)
266
304
  end
@@ -275,25 +313,21 @@ describe Kintsugi, :apply_change_to_project do
275
313
  changes_to_apply = get_diff(theirs_project, base_project)
276
314
 
277
315
  described_class.apply_change_to_project(base_project, changes_to_apply)
278
- base_project.save
279
316
 
280
317
  expect(base_project).to be_equivalent_to_project(theirs_project)
281
318
  end
282
319
 
283
320
  it "handles moved file to an existing group with a different path on filesystem" do
284
321
  base_project.main_group.find_subpath("new_group", true).path = "some_path"
285
-
286
322
  base_project.save
287
- theirs_project = create_copy_of_project(base_project.path, "theirs")
288
323
 
324
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
289
325
  new_group = theirs_project.main_group.find_subpath("new_group")
290
-
291
326
  theirs_project.main_group.find_file_by_path(filepath).move(new_group)
292
327
 
293
328
  changes_to_apply = get_diff(theirs_project, base_project)
294
329
 
295
330
  described_class.apply_change_to_project(base_project, changes_to_apply)
296
- base_project.save
297
331
 
298
332
  expect(base_project).to be_equivalent_to_project(theirs_project)
299
333
  end
@@ -312,7 +346,6 @@ describe Kintsugi, :apply_change_to_project do
312
346
  ours_project_before_applying_changes = create_copy_of_project(ours_project.path, "ours")
313
347
 
314
348
  described_class.apply_change_to_project(ours_project, changes_to_apply)
315
- ours_project.save
316
349
 
317
350
  expect(ours_project).to be_equivalent_to_project(ours_project_before_applying_changes)
318
351
  end
@@ -330,7 +363,6 @@ describe Kintsugi, :apply_change_to_project do
330
363
  ours_project_before_applying_changes = create_copy_of_project(ours_project.path, "ours")
331
364
 
332
365
  described_class.apply_change_to_project(ours_project, changes_to_apply)
333
- ours_project.save
334
366
 
335
367
  expect(ours_project).to be_equivalent_to_project(ours_project_before_applying_changes)
336
368
  end
@@ -348,7 +380,6 @@ describe Kintsugi, :apply_change_to_project do
348
380
  ours_project_before_applying_changes = create_copy_of_project(ours_project.path, "ours")
349
381
 
350
382
  described_class.apply_change_to_project(ours_project, changes_to_apply)
351
- ours_project.save
352
383
 
353
384
  expect(ours_project).to be_equivalent_to_project(ours_project_before_applying_changes)
354
385
  end
@@ -363,7 +394,6 @@ describe Kintsugi, :apply_change_to_project do
363
394
  changes_to_apply = get_diff(theirs_project, base_project)
364
395
 
365
396
  described_class.apply_change_to_project(ours_project, changes_to_apply)
366
- ours_project.save
367
397
 
368
398
  expect(ours_project).to be_equivalent_to_project(theirs_project)
369
399
  end
@@ -377,6 +407,54 @@ describe Kintsugi, :apply_change_to_project do
377
407
  base_project.save
378
408
  end
379
409
 
410
+ it "moves file that is referenced by a target from main group to a new group" do
411
+ file_reference = base_project.main_group.new_reference("bar")
412
+ base_project.targets[0].source_build_phase.add_file_reference(file_reference)
413
+ base_project.save
414
+
415
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
416
+ new_group = theirs_project.main_group.find_subpath("new_group", true)
417
+ file_reference = theirs_project.main_group.find_file_by_path("bar")
418
+ file_reference.move(new_group)
419
+ changes_to_apply = get_diff(theirs_project, base_project)
420
+
421
+ described_class.apply_change_to_project(base_project, changes_to_apply)
422
+
423
+ expect(base_project).to be_equivalent_to_project(theirs_project)
424
+ end
425
+
426
+ it "moves file that is referenced by a target from a group to the main group" do
427
+ file_reference = base_project.main_group.find_subpath("new_group", true).new_reference("bar")
428
+ base_project.targets[0].source_build_phase.add_file_reference(file_reference)
429
+ base_project.save
430
+
431
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
432
+ file_reference = theirs_project["new_group/bar"]
433
+ file_reference.move(theirs_project.main_group)
434
+ changes_to_apply = get_diff(theirs_project, base_project)
435
+
436
+ described_class.apply_change_to_project(base_project, changes_to_apply)
437
+
438
+ expect(base_project).to be_equivalent_to_project(theirs_project)
439
+ end
440
+
441
+ it "moves file that is referenced by a target and has a different file encoding" do
442
+ file_reference = base_project.main_group.find_subpath("new_group", true).new_reference("bar")
443
+ target.frameworks_build_phase.add_file_reference(file_reference)
444
+ base_project.save
445
+
446
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
447
+ file_reference = theirs_project["new_group/bar"]
448
+ file_reference.move(theirs_project.main_group)
449
+ file_reference.fileEncoding = "4"
450
+
451
+ changes_to_apply = get_diff(theirs_project, base_project)
452
+
453
+ described_class.apply_change_to_project(base_project, changes_to_apply)
454
+
455
+ expect(base_project).to be_equivalent_to_project(theirs_project)
456
+ end
457
+
380
458
  it "changes framework from file reference to reference proxy" do
381
459
  framework_filename = "baz"
382
460
 
@@ -389,7 +467,7 @@ describe Kintsugi, :apply_change_to_project do
389
467
  theirs_project = create_copy_of_project(base_project.path, "theirs")
390
468
 
391
469
  build_phase = theirs_project.targets[0].frameworks_build_phase
392
- build_phase.files[0].remove_from_project
470
+ build_phase.files.find { |build_file| build_file.display_name == "baz" }.remove_from_project
393
471
  build_phase.add_file_reference(
394
472
  theirs_project.root_object.project_references[0][:product_group].children[0]
395
473
  )
@@ -397,7 +475,6 @@ describe Kintsugi, :apply_change_to_project do
397
475
  changes_to_apply = get_diff(theirs_project, base_project)
398
476
 
399
477
  described_class.apply_change_to_project(base_project, changes_to_apply)
400
- base_project.save
401
478
 
402
479
  expect(base_project).to be_equivalent_to_project(theirs_project)
403
480
  end
@@ -410,7 +487,6 @@ describe Kintsugi, :apply_change_to_project do
410
487
  changes_to_apply = get_diff(theirs_project, base_project)
411
488
 
412
489
  described_class.apply_change_to_project(base_project, changes_to_apply)
413
- base_project.save
414
490
 
415
491
  expect(base_project).to be_equivalent_to_project(theirs_project)
416
492
  end
@@ -427,7 +503,8 @@ describe Kintsugi, :apply_change_to_project do
427
503
 
428
504
  theirs_project = create_copy_of_project(base_project.path, "theirs")
429
505
 
430
- file_reference = theirs_project.main_group.new_reference(framework_filename)
506
+ file_reference = theirs_project.main_group.new_reference("bar")
507
+ file_reference.name = framework_filename
431
508
  build_phase = theirs_project.targets[0].frameworks_build_phase
432
509
  build_phase.files[-1].remove_from_project
433
510
  theirs_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
@@ -435,7 +512,10 @@ describe Kintsugi, :apply_change_to_project do
435
512
  changes_to_apply = get_diff(theirs_project, base_project)
436
513
 
437
514
  described_class.apply_change_to_project(base_project, changes_to_apply)
438
- base_project.save
515
+ # This verifies we haven't created a new file reference instead of reusing the one in the
516
+ # hierarchy.
517
+ base_project.files[-1].name = "foo"
518
+ theirs_project.files[-1].name = "foo"
439
519
 
440
520
  expect(base_project).to be_equivalent_to_project(theirs_project)
441
521
  end
@@ -462,7 +542,6 @@ describe Kintsugi, :apply_change_to_project do
462
542
  changes_to_apply["rootObject"].delete("projectReferences")
463
543
 
464
544
  described_class.apply_change_to_project(base_project, changes_to_apply)
465
- base_project.save
466
545
 
467
546
  expect(base_project).to be_equivalent_to_project(theirs_project)
468
547
  end
@@ -489,7 +568,6 @@ describe Kintsugi, :apply_change_to_project do
489
568
  changes_to_apply = get_diff(theirs_project, base_project)
490
569
 
491
570
  described_class.apply_change_to_project(base_project, changes_to_apply)
492
- base_project.save
493
571
 
494
572
  expect(base_project).to be_equivalent_to_project(theirs_project)
495
573
  end
@@ -506,7 +584,6 @@ describe Kintsugi, :apply_change_to_project do
506
584
  changes_to_apply = get_diff(theirs_project, base_project)
507
585
 
508
586
  described_class.apply_change_to_project(base_project, changes_to_apply)
509
- base_project.save
510
587
 
511
588
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
512
589
  end
@@ -526,16 +603,13 @@ describe Kintsugi, :apply_change_to_project do
526
603
  changes_to_apply = get_diff(theirs_project, base_project)
527
604
 
528
605
  described_class.apply_change_to_project(base_project, changes_to_apply)
529
- base_project.save
530
606
 
531
607
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
532
608
  end
533
609
 
534
- it "adds build file to a file reference that already exist" do
610
+ it "adds build file to a file reference that already exists" do
535
611
  base_project.main_group.new_reference("bar")
536
-
537
612
  base_project.main_group.new_reference("bar")
538
-
539
613
  base_project.save
540
614
 
541
615
  theirs_project = create_copy_of_project(base_project.path, "theirs")
@@ -549,17 +623,14 @@ describe Kintsugi, :apply_change_to_project do
549
623
  changes_to_apply = get_diff(theirs_project, base_project)
550
624
 
551
625
  described_class.apply_change_to_project(base_project, changes_to_apply)
552
- base_project.save
553
626
 
554
627
  expect(base_project).to be_equivalent_to_project(theirs_project)
555
628
  end
556
629
 
557
630
  it "adds file reference to build file" do
558
631
  file_reference = base_project.main_group.new_reference("bar")
559
-
560
632
  build_file = base_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
561
633
  build_file.file_ref = nil
562
-
563
634
  base_project.save
564
635
 
565
636
  theirs_project = create_copy_of_project(base_project.path, "theirs")
@@ -570,7 +641,6 @@ describe Kintsugi, :apply_change_to_project do
570
641
  changes_to_apply = get_diff(theirs_project, base_project)
571
642
 
572
643
  described_class.apply_change_to_project(base_project, changes_to_apply)
573
- base_project.save
574
644
 
575
645
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
576
646
  end
@@ -580,7 +650,6 @@ describe Kintsugi, :apply_change_to_project do
580
650
  base_project.save
581
651
 
582
652
  theirs_project = create_copy_of_project(base_project.path, "theirs")
583
-
584
653
  file_reference = theirs_project.main_group.files.find { |file| file.display_name == "bar" }
585
654
  build_file =
586
655
  theirs_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
@@ -590,7 +659,6 @@ describe Kintsugi, :apply_change_to_project do
590
659
 
591
660
  other_project = create_copy_of_project(base_project.path, "other")
592
661
  described_class.apply_change_to_project(other_project, changes_to_apply)
593
- other_project.save
594
662
 
595
663
  expect(other_project).to be_equivalent_to_project(base_project)
596
664
  end
@@ -616,7 +684,6 @@ describe Kintsugi, :apply_change_to_project do
616
684
  changes_to_apply = get_diff(theirs_project, base_project)
617
685
 
618
686
  described_class.apply_change_to_project(base_project, changes_to_apply)
619
- base_project.save
620
687
 
621
688
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
622
689
  end
@@ -632,7 +699,6 @@ describe Kintsugi, :apply_change_to_project do
632
699
  changes_to_apply = get_diff(theirs_project, base_project)
633
700
 
634
701
  described_class.apply_change_to_project(base_project, changes_to_apply)
635
- base_project.save
636
702
 
637
703
  expect(base_project).to be_equivalent_to_project(theirs_project)
638
704
  end
@@ -641,7 +707,6 @@ describe Kintsugi, :apply_change_to_project do
641
707
  base_project.targets[0].build_configurations.each do |configuration|
642
708
  configuration.build_settings = {}
643
709
  end
644
-
645
710
  theirs_project = create_copy_of_project(base_project.path, "theirs")
646
711
 
647
712
  theirs_project.targets[0].build_configurations.each do |configuration|
@@ -654,7 +719,6 @@ describe Kintsugi, :apply_change_to_project do
654
719
  changes_to_apply = get_diff(theirs_project, base_project)
655
720
 
656
721
  described_class.apply_change_to_project(base_project, changes_to_apply)
657
- base_project.save
658
722
 
659
723
  expect(base_project).to be_equivalent_to_project(theirs_project)
660
724
  end
@@ -672,7 +736,6 @@ describe Kintsugi, :apply_change_to_project do
672
736
  changes_to_apply = get_diff(theirs_project, base_project)
673
737
 
674
738
  described_class.apply_change_to_project(base_project, changes_to_apply)
675
- base_project.save
676
739
 
677
740
  expect(base_project).to be_equivalent_to_project(theirs_project)
678
741
  end
@@ -696,7 +759,6 @@ describe Kintsugi, :apply_change_to_project do
696
759
  changes_to_apply = get_diff(theirs_project, base_project)
697
760
 
698
761
  described_class.apply_change_to_project(base_project, changes_to_apply)
699
- base_project.save
700
762
 
701
763
  expect(base_project).to be_equivalent_to_project(theirs_project)
702
764
  end
@@ -713,10 +775,8 @@ describe Kintsugi, :apply_change_to_project do
713
775
  ours_project.targets[0].build_configurations.each do |configuration|
714
776
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
715
777
  end
716
- ours_project.save
717
778
 
718
779
  described_class.apply_change_to_project(ours_project, changes_to_apply)
719
- ours_project.save
720
780
 
721
781
  expected_project = create_copy_of_project(base_project.path, "expected")
722
782
  expected_project.targets[0].build_configurations.each do |configuration|
@@ -737,10 +797,8 @@ describe Kintsugi, :apply_change_to_project do
737
797
  ours_project.targets[0].build_configurations.each do |configuration|
738
798
  configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
739
799
  end
740
- ours_project.save
741
800
 
742
801
  described_class.apply_change_to_project(ours_project, changes_to_apply)
743
- ours_project.save
744
802
 
745
803
  expected_project = create_copy_of_project(base_project.path, "expected")
746
804
  expected_project.targets[0].build_configurations.each do |configuration|
@@ -756,10 +814,9 @@ describe Kintsugi, :apply_change_to_project do
756
814
  "$(SRCROOT)/../Bar"
757
815
  ]
758
816
  end
759
-
760
817
  base_project.save
761
- theirs_project = create_copy_of_project(base_project.path, "theirs")
762
818
 
819
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
763
820
  theirs_project.targets[0].build_configurations.each do |configuration|
764
821
  configuration.build_settings["HEADER_SEARCH_PATHS"] = nil
765
822
  end
@@ -767,7 +824,6 @@ describe Kintsugi, :apply_change_to_project do
767
824
  changes_to_apply = get_diff(theirs_project, base_project)
768
825
 
769
826
  described_class.apply_change_to_project(base_project, changes_to_apply)
770
- base_project.save
771
827
 
772
828
  expect(base_project).to be_equivalent_to_project(theirs_project)
773
829
  end
@@ -776,10 +832,9 @@ describe Kintsugi, :apply_change_to_project do
776
832
  base_project.targets[0].build_configurations.each do |configuration|
777
833
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
778
834
  end
779
-
780
835
  base_project.save
781
- theirs_project = create_copy_of_project(base_project.path, "theirs")
782
836
 
837
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
783
838
  theirs_project.targets[0].build_configurations.each do |configuration|
784
839
  configuration.build_settings =
785
840
  configuration.build_settings.reject { |key, _| key == "HEADER_SEARCH_PATHS" }
@@ -788,7 +843,6 @@ describe Kintsugi, :apply_change_to_project do
788
843
  changes_to_apply = get_diff(theirs_project, base_project)
789
844
 
790
845
  described_class.apply_change_to_project(base_project, changes_to_apply)
791
- base_project.save
792
846
 
793
847
  expect(base_project).to be_equivalent_to_project(theirs_project)
794
848
  end
@@ -797,8 +851,8 @@ describe Kintsugi, :apply_change_to_project do
797
851
  base_project.targets[0].build_configurations.each do |configuration|
798
852
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
799
853
  end
800
-
801
854
  base_project.save
855
+
802
856
  theirs_project = create_copy_of_project(base_project.path, "theirs")
803
857
  theirs_project.targets[0].build_configurations.each do |configuration|
804
858
  configuration.build_settings = nil
@@ -807,7 +861,6 @@ describe Kintsugi, :apply_change_to_project do
807
861
  changes_to_apply = get_diff(theirs_project, base_project)
808
862
 
809
863
  described_class.apply_change_to_project(base_project, changes_to_apply)
810
- base_project.save
811
864
 
812
865
  expect(base_project).to be_equivalent_to_project(theirs_project)
813
866
  end
@@ -817,8 +870,8 @@ describe Kintsugi, :apply_change_to_project do
817
870
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
818
871
  configuration.build_settings["foo"] = "baz"
819
872
  end
820
-
821
873
  base_project.save
874
+
822
875
  theirs_project = create_copy_of_project(base_project.path, "theirs")
823
876
  theirs_project.targets[0].build_configurations.each do |configuration|
824
877
  configuration.build_settings = nil
@@ -832,7 +885,6 @@ describe Kintsugi, :apply_change_to_project do
832
885
  changes_to_apply = get_diff(theirs_project, base_project)
833
886
 
834
887
  described_class.apply_change_to_project(base_project, changes_to_apply)
835
- base_project.save
836
888
 
837
889
  expect(base_project).to be_equivalent_to_project(theirs_project)
838
890
  end
@@ -853,7 +905,6 @@ describe Kintsugi, :apply_change_to_project do
853
905
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
854
906
 
855
907
  described_class.apply_change_to_project(base_project, changes_to_apply)
856
- base_project.save
857
908
 
858
909
  expect(base_project).to be_equivalent_to_project(theirs_project)
859
910
  end
@@ -874,7 +925,6 @@ describe Kintsugi, :apply_change_to_project do
874
925
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
875
926
 
876
927
  described_class.apply_change_to_project(base_project, changes_to_apply)
877
- base_project.save
878
928
 
879
929
  expect(base_project).to be_equivalent_to_project(theirs_project)
880
930
  end
@@ -935,10 +985,9 @@ describe Kintsugi, :apply_change_to_project do
935
985
  base_project.targets[0].build_configurations.each do |configuration|
936
986
  configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
937
987
  end
938
-
939
988
  base_project.save
940
- theirs_project = create_copy_of_project(base_project.path, "theirs")
941
989
 
990
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
942
991
  theirs_project.targets[0].build_configurations.each do |configuration|
943
992
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
944
993
  end
@@ -946,7 +995,6 @@ describe Kintsugi, :apply_change_to_project do
946
995
  changes_to_apply = get_diff(theirs_project, base_project)
947
996
 
948
997
  described_class.apply_change_to_project(base_project, changes_to_apply)
949
- base_project.save
950
998
 
951
999
  expect(base_project).to be_equivalent_to_project(theirs_project)
952
1000
  end
@@ -955,10 +1003,9 @@ describe Kintsugi, :apply_change_to_project do
955
1003
  base_project.targets[0].build_configurations.each do |configuration|
956
1004
  configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
957
1005
  end
958
-
959
1006
  base_project.save
960
- theirs_project = create_copy_of_project(base_project.path, "theirs")
961
1007
 
1008
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
962
1009
  theirs_project.targets[0].build_configurations.each do |configuration|
963
1010
  configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[baz foo]
964
1011
  end
@@ -966,7 +1013,6 @@ describe Kintsugi, :apply_change_to_project do
966
1013
  changes_to_apply = get_diff(theirs_project, base_project)
967
1014
 
968
1015
  described_class.apply_change_to_project(base_project, changes_to_apply)
969
- base_project.save
970
1016
 
971
1017
  expect(base_project).to be_equivalent_to_project(theirs_project)
972
1018
  end
@@ -993,7 +1039,6 @@ describe Kintsugi, :apply_change_to_project do
993
1039
  changes_to_apply = get_diff(theirs_project, before_theirs_project)
994
1040
 
995
1041
  described_class.apply_change_to_project(base_project, changes_to_apply)
996
- base_project.save
997
1042
 
998
1043
  expect(base_project).to be_equivalent_to_project(expected_project)
999
1044
  end
@@ -1057,23 +1102,32 @@ describe Kintsugi, :apply_change_to_project do
1057
1102
  changes_to_apply = get_diff(theirs_project, base_project)
1058
1103
 
1059
1104
  described_class.apply_change_to_project(base_project, changes_to_apply)
1060
- base_project.save
1105
+
1106
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1107
+ end
1108
+
1109
+ it "adds build phase with a simple attribute value that has non nil default" do
1110
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1111
+ theirs_project.targets[0].new_shell_script_build_phase("bar")
1112
+ theirs_project.targets[0].build_phases.last.shell_script = "Other value"
1113
+
1114
+ changes_to_apply = get_diff(theirs_project, base_project)
1115
+
1116
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1061
1117
 
1062
1118
  expect(base_project).to be_equivalent_to_project(theirs_project)
1063
1119
  end
1064
1120
 
1065
1121
  it "removes build phase" do
1066
1122
  base_project.targets[0].new_shell_script_build_phase("bar")
1067
-
1068
1123
  base_project.save
1069
- theirs_project = create_copy_of_project(base_project.path, "theirs")
1070
1124
 
1125
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1071
1126
  theirs_project.targets[0].shell_script_build_phases[0].remove_from_project
1072
1127
 
1073
1128
  changes_to_apply = get_diff(theirs_project, base_project)
1074
1129
 
1075
1130
  described_class.apply_change_to_project(base_project, changes_to_apply)
1076
- base_project.save
1077
1131
 
1078
1132
  expect(base_project).to be_equivalent_to_project(theirs_project)
1079
1133
  end
@@ -1083,33 +1137,29 @@ describe Kintsugi, :apply_change_to_project do
1083
1137
  file = variant_group.new_reference("Base")
1084
1138
  file.last_known_file_type = "text.plist.strings"
1085
1139
  target.resources_build_phase.add_file_reference(variant_group)
1086
-
1087
1140
  base_project.save
1088
- theirs_project = create_copy_of_project(base_project.path, "theirs")
1089
1141
 
1142
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1090
1143
  theirs_variant_group = theirs_project.main_group.find_subpath("foo.strings")
1091
1144
  theirs_variant_group.new_reference("en")
1092
1145
 
1093
1146
  changes_to_apply = get_diff(theirs_project, base_project)
1094
1147
 
1095
1148
  described_class.apply_change_to_project(base_project, changes_to_apply)
1096
- base_project.save
1097
1149
 
1098
1150
  expect(base_project).to be_equivalent_to_project(theirs_project)
1099
1151
  end
1100
1152
 
1101
1153
  it "adds target dependency" do
1102
1154
  base_project.new_target("com.apple.product-type.library.static", "bar", :ios)
1103
-
1104
1155
  base_project.save
1105
- theirs_project = create_copy_of_project(base_project.path, "theirs")
1106
1156
 
1157
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1107
1158
  theirs_project.targets[1].add_dependency(theirs_project.targets[0])
1108
1159
 
1109
1160
  changes_to_apply = get_diff(theirs_project, base_project)
1110
1161
 
1111
1162
  described_class.apply_change_to_project(base_project, changes_to_apply)
1112
- base_project.save
1113
1163
 
1114
1164
  expect(base_project).to be_equivalent_to_project(theirs_project)
1115
1165
  end
@@ -1118,10 +1168,9 @@ describe Kintsugi, :apply_change_to_project do
1118
1168
  base_project.targets[0].build_configurations.each do |configuration|
1119
1169
  configuration.build_settings["GCC_PREFIX_HEADER"] = "foo"
1120
1170
  end
1121
-
1122
1171
  base_project.save
1123
- theirs_project = create_copy_of_project(base_project.path, "theirs")
1124
1172
 
1173
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1125
1174
  theirs_project.targets[0].build_configurations.each do |configuration|
1126
1175
  configuration.build_settings["GCC_PREFIX_HEADER"] = "bar"
1127
1176
  end
@@ -1129,16 +1178,13 @@ describe Kintsugi, :apply_change_to_project do
1129
1178
  changes_to_apply = get_diff(theirs_project, base_project)
1130
1179
 
1131
1180
  described_class.apply_change_to_project(base_project, changes_to_apply)
1132
- base_project.save
1133
1181
 
1134
1182
  expect(base_project).to be_equivalent_to_project(theirs_project)
1135
1183
  end
1136
1184
 
1137
1185
  it "adds build settings to new target" do
1138
1186
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1139
-
1140
1187
  theirs_project.new_target("com.apple.product-type.library.static", "bar", :ios)
1141
-
1142
1188
  theirs_project.targets[1].build_configurations.each do |configuration|
1143
1189
  configuration.build_settings["GCC_PREFIX_HEADER"] = "baz"
1144
1190
  end
@@ -1146,7 +1192,6 @@ describe Kintsugi, :apply_change_to_project do
1146
1192
  changes_to_apply = get_diff(theirs_project, base_project)
1147
1193
 
1148
1194
  described_class.apply_change_to_project(base_project, changes_to_apply)
1149
- base_project.save
1150
1195
 
1151
1196
  expect(base_project).to be_equivalent_to_project(theirs_project)
1152
1197
  end
@@ -1155,7 +1200,6 @@ describe Kintsugi, :apply_change_to_project do
1155
1200
  base_project.main_group.new_reference("baz")
1156
1201
 
1157
1202
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1158
-
1159
1203
  configuration_reference = theirs_project.main_group.find_subpath("baz")
1160
1204
  theirs_project.targets[0].build_configurations.each do |configuration|
1161
1205
  configuration.base_configuration_reference = configuration_reference
@@ -1164,35 +1208,29 @@ describe Kintsugi, :apply_change_to_project do
1164
1208
  changes_to_apply = get_diff(theirs_project, base_project)
1165
1209
 
1166
1210
  described_class.apply_change_to_project(base_project, changes_to_apply)
1167
- base_project.save
1168
1211
 
1169
1212
  expect(base_project).to be_equivalent_to_project(theirs_project)
1170
1213
  end
1171
1214
  end
1172
1215
 
1173
1216
  it "adds known regions" do
1174
- base_project.save
1175
1217
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1176
-
1177
1218
  theirs_project.root_object.known_regions += ["fr"]
1178
1219
 
1179
1220
  changes_to_apply = get_diff(theirs_project, base_project)
1180
1221
 
1181
1222
  described_class.apply_change_to_project(base_project, changes_to_apply)
1182
- base_project.save
1183
1223
 
1184
1224
  expect(base_project).to be_equivalent_to_project(theirs_project)
1185
1225
  end
1186
1226
 
1187
1227
  it "removes known regions" do
1188
1228
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1189
-
1190
1229
  theirs_project.root_object.known_regions = nil
1191
1230
 
1192
1231
  changes_to_apply = get_diff(theirs_project, base_project)
1193
1232
 
1194
1233
  described_class.apply_change_to_project(base_project, changes_to_apply)
1195
- base_project.save
1196
1234
 
1197
1235
  expect(base_project).to be_equivalent_to_project(theirs_project)
1198
1236
  end
@@ -1206,7 +1244,6 @@ describe Kintsugi, :apply_change_to_project do
1206
1244
  changes_to_apply = get_diff(theirs_project, base_project)
1207
1245
 
1208
1246
  described_class.apply_change_to_project(base_project, changes_to_apply)
1209
- base_project.save
1210
1247
 
1211
1248
  expect(base_project).to be_equivalent_to_project(theirs_project)
1212
1249
  end
@@ -1216,14 +1253,12 @@ describe Kintsugi, :apply_change_to_project do
1216
1253
  base_project.save
1217
1254
 
1218
1255
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1219
-
1220
1256
  theirs_project.root_object.attributes["TargetAttributes"] =
1221
1257
  {"foo" => {"LastSwiftMigration" => "1140"}}
1222
1258
 
1223
1259
  changes_to_apply = get_diff(theirs_project, base_project)
1224
1260
 
1225
1261
  described_class.apply_change_to_project(base_project, changes_to_apply)
1226
- base_project.save
1227
1262
 
1228
1263
  expect(base_project).to be_equivalent_to_project(theirs_project)
1229
1264
  end
@@ -1233,14 +1268,12 @@ describe Kintsugi, :apply_change_to_project do
1233
1268
  base_project.save
1234
1269
 
1235
1270
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1236
-
1237
1271
  theirs_project.root_object.attributes["TargetAttributes"] =
1238
1272
  {"foo" => {"LastSwiftMigration" => "1140"}}
1239
1273
 
1240
1274
  changes_to_apply = get_diff(theirs_project, base_project)
1241
1275
 
1242
1276
  described_class.apply_change_to_project(base_project, changes_to_apply)
1243
- base_project.save
1244
1277
 
1245
1278
  expect(base_project).to be_equivalent_to_project(theirs_project)
1246
1279
  end
@@ -1251,13 +1284,11 @@ describe Kintsugi, :apply_change_to_project do
1251
1284
  base_project.save
1252
1285
 
1253
1286
  theirs_project = create_copy_of_project(base_project.path, "theirs")
1254
-
1255
1287
  theirs_project.root_object.attributes["TargetAttributes"]["foo"] = {}
1256
1288
 
1257
1289
  changes_to_apply = get_diff(theirs_project, base_project)
1258
1290
 
1259
1291
  described_class.apply_change_to_project(base_project, changes_to_apply)
1260
- base_project.save
1261
1292
 
1262
1293
  expect(base_project).to be_equivalent_to_project(theirs_project)
1263
1294
  end
@@ -1276,7 +1307,6 @@ describe Kintsugi, :apply_change_to_project do
1276
1307
  changes_to_apply = get_diff(theirs_project, base_project)
1277
1308
 
1278
1309
  described_class.apply_change_to_project(ours_project, changes_to_apply)
1279
- ours_project.save
1280
1310
 
1281
1311
  expect(ours_project).to be_equivalent_to_project(theirs_project)
1282
1312
  end
@@ -1294,7 +1324,6 @@ describe Kintsugi, :apply_change_to_project do
1294
1324
  changes_to_apply = get_diff(theirs_project, base_project)
1295
1325
 
1296
1326
  described_class.apply_change_to_project(ours_project, changes_to_apply)
1297
- ours_project.save
1298
1327
 
1299
1328
  expect(ours_project).to be_equivalent_to_project(theirs_project)
1300
1329
  end
@@ -1322,7 +1351,6 @@ describe Kintsugi, :apply_change_to_project do
1322
1351
  changes_to_apply = get_diff(ours_project, theirs_project)
1323
1352
 
1324
1353
  described_class.apply_change_to_project(base_project, changes_to_apply)
1325
- base_project.save
1326
1354
 
1327
1355
  expect(base_project).to be_equivalent_to_project(ours_project, ignore_keys: ["containerPortal"])
1328
1356
  end
@@ -1346,6 +1374,213 @@ describe Kintsugi, :apply_change_to_project do
1346
1374
  expect(base_project).to be_equivalent_to_project(theirs_project)
1347
1375
  end
1348
1376
 
1377
+ it "adds build configuration list" do
1378
+ base_project.root_object.build_configuration_list = nil
1379
+ base_project.save
1380
+
1381
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1382
+ theirs_project.root_object.build_configuration_list =
1383
+ theirs_project.new(Xcodeproj::Project::XCConfigurationList)
1384
+
1385
+ changes_to_apply = get_diff(theirs_project, base_project)
1386
+
1387
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1388
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1389
+ end
1390
+
1391
+ it "removes build configuration list" do
1392
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1393
+ theirs_project.build_configuration_list.remove_from_project
1394
+
1395
+ changes_to_apply = get_diff(theirs_project, base_project)
1396
+
1397
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1398
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1399
+ end
1400
+
1401
+ it "adds group to product group" do
1402
+ base_project_path = make_temp_directory("base", ".xcodeproj")
1403
+ base_project = Xcodeproj::Project.new(base_project_path)
1404
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1405
+
1406
+ base_project.save
1407
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1408
+
1409
+ theirs_project.root_object.product_ref_group.new_group("foo")
1410
+
1411
+ changes_to_apply = get_diff(theirs_project, base_project)
1412
+
1413
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1414
+
1415
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1416
+ end
1417
+
1418
+ it "adds localization files to product group" do
1419
+ base_project_path = make_temp_directory("base", ".xcodeproj")
1420
+ base_project = Xcodeproj::Project.new(base_project_path)
1421
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1422
+
1423
+ base_project.save
1424
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1425
+
1426
+ variant_group = theirs_project.root_object.product_ref_group.new_variant_group("foo.strings")
1427
+ variant_group.new_reference("Base").last_known_file_type = "text.plist.strings"
1428
+
1429
+ changes_to_apply = get_diff(theirs_project, base_project)
1430
+
1431
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1432
+
1433
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1434
+ end
1435
+
1436
+ describe "avoiding duplicate references to the same component" do
1437
+ it "avoids adding file reference that already exists" do
1438
+ base_project.main_group.new_reference("bar")
1439
+ base_project.save
1440
+
1441
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1442
+ theirs_project.main_group.new_reference("bar")
1443
+
1444
+ changes_to_apply = get_diff(theirs_project, base_project)
1445
+ other_project = create_copy_of_project(base_project.path, "theirs")
1446
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1447
+
1448
+ expect(other_project).to be_equivalent_to_project(base_project)
1449
+ end
1450
+
1451
+ it "avoids adding group that already exists" do
1452
+ base_project.main_group.new_group("bar")
1453
+ base_project.save
1454
+
1455
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1456
+ theirs_project.main_group.new_group("bar")
1457
+
1458
+ changes_to_apply = get_diff(theirs_project, base_project)
1459
+ other_project = create_copy_of_project(base_project.path, "theirs")
1460
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1461
+
1462
+ expect(other_project).to be_equivalent_to_project(base_project)
1463
+ end
1464
+
1465
+ it "avoids adding variant group that already exists" do
1466
+ base_project.main_group.new_variant_group("bar")
1467
+ base_project.save
1468
+
1469
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1470
+ theirs_project.main_group.new_variant_group("bar")
1471
+
1472
+ changes_to_apply = get_diff(theirs_project, base_project)
1473
+ other_project = create_copy_of_project(base_project.path, "theirs")
1474
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1475
+
1476
+ expect(other_project).to be_equivalent_to_project(base_project)
1477
+ end
1478
+
1479
+ it "avoids adding subproject that already exists" do
1480
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1481
+
1482
+ subproject = add_new_subproject_to_project(theirs_project, "foo", "foo")
1483
+
1484
+ ours_project = create_copy_of_project(base_project.path, "ours")
1485
+ add_existing_subproject_to_project(ours_project, subproject, "foo")
1486
+
1487
+ changes_to_apply = get_diff(theirs_project, base_project)
1488
+
1489
+ described_class.apply_change_to_project(ours_project, changes_to_apply)
1490
+
1491
+ expect(ours_project.root_object.project_references.count).to equal(1)
1492
+ end
1493
+
1494
+ it "avoids adding build file that already exists" do
1495
+ file_reference = base_project.main_group.new_reference("bar")
1496
+ target = base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1497
+ target.frameworks_build_phase.add_file_reference(file_reference)
1498
+ base_project.save
1499
+
1500
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1501
+ file_reference = theirs_project.main_group.new_reference("bar")
1502
+ theirs_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
1503
+
1504
+ changes_to_apply = get_diff(theirs_project, base_project)
1505
+ other_project = create_copy_of_project(base_project.path, "theirs")
1506
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1507
+
1508
+ expect(other_project).to be_equivalent_to_project(base_project)
1509
+ end
1510
+
1511
+ it "avoids adding reference proxy that already exists" do
1512
+ framework_filename = "baz"
1513
+ subproject = add_new_subproject_to_project(base_project, "subproj", framework_filename)
1514
+ base_project.save
1515
+
1516
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1517
+
1518
+ theirs_project.root_object.project_references[0][:product_group] <<
1519
+ create_reference_proxy_from_product_reference(theirs_project,
1520
+ theirs_project.root_object.project_references[0][:project_ref],
1521
+ subproject.products_group.files[-1])
1522
+
1523
+
1524
+ changes_to_apply = get_diff(theirs_project, base_project)
1525
+
1526
+ other_project = create_copy_of_project(base_project.path, "theirs")
1527
+ described_class.apply_change_to_project(other_project, changes_to_apply)
1528
+
1529
+ expect(other_project).to be_equivalent_to_project(base_project)
1530
+ end
1531
+
1532
+ it "keeps array if adding string value that already exists in array" do
1533
+ base_project.new_target("com.apple.product-type.library.static", "bar", :ios)
1534
+ base_project.save
1535
+
1536
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1537
+ theirs_project.targets[0].build_configurations.each do |configuration|
1538
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
1539
+ end
1540
+ changes_to_apply = get_diff(theirs_project, base_project)
1541
+
1542
+ ours_project = create_copy_of_project(base_project.path, "ours")
1543
+ ours_project.targets[0].build_configurations.each do |configuration|
1544
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
1545
+ end
1546
+ ours_project.save
1547
+
1548
+ expected_project = create_copy_of_project(ours_project.path, "expected")
1549
+
1550
+ described_class.apply_change_to_project(ours_project, changes_to_apply)
1551
+
1552
+ expect(ours_project).to be_equivalent_to_project(expected_project)
1553
+ end
1554
+ end
1555
+
1556
+ describe "allowing adding reference to the same component" do
1557
+ before do
1558
+ Kintsugi::Settings.allow_duplicates = true
1559
+ end
1560
+
1561
+ after do
1562
+ Kintsugi::Settings.allow_duplicates = false
1563
+ end
1564
+
1565
+ it "adds subproject that already exists" do
1566
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1567
+
1568
+ subproject = add_new_subproject_to_project(theirs_project, "foo", "foo")
1569
+
1570
+ ours_project = create_copy_of_project(base_project.path, "ours")
1571
+ add_existing_subproject_to_project(ours_project, subproject, "foo")
1572
+
1573
+ changes_to_apply = get_diff(theirs_project, base_project)
1574
+
1575
+ described_class.apply_change_to_project(ours_project, changes_to_apply)
1576
+
1577
+ expect(ours_project.root_object.project_references[0][:project_ref].uuid)
1578
+ .not_to equal(ours_project.root_object.project_references[1][:project_ref].uuid)
1579
+ expect(ours_project.root_object.project_references[0][:project_ref].proxy_containers).not_to be_empty
1580
+ expect(ours_project.root_object.project_references[1][:project_ref].proxy_containers).not_to be_empty
1581
+ end
1582
+ end
1583
+
1349
1584
  def create_copy_of_project(project_path, new_project_prefix)
1350
1585
  copied_project_path = make_temp_directory(new_project_prefix, ".xcodeproj")
1351
1586
  FileUtils.cp(File.join(project_path, "project.pbxproj"), copied_project_path)