danger-dangermattic 1.0.0

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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.buildkite/gem-push.sh +15 -0
  3. data/.buildkite/pipeline.yml +69 -0
  4. data/.bundle/config +2 -0
  5. data/.github/workflows/reusable-check-labels-on-issues.yml +91 -0
  6. data/.github/workflows/reusable-run-danger.yml +54 -0
  7. data/.gitignore +30 -0
  8. data/.rubocop.yml +67 -0
  9. data/.ruby-version +1 -0
  10. data/.yardopts +7 -0
  11. data/CHANGELOG.md +7 -0
  12. data/Gemfile +5 -0
  13. data/Gemfile.lock +191 -0
  14. data/Guardfile +21 -0
  15. data/LICENSE +373 -0
  16. data/README.md +68 -0
  17. data/Rakefile +24 -0
  18. data/danger-dangermattic.gemspec +58 -0
  19. data/lib/danger_dangermattic.rb +3 -0
  20. data/lib/danger_plugin.rb +4 -0
  21. data/lib/dangermattic/gem_version.rb +5 -0
  22. data/lib/dangermattic/plugins/android_release_checker.rb +50 -0
  23. data/lib/dangermattic/plugins/android_strings_checker.rb +31 -0
  24. data/lib/dangermattic/plugins/android_unit_test_checker.rb +187 -0
  25. data/lib/dangermattic/plugins/common/common_release_checker.rb +113 -0
  26. data/lib/dangermattic/plugins/common/git_utils.rb +166 -0
  27. data/lib/dangermattic/plugins/common/github_utils.rb +68 -0
  28. data/lib/dangermattic/plugins/common/reporter.rb +38 -0
  29. data/lib/dangermattic/plugins/ios_release_checker.rb +106 -0
  30. data/lib/dangermattic/plugins/labels_checker.rb +74 -0
  31. data/lib/dangermattic/plugins/manifest_pr_checker.rb +106 -0
  32. data/lib/dangermattic/plugins/milestone_checker.rb +98 -0
  33. data/lib/dangermattic/plugins/podfile_checker.rb +122 -0
  34. data/lib/dangermattic/plugins/pr_size_checker.rb +125 -0
  35. data/lib/dangermattic/plugins/tracks_checker.rb +72 -0
  36. data/lib/dangermattic/plugins/view_changes_checker.rb +46 -0
  37. data/spec/android_release_checker_spec.rb +93 -0
  38. data/spec/android_strings_checker_spec.rb +185 -0
  39. data/spec/android_unit_test_checker_spec.rb +343 -0
  40. data/spec/common_release_checker_spec.rb +70 -0
  41. data/spec/fixtures/android_unit_test_checker/Abc.java +7 -0
  42. data/spec/fixtures/android_unit_test_checker/AbcFeatureConfig.java +7 -0
  43. data/spec/fixtures/android_unit_test_checker/Abcdef.kt +5 -0
  44. data/spec/fixtures/android_unit_test_checker/AbcdefgViewHelper.java +7 -0
  45. data/spec/fixtures/android_unit_test_checker/AnotherViewHelper.kt +7 -0
  46. data/spec/fixtures/android_unit_test_checker/MyNewClass.java +7 -0
  47. data/spec/fixtures/android_unit_test_checker/Polygon.kt +3 -0
  48. data/spec/fixtures/android_unit_test_checker/Shape.kt +10 -0
  49. data/spec/fixtures/android_unit_test_checker/TestsINeedThem.java +5 -0
  50. data/spec/fixtures/android_unit_test_checker/TestsINeedThem.kt +7 -0
  51. data/spec/fixtures/android_unit_test_checker/TestsINeedThem2.kt +12 -0
  52. data/spec/fixtures/android_unit_test_checker/src/android/java/org/activities/MyActivity.kt +7 -0
  53. data/spec/fixtures/android_unit_test_checker/src/android/java/org/activities/MyJavaActivity.java +7 -0
  54. data/spec/fixtures/android_unit_test_checker/src/android/java/org/fragments/MyFragment.kt +6 -0
  55. data/spec/fixtures/android_unit_test_checker/src/android/java/org/fragments/MyNewJavaFragment.java +7 -0
  56. data/spec/fixtures/android_unit_test_checker/src/android/java/org/module/MyModule.java +13 -0
  57. data/spec/fixtures/android_unit_test_checker/src/android/java/org/view/ActionCardViewHolder.kt +22 -0
  58. data/spec/fixtures/android_unit_test_checker/src/android/java/org/view/MyRecyclerView.java +7 -0
  59. data/spec/fixtures/android_unit_test_checker/src/androidTest/java/org/test/AbcTests.java +5 -0
  60. data/spec/fixtures/android_unit_test_checker/src/androidTest/java/org/test/AnotherTestClass.java +7 -0
  61. data/spec/fixtures/android_unit_test_checker/src/androidTest/java/org/test/PolygonTest.kt +4 -0
  62. data/spec/fixtures/android_unit_test_checker/src/androidTest/java/org/test/TestMyNewClass.java +9 -0
  63. data/spec/fixtures/android_unit_test_checker/src/androidTest/java/org/test/ToolTest.kt +5 -0
  64. data/spec/fixtures/android_unit_test_checker/src/main/java/org/wordpress/android/widgets/NestedWebView.kt +32 -0
  65. data/spec/fixtures/android_unit_test_checker/src/main/java/org/wordpress/util/config/BloggingPromptsFeatureConfig.kt +23 -0
  66. data/spec/fixtures/android_unit_test_checker/src/test/java/org/test/TestsINeedThem.java +9 -0
  67. data/spec/github_utils_spec.rb +110 -0
  68. data/spec/ios_release_checker_spec.rb +191 -0
  69. data/spec/labels_checker_spec.rb +169 -0
  70. data/spec/manifest_pr_checker_spec.rb +140 -0
  71. data/spec/milestone_checker_spec.rb +222 -0
  72. data/spec/podfile_checker_spec.rb +595 -0
  73. data/spec/pr_size_checker_spec.rb +250 -0
  74. data/spec/spec_helper.rb +115 -0
  75. data/spec/tracks_checker_spec.rb +156 -0
  76. data/spec/view_changes_checker_spec.rb +168 -0
  77. metadata +341 -0
