kintsugi 0.4.3 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,7 @@ require "tempfile"
8
8
  require "tmpdir"
9
9
 
10
10
  require "kintsugi/apply_change_to_project"
11
+ require "kintsugi/error"
11
12
 
12
13
  require_relative "be_equivalent_to_project"
13
14
 
@@ -50,6 +51,20 @@ describe Kintsugi, :apply_change_to_project do
50
51
  expect(base_project).to be_equivalent_to_project(theirs_project)
51
52
  end
52
53
 
54
+ it "adds package reference" do
55
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
56
+
57
+ theirs_project.root_object.package_references <<
58
+ create_remote_swift_package_reference(theirs_project)
59
+
60
+ changes_to_apply = get_diff(theirs_project, base_project)
61
+
62
+ described_class.apply_change_to_project(base_project, changes_to_apply)
63
+ base_project.save
64
+
65
+ expect(base_project).to be_equivalent_to_project(theirs_project)
66
+ end
67
+
53
68
  it "adds new subproject" do
54
69
  theirs_project = create_copy_of_project(base_project.path, "theirs")
55
70
  add_new_subproject_to_project(theirs_project, "foo", "foo")
@@ -100,6 +115,23 @@ describe Kintsugi, :apply_change_to_project do
100
115
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
101
116
  end
102
117
 
118
+ it "raises if adding subproject whose file reference isn't found" do
119
+ ours_project = create_copy_of_project(base_project.path, "ours")
120
+
121
+ add_new_subproject_to_project(base_project, "foo", "foo")
122
+ base_project.save
123
+
124
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
125
+
126
+ base_project.root_object.project_references.pop
127
+
128
+ changes_to_apply = get_diff(theirs_project, base_project)
129
+
130
+ expect {
131
+ described_class.apply_change_to_project(ours_project, changes_to_apply)
132
+ }.to raise_error(Kintsugi::MergeError)
133
+ end
134
+
103
135
  describe "file related changes" do
104
136
  let(:filepath) { "foo" }
105
137
 
@@ -370,6 +402,19 @@ describe Kintsugi, :apply_change_to_project do
370
402
  expect(base_project).to be_equivalent_to_project(theirs_project)
371
403
  end
372
404
 
405
+ it "adds package product dependency to target" do
406
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
407
+ theirs_project.targets[0].package_product_dependencies <<
408
+ create_swift_package_product_dependency(theirs_project)
409
+
410
+ changes_to_apply = get_diff(theirs_project, base_project)
411
+
412
+ described_class.apply_change_to_project(base_project, changes_to_apply)
413
+ base_project.save
414
+
415
+ expect(base_project).to be_equivalent_to_project(theirs_project)
416
+ end
417
+
373
418
  it "changes framework from reference proxy to file reference" do
374
419
  framework_filename = "baz"
375
420
 
@@ -382,7 +427,8 @@ describe Kintsugi, :apply_change_to_project do
382
427
 
383
428
  theirs_project = create_copy_of_project(base_project.path, "theirs")
384
429
 
385
- file_reference = theirs_project.main_group.new_reference(framework_filename)
430
+ file_reference = theirs_project.main_group.new_reference("bar")
431
+ file_reference.name = framework_filename
386
432
  build_phase = theirs_project.targets[0].frameworks_build_phase
387
433
  build_phase.files[-1].remove_from_project
388
434
  theirs_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
@@ -390,6 +436,10 @@ describe Kintsugi, :apply_change_to_project do
390
436
  changes_to_apply = get_diff(theirs_project, base_project)
391
437
 
392
438
  described_class.apply_change_to_project(base_project, changes_to_apply)
439
+ # This verifies we haven't created a new file reference instead of reusing the one in the
440
+ # hierarchy.
441
+ base_project.files[-1].name = "foo"
442
+ theirs_project.files[-1].name = "foo"
393
443
  base_project.save
394
444
 
395
445
  expect(base_project).to be_equivalent_to_project(theirs_project)
@@ -466,9 +516,28 @@ describe Kintsugi, :apply_change_to_project do
466
516
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
467
517
  end
