danger-wcc 0.0.2

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 (73) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +46 -0
  3. data/.gitignore +6 -0
  4. data/.rubocop.yml +219 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +12 -0
  7. data/Dangerfile +5 -0
  8. data/Gemfile +6 -0
  9. data/Guardfile +35 -0
  10. data/LICENSE +201 -0
  11. data/README.md +2 -0
  12. data/Rakefile +25 -0
  13. data/danger-wcc.gemspec +58 -0
  14. data/lib/danger_plugin.rb +3 -0
  15. data/lib/version.rb +5 -0
  16. data/lib/wcc/commit_lint.rb +158 -0
  17. data/lib/wcc/commit_lint/README.md +3 -0
  18. data/lib/wcc/commit_lint/commit_check.rb +19 -0
  19. data/lib/wcc/commit_lint/empty_line_check.rb +22 -0
  20. data/lib/wcc/commit_lint/subject_cap_check.rb +22 -0
  21. data/lib/wcc/commit_lint/subject_length_check.rb +28 -0
  22. data/lib/wcc/commit_lint/subject_period_check.rb +22 -0
  23. data/lib/wcc/commit_lint/subject_words_check.rb +22 -0
  24. data/lib/wcc/default.jshintrc +5 -0
  25. data/lib/wcc/defaults.reek +131 -0
  26. data/lib/wcc/github.rb +24 -0
  27. data/lib/wcc/jshint.rb +63 -0
  28. data/lib/wcc/plugin.rb +128 -0
  29. data/lib/wcc/reek.rb +56 -0
  30. data/lib/wcc/rubocop_exceptions.rb +99 -0
  31. data/lib/wcc/todos.rb +78 -0
  32. data/lib/wcc/utils.rb +136 -0
  33. data/spec/fixtures/brakeman/a.tmp +13 -0
  34. data/spec/fixtures/brakeman/b.tmp +14 -0
  35. data/spec/fixtures/brakeman/brakeman.diff +20 -0
  36. data/spec/fixtures/brakeman/brakeman.out +14 -0
  37. data/spec/fixtures/exception_context.diff +15 -0
  38. data/spec/fixtures/exception_insert_context.diff +14 -0
  39. data/spec/fixtures/exception_misspelled.diff +14 -0
  40. data/spec/fixtures/exception_multiline_context.diff +20 -0
  41. data/spec/fixtures/exception_reenabled.diff +13 -0
  42. data/spec/fixtures/find_in_diff.rb +21 -0
  43. data/spec/fixtures/find_in_diff_2_chunks.diff +24 -0
  44. data/spec/fixtures/flay.diff +17 -0
  45. data/spec/fixtures/flay.txt +18 -0
  46. data/spec/fixtures/github/labels.json +72 -0
  47. data/spec/fixtures/github_pr.json +325 -0
  48. data/spec/fixtures/jshint/a.tmp +5 -0
  49. data/spec/fixtures/jshint/b.tmp +7 -0
  50. data/spec/fixtures/jshint/jshint.diff +13 -0
  51. data/spec/fixtures/jshint/out.jshint +7 -0
  52. data/spec/fixtures/no_exception.diff +10 -0
  53. data/spec/fixtures/no_todo.diff +13 -0
  54. data/spec/fixtures/reek/line_numbers.reek +121 -0
  55. data/spec/fixtures/reek/reek.diff +50 -0
  56. data/spec/fixtures/rubocop_exception.rb +39 -0
  57. data/spec/fixtures/todo.rb +21 -0
  58. data/spec/fixtures/todo_link_next_line.diff +14 -0
  59. data/spec/fixtures/todo_link_same_line.diff +13 -0
  60. data/spec/fixtures/todo_no_link.diff +13 -0
  61. data/spec/fixtures/todo_removed.diff +13 -0
  62. data/spec/fixtures_helper.rb +19 -0
  63. data/spec/spec_helper.rb +73 -0
  64. data/spec/wcc/commit_lint_spec.rb +392 -0
  65. data/spec/wcc/github_spec.rb +67 -0
  66. data/spec/wcc/jshint_spec.rb +68 -0
  67. data/spec/wcc/plugin_spec.rb +134 -0
  68. data/spec/wcc/reek_spec.rb +71 -0
  69. data/spec/wcc/rubocop_exceptions_spec.rb +136 -0
  70. data/spec/wcc/todos_spec.rb +96 -0
  71. data/spec/wcc/utils_spec.rb +134 -0
  72. data/spec/wcc_spec.rb +21 -0
  73. metadata +393 -0
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../spec_helper', __FILE__)
4
+ require 'webmock'
5
+
6
+ module Danger
7
+ include FixturesHelper
8
+
9
+ API_URL = 'https://api.github.com'
10
+
11
+ describe Danger::DangerWCC do
12
+ before do
13
+ @dangerfile = testing_dangerfile
14
+ @my_plugin = @dangerfile.wcc
15
+ @github = @dangerfile.github
16
+
17
+ allow(@github).to receive(:pr_json)
18
+ .and_return(JSON.parse(load_fixture('github_pr.json')))
19
+ end
20
+
21
+ describe 'github' do
22
+ before do
23
+ stub_request(:get, API_URL + '/repos/watermarkchurch/danger-wcc/labels')
24
+ .with(query: hash_excluding({ 'anything' => 1 }))
25
+ .to_return(
26
+ body: load_fixture('github/labels.json'),
27
+ headers: { 'Content-Type' => 'application/json' }
28
+ )
29
+ end
30
+
31
+ it '#labels returns array of existing labels' do
32
+ # act
33
+ labels = @my_plugin.labels
34
+
35
+ # assert
36
+ expect(labels.length).to eq(10)
37
+ end
38
+
39
+ it '#add_labels adds existing labels to issue' do
40
+ stub = stub_request(:post,
41
+ API_URL + '/repos/watermarkchurch/danger-wcc/issues/2/labels')
42
+ .with(body: '["backlog","bug","duplicate"]')
43
+
44
+ # act
45
+ @my_plugin.add_labels('backlog', 'bug', 'duplicate')
46
+
47
+ # assert
48
+ expect(stub).to have_been_requested
49
+ end
50
+
51
+ it '#add_labels creates new labels before adding to issue' do
52
+ stub = stub_request(:post,
53
+ API_URL + '/repos/watermarkchurch/danger-wcc/labels')
54
+ .with(body: '{"name":"new_label","color":"ffffff"}')
55
+ stub_request(:post,
56
+ API_URL + '/repos/watermarkchurch/danger-wcc/issues/2/labels')
57
+ .with(body: '["backlog","new_label"]')
58
+
59
+ # act
60
+ @my_plugin.add_labels('backlog', 'new_label')
61
+
62
+ # assert
63
+ expect(stub).to have_been_requested
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../spec_helper', __FILE__)
4
+
5
+ module Danger
6
+ describe Danger::DangerWCC do
7
+ before do
8
+ @dangerfile = testing_dangerfile
9
+ @my_plugin = @dangerfile.wcc
10
+ @git = @dangerfile.git
11
+ @github = @dangerfile.github
12
+
13
+ allow(@github).to receive(:pr_json)
14
+ .and_return(JSON.parse(load_fixture('github_pr.json')))
15
+ allow(subject).to receive(:run)
16
+ .with(/npm/)
17
+ .and_return('')
18
+ allow(subject).to receive(:run_and_diff)
19
+ .and_return(load_fixture('jshint/jshint.diff'))
20
+ allow(subject).to receive(:run)
21
+ .with(/\/tmp\/.+\/jshint/)
22
+ .and_return(load_fixture('jshint/out.jshint'))
23
+ allow(Dir).to receive(:exist?)
24
+ .with('app/assets/javascripts')
25
+ .and_return(true)
26
+ end
27
+
28
+ describe 'jshint' do
29
+ let(:subject) { Danger::DangerWCC::Jshint.new(@my_plugin) }
30
+
31
+ after do
32
+ File.delete('.jshint') if File.file?('.jshint')
33
+ end
34
+
35
+ it 'runs jshint and parses diff' do
36
+ # act
37
+ subject.perform
38
+
39
+ # assert
40
+ warnings = @dangerfile.violation_report[:warnings]
41
+ expect(warnings.length).to eq(2)
42
+
43
+ expect(warnings[0].message)
44
+ .to eq("Misleading line break before '+'; readers may interpret this"\
45
+ ' as an expression boundary.')
46
+ expect(warnings[0].file).to eq('app/assets/javascripts/comment.js')
47
+ expect(warnings[0].line).to eq(42)
48
+
49
+ expect(warnings.last.message)
50
+ .to eq("['AM'] is better written in dot notation.")
51
+ expect(warnings.last.file).to eq('app/assets/javascripts/mobiscroll.js')
52
+ expect(warnings.last.line).to eq(3)
53
+ end
54
+
55
+ it 'writes .jshint only if .jshint doesnt exist' do
56
+ begin
57
+ File.write('.jshint', '{}')
58
+
59
+ subject.perform
60
+
61
+ expect(File.read('.jshint')).to eq('{}')
62
+ ensure
63
+ File.delete('.jshint')
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../spec_helper', __FILE__)
4
+
5
+ module Danger
6
+ describe Danger::DangerWCC do
7
+ before do
8
+ @dangerfile = testing_dangerfile
9
+ @my_plugin = @dangerfile.wcc
10
+ @git = @dangerfile.git
11
+ @github = @dangerfile.github
12
+
13
+ allow(@github).to receive(:html_link) do |text|
14
+ "<a href=\"github_html_link\">#{text}</a>"
15
+ end
16
+ end
17
+
18
+ describe 'all' do
19
+ it 'runs all checks and passes default options' do
20
+ Danger::DangerWCC::CHECKS.each do |check|
21
+ expect(@my_plugin).to receive(check)
22
+ .with({})
23
+ end
24
+
25
+ # act
26
+ @my_plugin.all
27
+ end
28
+
29
+ it 'errors if all checks disabled' do
30
+ disabled = Danger::DangerWCC::CHECKS
31
+ options = disabled.each_with_object({}) { |v, h| h[v] = false; }
32
+
33
+ # expect
34
+ disabled.each do |check|
35
+ expect(@my_plugin).to_not receive(check)
36
+ end
37
+
38
+ # act
39
+ expect {
40
+ @my_plugin.all(options)
41
+ }.to raise_error(ArgumentError)
42
+ end
43
+
44
+ it 'runs only enabled checks' do
45
+ enabled = %i[todos commit_lint]
46
+ disabled =
47
+ Danger::DangerWCC::CHECKS.reject do |check|
48
+ enabled.include?(check)
49
+ end
50
+ options = disabled.each_with_object({}) { |v, h| h[v] = false; }
51
+
52
+ # expect
53
+ enabled.each do |check|
54
+ expect(@my_plugin).to receive(check)
55
+ end
56
+ disabled.each do |check|
57
+ expect(@my_plugin).to_not receive(check)
58
+ end
59
+
60
+ # act
61
+ @my_plugin.all options
62
+ end
63
+
64
+ it 'passes options' do
65
+ options =
66
+ Danger::DangerWCC::CHECKS.each_with_object({}) do |v, h|
67
+ h[v] = false
68
+ end
69
+ options[:commit_lint] = { test: { options: 1 } }
70
+
71
+ # expect
72
+ expect(@my_plugin).to receive(:commit_lint)
73
+ .with({ test: { options: 1 } })
74
+
75
+ # act
76
+ @my_plugin.all options
77
+ end
78
+ end
79
+
80
+ describe 'brakeman' do
81
+ it 'runs brakeman and parses diff' do
82
+ allow(@my_plugin).to receive(:run_and_diff)
83
+ .with(/^bundle exec brakeman/)
84
+ .and_return(load_fixture('brakeman/brakeman.diff'))
85
+ allow(@my_plugin).to receive(:run)
86
+ .with(/^bundle exec brakeman/)
87
+ .and_return(load_fixture('brakeman/brakeman.out'))
88
+
89
+ # act
90
+ @my_plugin.brakeman
91
+
92
+ # expect
93
+ warnings = @dangerfile.violation_report[:errors]
94
+ expect(warnings.length).to eq(2)
95
+
96
+ expect(warnings[0].message)
97
+ .to match(/SSL Verification Bypass/)
98
+ expect(warnings[0].file)
99
+ .to eq('app/controllers/wmoauth_controller.rb')
100
+ expect(warnings[0].line).to eq(78)
101
+
102
+ expect(warnings[1].message)
103
+ .to match(/Unescaped model attribute near line/)
104
+ expect(warnings[1].file)
105
+ .to eq('app/views/sections/_discussion_questions.html.erb')
106
+ expect(warnings[1].line).to eq(4)
107
+ end
108
+ end
109
+
110
+ describe 'flay' do
111
+ it 'runs flay and reports only where changed' do
112
+ allow(@my_plugin).to receive(:run)
113
+ .with(/flay/)
114
+ .and_return(load_fixture('flay.txt'))
115
+
116
+ allow(@git).to receive(:diff)
117
+ .and_return([load_diff(
118
+ 'app/models/discourse.rb',
119
+ 'flay'
120
+ )])
121
+
122
+ # act
123
+ @my_plugin.flay
124
+
125
+ # assert
126
+ warnings = @dangerfile.violation_report[:warnings]
127
+ expect(warnings.length).to eq(1)
128
+ expect(warnings[0].message)
129
+ .to eq("IDENTICAL code found in :if (mass*2 = 152) at:\n"\
130
+ ' <a href="github_html_link">app/models/discourse.rb#L177</a>')
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../spec_helper', __FILE__)
4
+
5
+ module Danger
6
+ describe Danger::DangerWCC do
7
+ before do
8
+ @dangerfile = testing_dangerfile
9
+ @my_plugin = @dangerfile.wcc
10
+ @git = @dangerfile.git
11
+ @github = @dangerfile.github
12
+
13
+ allow(@github).to receive(:pr_json)
14
+ .and_return(JSON.parse(load_fixture('github_pr.json')))
15
+ allow(@github).to receive(:html_link) do |text|
16
+ "<a href=\"github_html_link\">#{text}</a>"
17
+ end
18
+ end
19
+
20
+ describe 'reek' do
21
+ let(:subject) { Danger::DangerWCC::Reek.new(@my_plugin) }
22
+
23
+ after do
24
+ File.delete('defaults.reek') if File.file?('defaults.reek')
25
+ end
26
+
27
+ it 'runs reek and parses diff' do
28
+ allow(subject).to receive(:run_and_diff)
29
+ .and_return(load_fixture('reek/reek.diff'))
30
+ allow(subject).to receive(:run)
31
+ .with(/^bundle exec reek/)
32
+ .and_return(load_fixture('reek/line_numbers.reek'))
33
+
34
+ # act
35
+ subject.perform
36
+
37
+ # expect
38
+ warnings = @dangerfile.violation_report[:warnings]
39
+ expect(warnings.length).to eq(6)
40
+
41
+ expect(warnings[0].message)
42
+ .to eq('TooManyStatements: Danger::DangerWCC#reek has approx 7 '\
43
+ 'statements [https://github.com/troessner/reek/blob/master/docs/'\
44
+ 'Too-Many-Statements.md](https://github.com/troessner/reek/blob/'\
45
+ 'master/docs/Too-Many-Statements.md)')
46
+ expect(warnings[0].file).to eq('lib/wcc/plugin.rb')
47
+ expect(warnings[0].line).to eq(53)
48
+
49
+ expect(warnings.last.message)
50
+ .to eq('IrresponsibleModule: Danger has no descriptive comment '\
51
+ '[https://github.com/troessner/reek/blob/master/docs/'\
52
+ 'Irresponsible-Module.md](https://github.com/troessner/reek/blob/'\
53
+ 'master/docs/Irresponsible-Module.md)')
54
+ expect(warnings.last.file).to eq('spec/wcc/plugin_spec.rb')
55
+ expect(warnings.last.line).to eq(5)
56
+ end
57
+
58
+ it 'writes defaults.reek only if .reek doesnt exist' do
59
+ begin
60
+ File.write('.reek', '')
61
+
62
+ subject.perform
63
+
64
+ expect(File.file?('defaults.reek')).to be false
65
+ ensure
66
+ File.delete('.reek')
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../spec_helper', __FILE__)
4
+
5
+ module Danger
6
+ describe Danger::DangerWCC do
7
+ before do
8
+ @dangerfile = testing_dangerfile
9
+ @my_plugin = @dangerfile.wcc
10
+ @git = @dangerfile.git
11
+ @github = @dangerfile.github
12
+
13
+ allow(@github).to receive(:html_link) do |text|
14
+ "<a href=\"github_html_link\">#{text}</a>"
15
+ end
16
+ end
17
+
18
+ describe 'rubocop exceptions' do
19
+ it 'Warns when Rubocop exception added without context' do
20
+ allow(@git).to receive(:diff)
21
+ .and_return([load_diff(
22
+ 'spec/fixtures/rubocop_exception.rb',
23
+ 'exception_reenabled'
24
+ )])
25
+
26
+ # act
27
+ @my_plugin.rubocop_exceptions
28
+
29
+ expect(@dangerfile.violation_report[:warnings])
30
+ .to eq([Violation.new('Rubocop rule Rails/SomeRule disabled in '\
31
+ '<a href="github_html_link">spec/fixtures/rubocop_exception.rb</a>'\
32
+ " \nPlease provide an explanation why this rule was disabled.",
33
+ false,
34
+ 'spec/fixtures/rubocop_exception.rb',
35
+ 5)])
36
+ end
37
+
38
+ it 'Errors when rubocop exception not reenabled' do
39
+ allow(@git).to receive(:diff)
40
+ .and_return([load_diff(
41
+ 'spec/fixtures/rubocop_exception.rb',
42
+ 'exception_misspelled'
43
+ )])
44
+
45
+ # act
46
+ @my_plugin.rubocop_exceptions
47
+
48
+ expect(@dangerfile.violation_report[:errors])
49
+ .to eq([Violation.new('Rubocop rule Lint/SomeLint disabled in '\
50
+ '<a href="github_html_link">spec/fixtures/rubocop_exception.rb</a>'\
51
+ " \nPlease provide an explanation why this rule was disabled."\
52
+ "\n\nThe rule was not reenabled!\n"\
53
+ 'Please add a `rubocop:enable` comment so the rule is disabled '\
54
+ 'for the minimal scope.',
55
+ false,
56
+ 'spec/fixtures/rubocop_exception.rb',
57
+ 10)])
58
+ end
59
+
60
+ it 'Messages when exception added with context' do
61
+ allow(@git).to receive(:diff)
62
+ .and_return([load_diff(
63
+ 'spec/fixtures/rubocop_exception.rb',
64
+ 'exception_context'
65
+ )])
66
+
67
+ # act
68
+ @my_plugin.rubocop_exceptions
69
+
70
+ expect(@dangerfile.violation_report[:messages])
71
+ .to eq([Violation.new('Rubocop rule Metrics/LineLength disabled in '\
72
+ '<a href="github_html_link">spec/fixtures/rubocop_exception.rb</a>'\
73
+ " explanation:\n\t> Disabling because I want to.",
74
+ false,
75
+ 'spec/fixtures/rubocop_exception.rb',
76
+ 15)])
77
+ end
78
+
79
+ it 'Messages when exception added with multiline context' do
80
+ allow(@git).to receive(:diff)
81
+ .and_return([load_diff(
82
+ 'spec/fixtures/rubocop_exception.rb',
83
+ 'exception_multiline_context'
84
+ )])
85
+
86
+ # act
87
+ @my_plugin.rubocop_exceptions
88
+
89
+ expect(@dangerfile.violation_report[:messages])
90
+ .to eq([Violation.new('Rubocop rule Layout/AlignHash disabled in '\
91
+ '<a href="github_html_link">spec/fixtures/rubocop_exception.rb</a>'\
92
+ ' explanation:'\
93
+ "\n\t> I want to disable this because.."\
94
+ "\n\t> I forgot the reasons.",
95
+ false,
96
+ 'spec/fixtures/rubocop_exception.rb',
97
+ 30)])
98
+ end
99
+
100
+ it 'Messages when exception added in between existing comments' do
101
+ allow(@git).to receive(:diff)
102
+ .and_return([load_diff(
103
+ 'spec/fixtures/rubocop_exception.rb',
104
+ 'exception_insert_context'
105
+ )])
106
+
107
+ # act
108
+ @my_plugin.rubocop_exceptions
109
+
110
+ expect(@dangerfile.violation_report[:messages])
111
+ .to eq([Violation.new('Rubocop rule Metrics/ABC disabled in '\
112
+ '<a href="github_html_link">spec/fixtures/rubocop_exception.rb</a>'\
113
+ ' explanation:'\
114
+ "\n\t> here is my comment why we are disabling ABC",
115
+ false,
116
+ 'spec/fixtures/rubocop_exception.rb',
117
+ 21)])
118
+ end
119
+
120
+ it 'Does not message when no exception added' do
121
+ allow(@git).to receive(:diff)
122
+ .and_return([load_diff(
123
+ 'spec/fixtures/rubocop_exception.rb',
124
+ 'no_exception'
125
+ )])
126
+
127
+ # act
128
+ @my_plugin.rubocop_exceptions
129
+
130
+ expect(@dangerfile.violation_report[:messages]).to eq([])
131
+ expect(@dangerfile.violation_report[:warnings]).to eq([])
132
+ expect(@dangerfile.violation_report[:errors]).to eq([])
133
+ end
134
+ end
135
+ end
136
+ end