@@ -0,0 +1,250 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'spec_helper'
4
+
5
+ module Danger
6
+ describe Danger::PRSizeChecker do
7
+ it 'is a plugin' do
8
+ expect(described_class.new(nil)).to be_a Danger::Plugin
9
+ end
10
+
11
+ describe 'with Dangerfile' do
12
+ before do
13
+ @dangerfile = testing_dangerfile
14
+ @plugin = @dangerfile.pr_size_checker
15
+ end
16
+
17
+ context 'when checking a PR diff size' do
18
+ before do
19
+ allow(@plugin.git).to receive_messages(added_files: [], modified_files: [], deleted_files: [])
20
+ end
21
+
22
+ shared_examples 'using the default diff size counter, without a file selector' do |type|
23
+ let(:diff_counter_for_type) do
24
+ type_hash = {
25
+ insertions: :insertions,
26
+ deletions: :deletions,
27
+ all: :lines_of_code
28
+ }
29
+
30
+ type_hash[type]
31
+ end
32
+
33
+ it 'reports a warning when using default parameters in a PR that has larger diff than the maximum' do
34
+ allow(@plugin.git).to receive(diff_counter_for_type).and_return(501)
35
+
36
+ @plugin.check_diff_size(max_size: 500, type: type)
37
+
38
+ expect(@dangerfile).to report_warnings([format(described_class::DEFAULT_DIFF_SIZE_MESSAGE_FORMAT, 500)])
39
+ end
40
+
41
+ it 'does nothing when using default parameters in a PR that has equal diff than the maximum' do
42
+ allow(@plugin.git).to receive(diff_counter_for_type).and_return(500)
43
+
44
+ @plugin.check_diff_size(max_size: 500, type: type)
45
+
46
+ expect(@dangerfile).to not_report
47
+ end
48
+
49
+ it 'does nothing when using default parameters in a PR that has smaller diff than the maximum' do
50
+ allow(@plugin.git).to receive(diff_counter_for_type).and_return(499)
51
+
52
+ @plugin.check_diff_size(max_size: 500, type: type)
53
+
54
+ expect(@dangerfile).to not_report
55
+ end
56
+
57
+ context 'when reporting a custom error or warning with a custom max_size' do
58
+ shared_examples 'reporting diff size custom warnings or errors' do |report_type, message|
59
+ it 'reports an error using a custom message and a custom PR body size' do
60
+ allow(@plugin.git).to receive(diff_counter_for_type).and_return(600)
61
+
62
+ if message
63
+ @plugin.check_diff_size(max_size: 599, type: type, message: message, report_type: report_type)
64
+ else
65
+ @plugin.check_diff_size(max_size: 599, type: type, report_type: report_type)
66
+ end
67
+
68
+ message ||= format(described_class::DEFAULT_DIFF_SIZE_MESSAGE_FORMAT, 599)
69
+
70
+ expect_warning_or_error(report_type: report_type, message: message)
71
+ end
72
+ end
73
+
74
+ context 'when fail on error is false and a custom message is given' do
75
+ include_examples 'reporting diff size custom warnings or errors', false, 'this is my custom warning message'
76
+ end
77
+
78
+ context 'when fail on error is false' do
79
+ include_examples 'reporting diff size custom warnings or errors', false
80
+ end
81
+
82
+ context 'when fail on error is true' do
83
+ include_examples 'reporting diff size custom warnings or errors', true
84
+ end
85
+
86
+ context 'when a custom error message is given and fail on error is true' do
87
+ include_examples 'reporting diff size custom warnings or errors', true, 'this is my custom error message'
88
+ end
89
+ end
90
+ end
91
+
92
+ shared_examples 'using a file selector to filter and count the changes in a diff' do |type, max_sizes|
93
+ context 'when using a files filter that will regard the diff as too large' do
94
+ it 'reports a warning' do
95
+ prepare_diff_with_test_files
96
+
97
+ @plugin.check_diff_size(
98
+ max_size: max_sizes[0],
99
+ file_selector: ->(path) { File.dirname(path).start_with?('src/test/java') },
100
+ type: type
101
+ )
102
+
103
+ expect(@dangerfile).to report_warnings([format(described_class::DEFAULT_DIFF_SIZE_MESSAGE_FORMAT, max_sizes[0])])
104
+ end
105
+
106
+ it 'reports a custom error' do
107
+ prepare_diff_with_test_files
108
+
109
+ custom_message = 'diff size too large custom file filter and error message'
110
+ @plugin.check_diff_size(
111
+ max_size: max_sizes[1],
112
+ file_selector: ->(path) { File.extname(path) == '.java' },
113
+ type: type,
114
+ message: custom_message,
115
+ report_type: :error
116
+ )
117
+
118
+ expect(@dangerfile).to report_errors([custom_message])
119
+ end
120
+ end
121
+
122
+ it 'does nothing when a files filter is used but the max size is greater than or equal to the diff size' do
123
+ prepare_diff_with_test_files
124
+
125
+ @plugin.check_diff_size(
126
+ max_size: max_sizes[2],
127
+ file_selector: ->(path) { File.extname(path).match(/^(.java|.kt)$/) },
128
+ type: type
129
+ )
130
+
131
+ expect(@dangerfile).to not_report
132
+ end
133
+
134
+ def prepare_diff_with_test_files
135
+ added_test_file = 'src/test/java/org/magic/MagicTests.kt'
136
+ added_config = 'config.xml'
137
+ added_file = 'MyNewSorcery.java'
138
+ modified_file1 = 'src/java/PotionIngredients.java'
139
+ modified_file2 = 'src/java/Potion.kt'
140
+ modified_strings = 'src/main/res/values/strings.xml'
141
+ deleted_file1 = 'src/java/org/Fire.kt'
142
+ deleted_file2 = 'BlackCat.kt'
143
+ deleted_test_file = 'src/test/java/org/magic/Power.java'
144
+ deleted_strings = 'src/main/res/values-de/strings.xml'
145
+
146
+ allow(@plugin.git).to receive_messages(added_files: [added_config, added_file], modified_files: [modified_file1, modified_file2, added_test_file, modified_strings], deleted_files: [deleted_file1, deleted_test_file, deleted_strings, deleted_file2])
147
+
148
+ allow(@plugin.git).to receive(:diff).and_return(instance_double(Git::Diff))
149
+ expected_files = { added_test_file => {}, added_config => {}, added_file => {}, modified_file1 => {}, modified_file2 => {}, modified_strings => {}, deleted_file1 => {}, deleted_file2 => {}, deleted_test_file => {}, deleted_strings => {} }
150
+ allow(@plugin.git.diff).to receive(:stats).and_return({ files: expected_files })
151
+
152
+ allow(@plugin.git).to receive(:info_for_file).with(added_test_file).and_return({ insertions: 201 })
153
+ allow(@plugin.git).to receive(:info_for_file).with(added_config).and_return({ insertions: 311 })
154
+ allow(@plugin.git).to receive(:info_for_file).with(added_file).and_return({ insertions: 13 })
155
+ allow(@plugin.git).to receive(:info_for_file).with(modified_file1).and_return({ insertions: 127, deletions: 159 })
156
+ allow(@plugin.git).to receive(:info_for_file).with(modified_file2).and_return({ insertions: 43, deletions: 37 })
157
+ allow(@plugin.git).to receive(:info_for_file).with(modified_strings).and_return({ insertions: 432, deletions: 297 })
158
+ allow(@plugin.git).to receive(:info_for_file).with(deleted_file1).and_return({ deletions: 246 })
159
+ allow(@plugin.git).to receive(:info_for_file).with(deleted_file2).and_return({ deletions: 493 })
160
+ allow(@plugin.git).to receive(:info_for_file).with(deleted_test_file).and_return({ deletions: 222 })
161
+ allow(@plugin.git).to receive(:info_for_file).with(deleted_strings).and_return({ deletions: 593 })
162
+ end
163
+ end
164
+
165
+ context 'with the entire diff' do
166
+ include_examples 'using the default diff size counter, without a file selector', :all
167
+ include_examples 'using a file selector to filter and count the changes in a diff', :all, [422, 520, 1541]
168
+ end
169
+
170
+ context 'with the insertions in the diff' do
171
+ include_examples 'using the default diff size counter, without a file selector', :insertions
172
+ include_examples 'using a file selector to filter and count the changes in a diff', :insertions, [200, 139, 384]
173
+ end
174
+
175
+ context 'with the deletions in the diff' do
176
+ include_examples 'using the default diff size counter, without a file selector', :deletions
177
+ include_examples 'using a file selector to filter and count the changes in a diff', :deletions, [221, 380, 1157]
178
+ end
179
+ end
180
+
181
+ context 'when checking a PR body size' do
182
+ it 'reports a warning when using default parameters in a PR that has a smaller body text length than the minimum' do
183
+ allow(@plugin.github).to receive(:pr_body).and_return('PR body')
184
+
185
+ @plugin.check_pr_body(min_length: 15)
186
+
187
+ expect(@dangerfile).to report_warnings([format(described_class::DEFAULT_MIN_PR_BODY_MESSAGE_FORMAT, 15)])
188
+ end
189
+
190
+ it 'does nothing when using default parameters in a PR that has a bigger PR body text length than the minimum' do
191
+ allow(@plugin.github).to receive(:pr_body).and_return('some test PR body')
192
+
193
+ @plugin.check_pr_body(min_length: 10)
194
+
195
+ expect(@dangerfile).to not_report
196
+ end
197
+
198
+ it 'reports a warning when using default parameters in a PR that has an equal PR body text length than the minimum' do
199
+ allow(@plugin.github).to receive(:pr_body).and_return('some test-')
200
+
201
+ @plugin.check_pr_body(min_length: 10)
202
+
203
+ expect(@dangerfile).to report_warnings([format(described_class::DEFAULT_MIN_PR_BODY_MESSAGE_FORMAT, 10)])
204
+ end
205
+
206
+ context 'when reporting a custom error or warning with a custom min_length' do
207
+ shared_examples 'reporting PR length check custom warnings or errors' do |report_type, message|
208
+ it 'reports an error when using a custom message and a custom minimum PR body text length' do
209
+ allow(@plugin.github).to receive(:pr_body).and_return('still too short message')
210
+
211
+ if message
212
+ @plugin.check_pr_body(min_length: 25, message: message, report_type: report_type)
213
+ else
214
+ @plugin.check_pr_body(min_length: 25, report_type: report_type)
215
+ end
216
+
217
+ message ||= format(described_class::DEFAULT_MIN_PR_BODY_MESSAGE_FORMAT, 25)
218
+
219
+ expect_warning_or_error(report_type: report_type, message: message)
220
+ end
221
+ end
222
+
223
+ context 'when fail on error is false and a custom message is given' do
224
+ include_examples 'reporting PR length check custom warnings or errors', false, 'this is my custom warning message'
225
+ end
226
+
227
+ context 'when fail on error is false' do
228
+ include_examples 'reporting PR length check custom warnings or errors', false
229
+ end
230
+
231
+ context 'when fail on error is true' do
232
+ include_examples 'reporting PR length check custom warnings or errors', true
233
+ end
234
+
235
+ context 'when a custom error message is given and fail on error is true' do
236
+ include_examples 'reporting PR length check custom warnings or errors', true, 'this is my custom error message'
237
+ end
238
+ end
239
+ end
240
+
241
+ def expect_warning_or_error(report_type:, message:)
242
+ if report_type == :error
243
+ expect(@dangerfile).to report_errors([message])
244
+ elsif report_type == :warning
245
+ expect(@dangerfile).to report_warnings([message])
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
4
+
5
+ require 'pry'
6
+
7
+ require 'rspec'
8
+ require 'danger'
9
+
10
+ if `git remote -v` == ''
11
+ puts 'You cannot run tests without setting a local git remote on this repo'
12
+ puts 'It\'s a weird side-effect of Danger\'s internals.'
13
+ exit(0)
14
+ end
15
+
16
+ RSpec.configure do |config|
17
+ config.filter_gems_from_backtrace 'bundler'
18
+ config.color = true
19
+ config.tty = true
20
+ end
21
+
22
+ require 'danger_plugin'
23
+
24
+ # These functions are a subset of https://github.com/danger/danger/blob/master/spec/spec_helper.rb
25
+ # If you are expanding these files, see if it's already been done ^.
26
+
27
+ # A silent version of the user interface,
28
+ # it comes with an extra function `.string` which will
29
+ # strip all ANSI colours from the string.
30
+
31
+ # rubocop:disable Lint/NestedMethodDefinition
32
+ def testing_ui
33
+ @output = StringIO.new
34
+ def @output.winsize
35
+ [20, 9999]
36
+ end
37
+
38
+ cork = Cork::Board.new(out: @output)
39
+ def cork.string
40
+ out.string.gsub(/\e\[([;\d]+)?m/, '')
41
+ end
42
+ cork
43
+ end
44
+ # rubocop:enable Lint/NestedMethodDefinition
45
+
46
+ # Example environment (ENV)
47
+ def testing_env
48
+ {
49
+ 'HAS_JOSH_K_SEAL_OF_APPROVAL' => 'true',
50
+ 'TRAVIS_PULL_REQUEST' => '800',
51
+ 'TRAVIS_REPO_SLUG' => 'artsy/eigen',
52
+ 'TRAVIS_COMMIT_RANGE' => '759adcbd0d8f...13c4dc8bb61d',
53
+ 'DANGER_GITHUB_API_TOKEN' => '123sbdq54erfsd3422gdfio'
54
+ }
55
+ end
56
+
57
+ # A stubbed out Dangerfile for use in tests
58
+ def testing_dangerfile
59
+ env = Danger::EnvironmentManager.new(testing_env)
60
+ Danger::Dangerfile.new(env, testing_ui)
61
+ end
62
+
63
+ def fixture(name)
64
+ File.read("spec/fixtures/#{name}")
65
+ end
66
+
67
+ # custom matchers
68
+
69
+ RSpec::Matchers.define :report_warnings do |expected_warnings|
70
+ match do |dangerfile|
71
+ dangerfile.status_report[:warnings].eql?(expected_warnings) &&
72
+ dangerfile.status_report[:errors]&.empty? &&
73
+ dangerfile.status_report[:messages]&.empty?
74
+ end
75
+
76
+ failure_message do |dangerfile|
77
+ "expected warnings '#{expected_warnings}' to be reported, got instead:\n- Warnings: #{dangerfile.status_report[:warnings]}\n- Errors: #{dangerfile.status_report[:errors]}\n- Messages: #{dangerfile.status_report[:messages]}"
78
+ end
79
+ end
80
+
81
+ RSpec::Matchers.define :report_errors do |expected_errors|
82
+ match do |dangerfile|
83
+ dangerfile.status_report[:errors].eql?(expected_errors) &&
84
+ dangerfile.status_report[:warnings]&.empty? &&
85
+ dangerfile.status_report[:messages]&.empty?
86
+ end
87
+
88
+ failure_message do |dangerfile|
89
+ "expected errors '#{expected_errors}' to be reported, got instead:\n- Errors: #{dangerfile.status_report[:errors]}\n- Warnings: #{dangerfile.status_report[:warnings]}\n- Messages: #{dangerfile.status_report[:messages]}"
90
+ end
91
+ end
92
+
93
+ RSpec::Matchers.define :report_messages do |expected_messages|
94
+ match do |dangerfile|
95
+ dangerfile.status_report[:messages].eql?(expected_messages) &&
96
+ dangerfile.status_report[:errors]&.empty? &&
97
+ dangerfile.status_report[:warnings]&.empty?
98
+ end
99
+
100
+ failure_message do |dangerfile|
101
+ "expected messages '#{expected_messages}' to be reported, got instead:\n- Messages: #{dangerfile.status_report[:messages]}\n- Warnings: #{dangerfile.status_report[:warnings]}\n- Errors: #{dangerfile.status_report[:errors]}"
102
+ end
103
+ end
104
+
105
+ RSpec::Matchers.define :not_report do
106
+ match do |dangerfile|
107
+ dangerfile.status_report[:errors]&.empty? &&
108
+ dangerfile.status_report[:warnings]&.empty? &&
109
+ dangerfile.status_report[:messages]&.empty?
110
+ end
111
+
112
+ failure_message do |dangerfile|
113
+ "expected no warnings or errors to be reported, got instead:\n#{dangerfile.status_report}"
114
+ end
115
+ end
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'spec_helper'
4
+
5
+ module Danger
6
+ describe Danger::TracksChecker do
7
+ it 'is a plugin' do
8
+ expect(described_class.new(nil)).to be_a Danger::Plugin
9
+ end
10
+
11
+ describe 'with Dangerfile' do
12
+ before do
13
+ @dangerfile = testing_dangerfile
14
+ @plugin = @dangerfile.tracks_checker
15
+ end
16
+
17
+ let(:track_files) do
18
+ [
19
+ 'AnalyticsTracker.kt',
20
+ 'AnalyticsEvent.kt',
21
+ 'LoginAnalyticsTracker.kt',
22
+ 'WooAnalyticsStat.swift'
23
+ ]
24
+ end
25
+
26
+ let(:tracks_matchers) do
27
+ [
28
+ /AnalyticsTracker\.track/
29
+ ]
30
+ end
31
+
32
+ describe '#check_tracks_changes' do
33
+ before do
34
+ allow(@plugin.git).to receive_messages(modified_files: [], added_files: [], deleted_files: [])
35
+
36
+ stub_const('GitDiffStruct', Struct.new(:type, :path, :patch))
37
+ end
38
+
39
+ context 'when checking changes in Tracks-related files' do
40
+ it 'reports a message with instructions for review when there are changes in Tracks-related files' do
41
+ tracks_label = '[Tracks]'
42
+ allow(@plugin.github).to receive(:pr_labels).and_return([tracks_label])
43
+ allow(@plugin.git_utils).to receive(:all_changed_files).and_return(['Test.kt', 'LoginAnalyticsTracker.kt', 'Test.java'])
44
+
45
+ @plugin.check_tracks_changes(tracks_files: track_files, tracks_usage_matchers: tracks_matchers, tracks_label: tracks_label)
46
+
47
+ expect(@dangerfile).to report_messages([TracksChecker::TRACKS_PR_INSTRUCTIONS + format(TracksChecker::TRACKS_NO_LABEL_INSTRUCTION_FORMAT, tracks_label)])
48
+ end
49
+
50
+ it 'reports a message with instructions for review without the label check when there are changes in Tracks-related files and no label parameter' do
51
+ allow(@plugin.git_utils).to receive(:all_changed_files).and_return(['Test.kt', 'LoginAnalyticsTracker.kt', 'Test.java'])
52
+
53
+ @plugin.check_tracks_changes(tracks_files: track_files, tracks_usage_matchers: tracks_matchers, tracks_label: nil)
54
+
55
+ expect(@dangerfile).to report_messages([TracksChecker::TRACKS_PR_INSTRUCTIONS])
56
+ end
57
+
58
+ it 'reports an error when there are changes in Tracks-related files but no Tracks label' do
59
+ allow(@plugin.github).to receive(:pr_labels).and_return([])
60
+ allow(@plugin.git_utils).to receive(:all_changed_files).and_return(['Test.kt', 'LoginAnalyticsTracker.kt', 'Test.java'])
61
+
62
+ tracks_label = 'TRACKS'
63
+ @plugin.check_tracks_changes(tracks_files: track_files, tracks_usage_matchers: tracks_matchers, tracks_label: tracks_label)
64
+
65
+ expect_label_checks(tracks_label)
66
+ end
67
+
68
+ it 'does nothing when there are no changes in Tracks-related files' do
69
+ modified_files = ['MyClass.swift']
70
+ allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
71
+ allow(@plugin.git_utils).to receive(:matching_lines_in_diff_files).with(files: modified_files, line_matcher: kind_of(Proc), change_type: nil).and_return([])
72
+
73
+ @plugin.check_tracks_changes(tracks_files: track_files, tracks_usage_matchers: tracks_matchers, tracks_label: nil)
74
+
75
+ expect(@dangerfile).to not_report
76
+ end
77
+ end
78
+
79
+ context 'when checking Tracks-related changes within a diff' do
80
+ it 'reports a message with instructions for review when there are matching changes' do
81
+ tracks_label = 'Tracks'
82
+ allow(@plugin.github).to receive(:pr_labels).and_return([tracks_label])
83
+ modified_files = ['MyClass.kt']
84
+ allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
85
+
86
+ allow(@plugin.git_utils).to receive(:matching_lines_in_diff_files).with(files: modified_files, line_matcher: kind_of(Proc), change_type: nil) do |args|
87
+ analytics_call_in_diff = '- AnalyticsTracker.track("myEvent1")'
88
+ expect(args[:line_matcher].call(analytics_call_in_diff)).to be true
89
+
90
+ [analytics_call_in_diff]
91
+ end
92
+
93
+ @plugin.check_tracks_changes(tracks_files: track_files, tracks_usage_matchers: tracks_matchers, tracks_label: tracks_label)
94
+
95
+ expect(@dangerfile).to report_messages([TracksChecker::TRACKS_PR_INSTRUCTIONS + format(TracksChecker::TRACKS_NO_LABEL_INSTRUCTION_FORMAT, tracks_label)])
96
+ end
97
+
98
+ it 'reports a message with instructions without the label check for review when there are matching changes and no label parameter' do
99
+ modified_files = ['MyClass.kt']
100
+ allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
101
+
102
+ allow(@plugin.git_utils).to receive(:matching_lines_in_diff_files).with(files: modified_files, line_matcher: kind_of(Proc), change_type: nil) do |args|
103
+ analytics_call_in_diff = '- AnalyticsTracker.track("evento")'
104
+ expect(args[:line_matcher].call(analytics_call_in_diff)).to be true
105
+
106
+ [analytics_call_in_diff]
107
+ end
108
+
109
+ @plugin.check_tracks_changes(tracks_files: track_files, tracks_usage_matchers: tracks_matchers, tracks_label: nil)
110
+
111
+ expect(@dangerfile).to report_messages([TracksChecker::TRACKS_PR_INSTRUCTIONS])
112
+ end
113
+
114
+ it 'reports a message with instructions for review and an error when there are matching changes and no label' do
115
+ allow(@plugin.github).to receive(:pr_labels).and_return([])
116
+ modified_files = ['MyClass.kt']
117
+ allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
118
+
119
+ allow(@plugin.git_utils).to receive(:matching_lines_in_diff_files).with(files: modified_files, line_matcher: kind_of(Proc), change_type: nil) do |args|
120
+ analytics_call_in_diff = '- AnalyticsTracker.track("myEvent1")'
121
+ expect(args[:line_matcher].call(analytics_call_in_diff)).to be true
122
+
123
+ [analytics_call_in_diff]
124
+ end
125
+
126
+ tracks_label = 'TRACKS PR'
127
+ @plugin.check_tracks_changes(tracks_files: track_files, tracks_usage_matchers: tracks_matchers, tracks_label: tracks_label)
128
+
129
+ expect_label_checks(tracks_label)
130
+ end
131
+
132
+ it 'does nothing when there are no matching changes' do
133
+ modified_files = ['MyClass.kt']
134
+ allow(@plugin.git_utils).to receive(:all_changed_files).and_return(modified_files)
135
+
136
+ allow(@plugin.git_utils).to receive(:matching_lines_in_diff_files).with(files: modified_files, line_matcher: kind_of(Proc), change_type: nil) do |args|
137
+ analytics_call_in_diff = '+ AnalyticsHelper.log("event_1")'
138
+ expect(args[:line_matcher].call(analytics_call_in_diff)).to be false
139
+
140
+ []
141
+ end
142
+
143
+ @plugin.check_tracks_changes(tracks_files: track_files, tracks_usage_matchers: tracks_matchers, tracks_label: nil)
144
+
145
+ expect(@dangerfile).to not_report
146
+ end
147
+ end
148
+ end
149
+
150
+ def expect_label_checks(tracks_label)
151
+ expect(@dangerfile.status_report[:messages]).to eq [TracksChecker::TRACKS_PR_INSTRUCTIONS + format(TracksChecker::TRACKS_NO_LABEL_INSTRUCTION_FORMAT, tracks_label)]
152
+ expect(@dangerfile.status_report[:errors]).to eq [format(TracksChecker::TRACKS_NO_LABEL_MESSAGE_FORMAT, tracks_label)]
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'spec_helper'
4
+
5
+ module Danger
6
+ describe Danger::ViewChangesChecker do
7
+ it 'is a plugin' do
8
+ expect(described_class.new(nil)).to be_a Danger::Plugin
9
+ end
10
+
11
+ shared_examples 'PR with view code changes' do |modified_files|
12
+ before do
13
+ allow(@plugin.git).to receive(:modified_files).and_return(modified_files)
14
+ end
15
+
16
+ it 'warns when a PR with view code changes does not have screenshots' do
17
+ allow(@plugin.github).to receive(:pr_body).and_return('PR Body')
18
+
19
+ @plugin.check
20
+
21
+ expect(@dangerfile).to report_warnings([ViewChangesChecker::MESSAGE])
22
+ end
23
+
24
+ it 'does nothing when a PR with view code changes has screenshots defined in markdown' do
25
+ allow(@plugin.github).to receive(:pr_body)
26
+ .and_return('PR [![Alt text](https://myimages.com/boo)](https://digitalocean.com) Body')
27
+
28
+ @plugin.check
29
+
30
+ expect(@dangerfile).to not_report
31
+ end
32
+
33
+ it 'does nothing when a PR with view code changes has url to screenshots' do
34
+ allow(@plugin.github).to receive(:pr_body)
35
+ .and_return('<a href=\'https://myimages.com/boo.jpg\'>see secreenshot</a> Body')
36
+
37
+ @plugin.check
38
+
39
+ expect(@dangerfile).to not_report
40
+ end
41
+
42
+ it 'does nothing when a PR with view code changes has a screenshot defined with a html tag with different attributes before src' do
43
+ allow(@plugin.github).to receive(:pr_body)
44
+ .and_return("see screenshot:\n<img width=300 hint=\"First screenshots\" src=\"https://github.com/bloom/DayOne-Apple/assets/4780/1f9e01a8-c63d-41d4-9ac8-fa9a5182ab55\"> body body")
45
+
46
+ @plugin.check
47
+
48
+ expect(@dangerfile).to not_report
49
+ end
50
+
51
+ it 'does nothing when a PR with view code changes has a screenshot defined with a html tag' do
52
+ allow(@plugin.github).to receive(:pr_body)
53
+ .and_return("see screenshot:\n<img src=\"https://github.com/woocommerce/woocommerce-ios/assets/1864060/17d9227d-67e8-4efb-8c26-02b81e1b19d2\" width=\"375\"> body body")
54
+
55
+ @plugin.check
56
+
57
+ expect(@dangerfile).to not_report
58
+ end
59
+
60
+ it 'does nothing when a PR with view code changes has a video defined with a html tag with different attributes before src' do
61
+ allow(@plugin.github).to receive(:pr_body)
62
+ .and_return("see video:\n<video width=300 hint=\"First video\" src=\"https://www.w3schools.com/tags/movie.mp4\"> body body")
63
+
64
+ @plugin.check
65
+
66
+ expect(@dangerfile).to not_report
67
+ end
68
+
69
+ it 'does nothing when a PR with view code changes has a video defined with a html tag' do
70
+ allow(@plugin.github).to receive(:pr_body)
71
+ .and_return("see video:\n<video src=\"https://www.w3schools.com/tags/movie.mp4\" width=\"375\"> body body")
72
+
73
+ @plugin.check
74
+
75
+ expect(@dangerfile).to not_report
76
+ end
77
+
78
+ it 'does nothing when a PR with view code changes has a video defined with a simple URL' do
79
+ allow(@plugin.github).to receive(:pr_body)
80
+ .and_return("see video:\nhttps://github.com/woocommerce/woocommerce-ios/assets/1864060/0e983305-5047-40a3-8829-734e0b582b96 body body")
81
+
82
+ @plugin.check
83
+
84
+ expect(@dangerfile).to not_report
85
+ end
86
+ end
87
+
88
+ shared_examples 'PR without view code changes' do |modified_files|
89
+ before do
90
+ allow(@plugin.git).to receive(:modified_files).and_return(modified_files)
91
+ allow(@plugin.github).to receive(:pr_body).and_return('Body')
92
+ @plugin.check
93
+ end
94
+
95
+ it 'does nothing' do
96
+ expect(@dangerfile).to not_report
97
+ end
98
+ end
99
+
100
+ describe 'with Dangerfile' do
101
+ before do
102
+ @dangerfile = testing_dangerfile
103
+ @plugin = @dangerfile.view_changes_checker
104
+ end
105
+
106
+ context 'when checking an iOS PR' do
107
+ context 'with view code changes in Swift files' do
108
+ include_examples 'PR with view code changes', ['TestView.swift', 'SimpleViewHelper.m']
109
+ end
110
+
111
+ context 'with button changes in Swift files' do
112
+ include_examples 'PR with view code changes', ['SimpleViewHelper.m', 'MyAwesomeButton.swift']
113
+ end
114
+
115
+ context 'with view code changes in ObjC files' do
116
+ include_examples 'PR with view code changes', ['TestView.m', 'SimpleViewHelper.m']
117
+ end
118
+
119
+ context 'with button changes in ObjC files' do
120
+ include_examples 'PR with view code changes', ['SimpleViewHelper.m', 'MyAwesomeButton.m']
121
+ end
122
+
123
+ context 'with changes in a .xib file' do
124
+ include_examples 'PR with view code changes', ['SimpleViewHelper.m', 'top_bar.xib']
125
+ end
126
+
127
+ context 'with changes in a Storyboard' do
128
+ include_examples 'PR with view code changes', ['SimpleViewHelper.m', 'main_screen.storyboard']
129
+ end
130
+
131
+ context 'with no view changes' do
132
+ include_examples 'PR without view code changes',
133
+ ['SimpleViewHelper.m', 'MyButtonTester.swift', 'Version.xcconfig']
134
+ end
135
+ end
136
+
137
+ context 'when checking an Android PR' do
138
+ context 'with view code changes in Kotlin files' do
139
+ include_examples 'PR with view code changes', ['SimpleViewHelper.kt', 'MySimpleView.kt']
140
+ end
141
+
142
+ context 'with button changes in Kotlin files' do
143
+ include_examples 'PR with view code changes', ['MyAwesomeButton.kt', 'SimpleViewHelper.java']
144
+ end
145
+
146
+ context 'with view code changes in Java files' do
147
+ include_examples 'PR with view code changes', ['TestView.java', 'SimpleViewHelper.kt']
148
+ end
149
+
150
+ context 'with button changes in Java files' do
151
+ include_examples 'PR with view code changes', ['SimpleViewHelper.kt', 'MyAwesomeButton.java']
152
+ end
153
+
154
+ context 'with view code changes in a XML file' do
155
+ include_examples 'PR with view code changes', ['test_view.xml', 'SimpleViewHelper.kt', 'strings.xml']
156
+ end
157
+
158
+ context 'with button changes in a XML file' do
159
+ include_examples 'PR with view code changes', ['SimpleViewHelper.kt', 'strings.xml', 'my_awesome_button.xml']
160
+ end
161
+
162
+ context 'with no view changes' do
163
+ include_examples 'PR without view code changes', ['SimpleViewHelper.java', 'values.xml', 'MyButtonTester.kt']
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end