468
518
 
469
- it "adds build file to a file reference that already exist" do
470
- file_reference = base_project.main_group.new_reference("bar")
471
- base_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
519
+ it "adds product ref to build file" do
520
+ base_project.main_group.new_reference("bar")
521
+ base_project.save
522
+
523
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
524
+
525
+ file_reference = theirs_project.main_group.files.find { |file| file.display_name == "bar" }
526
+ build_file =
527
+ theirs_project.targets[0].frameworks_build_phase.add_file_reference(file_reference)
528
+ build_file.product_ref =
529
+ create_swift_package_product_dependency(theirs_project)
530
+
531
+ changes_to_apply = get_diff(theirs_project, base_project)
532
+
533
+ described_class.apply_change_to_project(base_project, changes_to_apply)
534
+ base_project.save
535
+
536
+ expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
537
+ end
538
+
539
+ it "adds build file to a file reference that already exists" do
540
+ base_project.main_group.new_reference("bar")
472
541
 
473
542
  base_project.main_group.new_reference("bar")
474
543
 
@@ -557,69 +626,427 @@ describe Kintsugi, :apply_change_to_project do
557
626
  expect(base_project).to be_equivalent_to_project(theirs_project, ignore_keys: ["containerPortal"])
558
627
  end
559
628
 
560
- it "adds new build setting" do
561
- theirs_project = create_copy_of_project(base_project.path, "theirs")
629
+ describe "build settings" do
630
+ it "adds new string build setting" do
631
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
562
632
 
563
- theirs_project.targets[0].build_configurations.each do |configuration|
564
- configuration.build_settings["HEADER_SEARCH_PATHS"] = [
565
- "$(SRCROOT)/../Foo",
566
- "$(SRCROOT)/../Bar"
567
- ]
633
+ theirs_project.targets[0].build_configurations.each do |configuration|
634
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "$(SRCROOT)/../Bar"
635
+ end
636
+
637
+ changes_to_apply = get_diff(theirs_project, base_project)
638
+
639
+ described_class.apply_change_to_project(base_project, changes_to_apply)
640
+ base_project.save
641
+
642
+ expect(base_project).to be_equivalent_to_project(theirs_project)
568
643
  end
569
644
 
570
- changes_to_apply = get_diff(theirs_project, base_project)
645
+ it "adds new array build setting" do
646
+ base_project.targets[0].build_configurations.each do |configuration|
647
+ configuration.build_settings = {}
648
+ end
571
649
 
572
- described_class.apply_change_to_project(base_project, changes_to_apply)
573
- base_project.save
650
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
574
651
 
575
- expect(base_project).to be_equivalent_to_project(theirs_project)
576
- end
652
+ theirs_project.targets[0].build_configurations.each do |configuration|
653
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = [
654
+ "$(SRCROOT)/../Foo",
655
+ "$(SRCROOT)/../Bar"
656
+ ]
657
+ end
577
658
 
578
- it "adds values to existing build setting" do
579
- base_project.targets[0].build_configurations.each do |configuration|
580
- configuration.build_settings["HEADER_SEARCH_PATHS"] = [
581
- "$(SRCROOT)/../Foo"
582
- ]
659
+ changes_to_apply = get_diff(theirs_project, base_project)
660
+
661
+ described_class.apply_change_to_project(base_project, changes_to_apply)
662
+ base_project.save
663
+
664
+ expect(base_project).to be_equivalent_to_project(theirs_project)
583
665
  end
584
666
 
585
- theirs_project = create_copy_of_project(base_project.path, "theirs")
667
+ it "adds new hash build setting" do
668
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
586
669
 
587
- theirs_project.targets[0].build_configurations.each do |configuration|
588
- configuration.build_settings["HEADER_SEARCH_PATHS"] = [
589
- "$(SRCROOT)/../Foo",
590
- "$(SRCROOT)/../Bar"
591
- ]
670
+ theirs_project.targets[0].build_configurations.each do |configuration|
671
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = [
672
+ "$(SRCROOT)/../Foo",
673
+ "$(SRCROOT)/../Bar"
674
+ ]
675
+ end
676
+
677
+ changes_to_apply = get_diff(theirs_project, base_project)
678
+
679
+ described_class.apply_change_to_project(base_project, changes_to_apply)
680
+ base_project.save
681
+
682
+ expect(base_project).to be_equivalent_to_project(theirs_project)
592
683
  end
593
684
 
594
- changes_to_apply = get_diff(theirs_project, base_project)
685
+ it "adds values to existing array build setting" do
686
+ base_project.targets[0].build_configurations.each do |configuration|
687
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = [
688
+ "$(SRCROOT)/../Foo"
689
+ ]
690
+ end
595
691
 
596
- described_class.apply_change_to_project(base_project, changes_to_apply)
597
- base_project.save
692
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
598
693
 
599
- expect(base_project).to be_equivalent_to_project(theirs_project)
600
- end
694
+ theirs_project.targets[0].build_configurations.each do |configuration|
695
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = [
696
+ "$(SRCROOT)/../Foo",
697
+ "$(SRCROOT)/../Bar"
698
+ ]
699
+ end
601
700
 
602
- it "removes build setting" do
603
- base_project.targets[0].build_configurations.each do |configuration|
604
- configuration.build_settings["HEADER_SEARCH_PATHS"] = [
605
- "$(SRCROOT)/../Foo",
606
- "$(SRCROOT)/../Bar"
607
- ]
701
+ changes_to_apply = get_diff(theirs_project, base_project)
702
+
703
+ described_class.apply_change_to_project(base_project, changes_to_apply)
704
+ base_project.save
705
+
706
+ expect(base_project).to be_equivalent_to_project(theirs_project)
608
707
  end
609
708
 
610
- base_project.save
611
- theirs_project = create_copy_of_project(base_project.path, "theirs")
709
+ it "adds array value to an existing string if no removed value" do
710
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
612
711
 
613
- theirs_project.targets[0].build_configurations.each do |configuration|
614
- configuration.build_settings["HEADER_SEARCH_PATHS"] = nil
712
+ theirs_project.targets[0].build_configurations.each do |configuration|
713
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
714
+ end
715
+ changes_to_apply = get_diff(theirs_project, base_project)
716
+
717
+ ours_project = create_copy_of_project(base_project.path, "ours")
718
+ ours_project.targets[0].build_configurations.each do |configuration|
719
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
720
+ end
721
+ ours_project.save
722
+
723
+ described_class.apply_change_to_project(ours_project, changes_to_apply)
724
+ ours_project.save
725
+
726
+ expected_project = create_copy_of_project(base_project.path, "expected")
727
+ expected_project.targets[0].build_configurations.each do |configuration|
728
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo baz]
729
+ end
730
+ expect(ours_project).to be_equivalent_to_project(expected_project)
615
731
  end
616
732
 
617
- changes_to_apply = get_diff(theirs_project, base_project)
733
+ it "adds string value to existing array value if no removed value" do
734
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
618
735
 
619
- described_class.apply_change_to_project(base_project, changes_to_apply)
620
- base_project.save
736
+ theirs_project.targets[0].build_configurations.each do |configuration|
737
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
738
+ end
739
+ changes_to_apply = get_diff(theirs_project, base_project)
621
740
 
622
- expect(base_project).to be_equivalent_to_project(theirs_project)
741
+ ours_project = create_copy_of_project(base_project.path, "ours")
742
+ ours_project.targets[0].build_configurations.each do |configuration|
743
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
744
+ end
745
+ ours_project.save
746
+
747
+ described_class.apply_change_to_project(ours_project, changes_to_apply)
748
+ ours_project.save
749
+
750
+ expected_project = create_copy_of_project(base_project.path, "expected")
751
+ expected_project.targets[0].build_configurations.each do |configuration|
752
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo baz]
753
+ end
754
+ expect(ours_project).to be_equivalent_to_project(expected_project)
755
+ end
756
+
757
+ it "removes array build setting" do
758
+ base_project.targets[0].build_configurations.each do |configuration|
759
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = [
760
+ "$(SRCROOT)/../Foo",
761
+ "$(SRCROOT)/../Bar"
762
+ ]
763
+ end
764
+
765
+ base_project.save
766
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
767
+
768
+ theirs_project.targets[0].build_configurations.each do |configuration|
769
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = nil
770
+ end
771
+
772
+ changes_to_apply = get_diff(theirs_project, base_project)
773
+
774
+ described_class.apply_change_to_project(base_project, changes_to_apply)
775
+ base_project.save
776
+
777
+ expect(base_project).to be_equivalent_to_project(theirs_project)
778
+ end
779
+
780
+ it "removes string build setting" do
781
+ base_project.targets[0].build_configurations.each do |configuration|
782
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
783
+ end
784
+
785
+ base_project.save
786
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
787
+
788
+ theirs_project.targets[0].build_configurations.each do |configuration|
789
+ configuration.build_settings =
790
+ configuration.build_settings.reject { |key, _| key == "HEADER_SEARCH_PATHS" }
791
+ end
792
+
793
+ changes_to_apply = get_diff(theirs_project, base_project)
794
+
795
+ described_class.apply_change_to_project(base_project, changes_to_apply)
796
+ base_project.save
797
+
798
+ expect(base_project).to be_equivalent_to_project(theirs_project)
799
+ end
800
+
801
+ it "removes hash build setting" do
802
+ base_project.targets[0].build_configurations.each do |configuration|
803
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
804
+ end
805
+
806
+ base_project.save
807
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
808
+ theirs_project.targets[0].build_configurations.each do |configuration|
809
+ configuration.build_settings = nil
810
+ end
811
+
812
+ changes_to_apply = get_diff(theirs_project, base_project)
813
+
814
+ described_class.apply_change_to_project(base_project, changes_to_apply)
815
+ base_project.save
816
+
817
+ expect(base_project).to be_equivalent_to_project(theirs_project)
818
+ end
819
+
820
+ it "removes hash build setting if removed hash contains the existing hash" do
821
+ base_project.targets[0].build_configurations.each do |configuration|
822
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
823
+ configuration.build_settings["foo"] = "baz"
824
+ end
825
+
826
+ base_project.save
827
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
828
+ theirs_project.targets[0].build_configurations.each do |configuration|
829
+ configuration.build_settings = nil
830
+ end
831
+
832
+ ours_project = create_copy_of_project(base_project.path, "theirs")
833
+ ours_project.targets[0].build_configurations.each do |configuration|
834
+ configuration.build_settings["foo"] = nil
835
+ end
836
+
837
+ changes_to_apply = get_diff(theirs_project, base_project)
838
+
839
+ described_class.apply_change_to_project(base_project, changes_to_apply)
840
+ base_project.save
841
+
842
+ expect(base_project).to be_equivalent_to_project(theirs_project)
843
+ end
844
+
845
+ it "removes value if existing is string and removed is array that contains it" do
846
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
847
+
848
+ base_project.targets[0].build_configurations.each do |configuration|
849
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
850
+ end
851
+ base_project.save
852
+
853
+ before_theirs_project = create_copy_of_project(base_project.path, "before_theirs")
854
+ before_theirs_project.targets[0].build_configurations.each do |configuration|
855
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = ["bar"]
856
+ end
857
+
858
+ changes_to_apply = get_diff(theirs_project, before_theirs_project)
859
+
860
+ described_class.apply_change_to_project(base_project, changes_to_apply)
861
+ base_project.save
862
+
863
+ expect(base_project).to be_equivalent_to_project(theirs_project)
864
+ end
865
+
866
+ it "removes value if removed value is string and existing is array that contains it" do
867
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
868
+
869
+ base_project.targets[0].build_configurations.each do |configuration|
870
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = ["bar"]
871
+ end
872
+ base_project.save
873
+
874
+ before_theirs_project = create_copy_of_project(base_project.path, "before_theirs")
875
+ before_theirs_project.targets[0].build_configurations.each do |configuration|
876
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
877
+ end
878
+
879
+ changes_to_apply = get_diff(theirs_project, before_theirs_project)
880
+
881
+ described_class.apply_change_to_project(base_project, changes_to_apply)
882
+ base_project.save
883
+
884
+ expect(base_project).to be_equivalent_to_project(theirs_project)
885
+ end
886
+
887
+ it "removes value if existing is string and removed is array that contains it among other " \
888
+ "values" do
889
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
890
+
891
+ base_project.targets[0].build_configurations.each do |configuration|
892
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
893
+ end
894
+ base_project.save
895
+
896
+ before_theirs_project = create_copy_of_project(base_project.path, "before_theirs")
897
+ before_theirs_project.targets[0].build_configurations.each do |configuration|
898
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar baz]
899
+ end
900
+
901
+ changes_to_apply = get_diff(theirs_project, before_theirs_project)
902
+
903
+ described_class.apply_change_to_project(base_project, changes_to_apply)
904
+ base_project.save
905
+
906
+ expected_project = create_copy_of_project(base_project.path, "expected")
907
+ expected_project.targets[0].build_configurations.each do |configuration|
908
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = nil
909
+ end
910
+ expect(base_project).to be_equivalent_to_project(expected_project)
911
+ end
912
+
913
+ it "changes to a single string value if removed is string and existing is array that " \
914
+ "contains it among another value" do
915
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
916
+
917
+ base_project.targets[0].build_configurations.each do |configuration|
918
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar baz]
919
+ end
920
+ base_project.save
921
+
922
+ before_theirs_project = create_copy_of_project(base_project.path, "before_theirs")
923
+ before_theirs_project.targets[0].build_configurations.each do |configuration|
924
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
925
+ end
926
+
927
+ changes_to_apply = get_diff(theirs_project, before_theirs_project)
928
+
929
+ described_class.apply_change_to_project(base_project, changes_to_apply)
930
+ base_project.save
931
+
932
+ expected_project = create_copy_of_project(base_project.path, "expected")
933
+ expected_project.targets[0].build_configurations.each do |configuration|
934
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
935
+ end
936
+ expect(base_project).to be_equivalent_to_project(expected_project)
937
+ end
938
+
939
+ it "changes to string value if change contains removal of existing array" do
940
+ base_project.targets[0].build_configurations.each do |configuration|
941
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar foo]
942
+ end
943
+
944
+ base_project.save
945
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
946
+
947
+ theirs_project.targets[0].build_configurations.each do |configuration|
948
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
949
+ end
950
+
951
+ changes_to_apply = get_diff(theirs_project, base_project)
952
+
953
+ described_class.apply_change_to_project(base_project, changes_to_apply)
954
+ base_project.save
955
+
956
+ expect(base_project).to be_equivalent_to_project(theirs_project)
957
+ end
958
+
959
+ it "changes to array value if change contains removal of existing string" do
960
+ base_project.targets[0].build_configurations.each do |configuration|
961
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
962
+ end
963
+
964
+ base_project.save
965
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
966
+
967
+ theirs_project.targets[0].build_configurations.each do |configuration|
968
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[baz foo]
969
+ end
970
+
971
+ changes_to_apply = get_diff(theirs_project, base_project)
972
+
973
+ described_class.apply_change_to_project(base_project, changes_to_apply)
974
+ base_project.save
975
+
976
+ expect(base_project).to be_equivalent_to_project(theirs_project)
977
+ end
978
+
979
+ it "changes to array if added value is string and existing is another string and removal is" \
980
+ "nil for an array build setting" do
981
+ before_theirs_project = create_copy_of_project(base_project.path, "theirs")
982
+
983
+ base_project.targets[0].build_configurations.each do |configuration|
984
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
985
+ end
986
+ base_project.save
987
+
988
+ theirs_project = create_copy_of_project(base_project.path, "before_theirs")
989
+ theirs_project.targets[0].build_configurations.each do |configuration|
990
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
991
+ end
992
+
993
+ expected_project = create_copy_of_project(base_project.path, "expected")
994
+ expected_project.targets[0].build_configurations.each do |configuration|
995
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = %w[bar baz]
996
+ end
997
+
998
+ changes_to_apply = get_diff(theirs_project, before_theirs_project)
999
+
1000
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1001
+ base_project.save
1002
+
1003
+ expect(base_project).to be_equivalent_to_project(expected_project)
1004
+ end
1005
+
1006
+ it "raises if added value is string and existing is another string and removal is nil for a " \
1007
+ "string build setting" do
1008
+ before_theirs_project = create_copy_of_project(base_project.path, "theirs")
1009
+
1010
+ base_project.targets[0].build_configurations.each do |configuration|
1011
+ configuration.build_settings["PRODUCT_NAME"] = "bar"
1012
+ end
1013
+ base_project.save
1014
+
1015
+ theirs_project = create_copy_of_project(base_project.path, "before_theirs")
1016
+ theirs_project.targets[0].build_configurations.each do |configuration|
1017
+ configuration.build_settings["PRODUCT_NAME"] = "baz"
1018
+ end
1019
+
1020
+ changes_to_apply = get_diff(theirs_project, before_theirs_project)
1021
+
1022
+ expect {
1023
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1024
+ }.to raise_error(Kintsugi::MergeError)
1025
+ end
1026
+
1027
+ it "raises if trying to remove hash entry whose value changed" do
1028
+ base_project.targets[0].build_configurations.each do |configuration|
1029
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "bar"
1030
+ end
1031
+
1032
+ base_project.save
1033
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1034
+ theirs_project.targets[0].build_configurations.each do |configuration|
1035
+ configuration.build_settings = nil
1036
+ end
1037
+
1038
+ base_project.save
1039
+ before_theirs_project = create_copy_of_project(base_project.path, "theirs")
1040
+ before_theirs_project.targets[0].build_configurations.each do |configuration|
1041
+ configuration.build_settings["HEADER_SEARCH_PATHS"] = "baz"
1042
+ end
1043
+
1044
+ changes_to_apply = get_diff(theirs_project, before_theirs_project)
1045
+
1046
+ expect {
1047
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1048
+ }.to raise_error(Kintsugi::MergeError)
1049
+ end
623
1050
  end
624
1051
 
625
1052
  it "adds build phases" do
@@ -640,6 +1067,20 @@ describe Kintsugi, :apply_change_to_project do
640
1067
  expect(base_project).to be_equivalent_to_project(theirs_project)
641
1068
  end
642
1069
 
1070
+ it "adds build phase with a simple attribute value that has non nil default" do
1071
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1072
+
1073
+ theirs_project.targets[0].new_shell_script_build_phase("bar")
1074
+ theirs_project.targets[0].build_phases.last.shell_script = "Other value"
1075
+
1076
+ changes_to_apply = get_diff(theirs_project, base_project)
1077
+
1078
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1079
+ base_project.save
1080
+
1081
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1082
+ end
1083
+
643
1084
  it "removes build phase" do
644
1085
  base_project.targets[0].new_shell_script_build_phase("bar")
645
1086
 
@@ -752,7 +1193,7 @@ describe Kintsugi, :apply_change_to_project do
752
1193
  base_project.save
753
1194
  theirs_project = create_copy_of_project(base_project.path, "theirs")
754
1195
 
755
- theirs_project.root_object.known_regions += ["en"]
1196
+ theirs_project.root_object.known_regions += ["fr"]
756
1197
 
757
1198
  changes_to_apply = get_diff(theirs_project, base_project)
758
1199
 
@@ -763,12 +1204,9 @@ describe Kintsugi, :apply_change_to_project do
763
1204
  end
764
1205
 
765
1206
  it "removes known regions" do
766
- base_project.root_object.known_regions += ["en"]
767
-
768
- base_project.save
769
1207
  theirs_project = create_copy_of_project(base_project.path, "theirs")
770
1208
 
771
- theirs_project.root_object.known_regions = []
1209
+ theirs_project.root_object.known_regions = nil
772
1210
 
773
1211
  changes_to_apply = get_diff(theirs_project, base_project)
774
1212
 
@@ -927,6 +1365,41 @@ describe Kintsugi, :apply_change_to_project do
927
1365
  expect(base_project).to be_equivalent_to_project(theirs_project)
928
1366
  end
929
1367
 
1368
+ it "adds group to product group" do
1369
+ base_project_path = make_temp_directory("base", ".xcodeproj")
1370
+ base_project = Xcodeproj::Project.new(base_project_path)
1371
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1372
+
1373
+ base_project.save
1374
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1375
+
1376
+ theirs_project.root_object.product_ref_group.new_group("foo")
1377
+
1378
+ changes_to_apply = get_diff(theirs_project, base_project)
1379
+
1380
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1381
+
1382
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1383
+ end
1384
+
1385
+ it "adds localization files to product group" do
1386
+ base_project_path = make_temp_directory("base", ".xcodeproj")
1387
+ base_project = Xcodeproj::Project.new(base_project_path)
1388
+ base_project.new_target("com.apple.product-type.library.static", "foo", :ios)
1389
+
1390
+ base_project.save
1391
+ theirs_project = create_copy_of_project(base_project.path, "theirs")
1392
+
1393
+ variant_group = theirs_project.root_object.product_ref_group.new_variant_group("foo.strings")
1394
+ variant_group.new_reference("Base").last_known_file_type = "text.plist.strings"
1395
+
1396
+ changes_to_apply = get_diff(theirs_project, base_project)
1397
+
1398
+ described_class.apply_change_to_project(base_project, changes_to_apply)
1399
+
1400
+ expect(base_project).to be_equivalent_to_project(theirs_project)
1401
+ end
1402
+
930
1403
  def create_copy_of_project(project_path, new_project_prefix)
931
1404
  copied_project_path = make_temp_directory(new_project_prefix, ".xcodeproj")
932
1405
  FileUtils.cp(File.join(project_path, "project.pbxproj"), copied_project_path)
@@ -934,7 +1407,15 @@ describe Kintsugi, :apply_change_to_project do
934
1407
  end
935
1408
 
936
1409
  def get_diff(first_project, second_project)
937
- Xcodeproj::Differ.project_diff(first_project, second_project, :added, :removed)
1410
+ diff = Xcodeproj::Differ.project_diff(first_project, second_project, :added, :removed)
1411
+
1412
+ diff_without_display_name =
1413
+ diff.merge("rootObject" => diff["rootObject"].reject { |key, _| key == "displayName" })
1414
+ if diff_without_display_name == {"rootObject" => {}}
1415
+ raise "Diff contains no changes. This probably means the test doesn't check anything."
1416
+ end
1417
+
1418
+ diff
938
1419
  end
939
1420
 
940
1421
  def add_new_subproject_to_project(project, subproject_name, subproject_product_name)
@@ -987,6 +1468,22 @@ describe Kintsugi, :apply_change_to_project do
987
1468
  reference_proxy
988
1469
  end
989
1470
 
1471
+ def create_swift_package_product_dependency(project)
1472
+ product_dependency = project.new(Xcodeproj::Project::XCSwiftPackageProductDependency)
1473
+ product_dependency.product_name = "foo"
1474
+ product_dependency.package = create_remote_swift_package_reference(project)
1475
+
1476
+ product_dependency
1477
+ end
1478
+
1479
+ def create_remote_swift_package_reference(project)
1480
+ package_reference = project.new(Xcodeproj::Project::XCRemoteSwiftPackageReference)
1481
+ package_reference.repositoryURL = "http://foo"
1482
+ package_reference.requirement = {"foo" => "bar"}
1483
+
1484
+ package_reference
1485
+ end
1486
+
990
1487
  def make_temp_directory(directory_prefix, directory_extension)
991
1488
  directory_path = Dir.mktmpdir([directory_prefix, directory_extension])
992
1489
  temporary_directories_paths << directory_path