licensee 9.10.1 → 9.13.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/bin/licensee +5 -4
  4. data/lib/licensee.rb +7 -5
  5. data/lib/licensee/commands/detect.rb +7 -5
  6. data/lib/licensee/commands/diff.rb +7 -8
  7. data/lib/licensee/commands/license_path.rb +2 -0
  8. data/lib/licensee/commands/version.rb +2 -0
  9. data/lib/licensee/content_helper.rb +230 -85
  10. data/lib/licensee/hash_helper.rb +7 -5
  11. data/lib/licensee/license.rb +21 -22
  12. data/lib/licensee/license_field.rb +3 -1
  13. data/lib/licensee/license_meta.rb +2 -0
  14. data/lib/licensee/license_rules.rb +2 -0
  15. data/lib/licensee/matchers.rb +2 -0
  16. data/lib/licensee/matchers/cabal.rb +16 -2
  17. data/lib/licensee/matchers/cargo.rb +3 -1
  18. data/lib/licensee/matchers/copyright.rb +6 -4
  19. data/lib/licensee/matchers/cran.rb +5 -3
  20. data/lib/licensee/matchers/dice.rb +6 -4
  21. data/lib/licensee/matchers/dist_zilla.rb +3 -1
  22. data/lib/licensee/matchers/exact.rb +2 -0
  23. data/lib/licensee/matchers/gemspec.rb +7 -5
  24. data/lib/licensee/matchers/matcher.rb +3 -1
  25. data/lib/licensee/matchers/npm_bower.rb +3 -1
  26. data/lib/licensee/matchers/package.rb +2 -0
  27. data/lib/licensee/matchers/reference.rb +3 -1
  28. data/lib/licensee/matchers/spdx.rb +3 -1
  29. data/lib/licensee/project_files.rb +2 -0
  30. data/lib/licensee/project_files/license_file.rb +12 -10
  31. data/lib/licensee/project_files/package_manager_file.rb +2 -0
  32. data/lib/licensee/project_files/project_file.rb +12 -5
  33. data/lib/licensee/project_files/readme_file.rb +5 -3
  34. data/lib/licensee/projects.rb +2 -0
  35. data/lib/licensee/projects/fs_project.rb +9 -2
  36. data/lib/licensee/projects/git_project.rb +19 -11
  37. data/lib/licensee/projects/github_project.rb +3 -1
  38. data/lib/licensee/projects/project.rb +7 -5
  39. data/lib/licensee/rule.rb +2 -0
  40. data/lib/licensee/version.rb +3 -1
  41. data/licensee.gemspec +45 -0
  42. data/spec/bin_spec.rb +3 -1
  43. data/spec/fixture_spec.rb +46 -0
  44. data/spec/fixtures/bsd-3-noendorseslash/LICENSE +30 -0
  45. data/spec/fixtures/cc0-cal2013/LICENSE +116 -0
  46. data/spec/fixtures/cc0-cc/LICENSE +121 -0
  47. data/spec/fixtures/detect.json +10 -8
  48. data/spec/fixtures/fixtures.yml +134 -0
  49. data/spec/fixtures/html/license.html +262 -0
  50. data/spec/fixtures/license-hashes.json +41 -0
  51. data/spec/fixtures/mit-optional/LICENSE.txt +21 -0
  52. data/spec/fixtures/multiple-arrs/LICENSE +30 -0
  53. data/spec/fixtures/readme-invalid-encoding/README.md +24 -0
  54. data/spec/fixtures/unlicense-noinfo/LICENSE +22 -0
  55. data/spec/integration_spec.rb +68 -2
  56. data/spec/licensee/commands/detect_spec.rb +11 -7
  57. data/spec/licensee/commands/license_path_spec.rb +3 -1
  58. data/spec/licensee/commands/version_spec.rb +3 -1
  59. data/spec/licensee/content_helper_spec.rb +185 -67
  60. data/spec/licensee/hash_helper_spec.rb +3 -1
  61. data/spec/licensee/license_field_spec.rb +5 -3
  62. data/spec/licensee/license_meta_spec.rb +16 -12
  63. data/spec/licensee/license_rules_spec.rb +6 -2
  64. data/spec/licensee/license_spec.rb +37 -35
  65. data/spec/licensee/matchers/cabal_matcher_spec.rb +97 -2
  66. data/spec/licensee/matchers/cargo_matcher_spec.rb +5 -2
  67. data/spec/licensee/matchers/copyright_matcher_spec.rb +7 -5
  68. data/spec/licensee/matchers/cran_matcher_spec.rb +5 -2
  69. data/spec/licensee/matchers/dice_matcher_spec.rb +15 -12
  70. data/spec/licensee/matchers/dist_zilla_matcher_spec.rb +5 -2
  71. data/spec/licensee/matchers/exact_matcher_spec.rb +5 -2
  72. data/spec/licensee/matchers/gemspec_matcher_spec.rb +5 -2
  73. data/spec/licensee/matchers/matcher_spec.rb +6 -2
  74. data/spec/licensee/matchers/npm_bower_matcher_spec.rb +5 -3
  75. data/spec/licensee/matchers/package_matcher_spec.rb +6 -2
  76. data/spec/licensee/matchers/reference_matcher_spec.rb +4 -2
  77. data/spec/licensee/matchers/spdx_matcher_spec.rb +5 -2
  78. data/spec/licensee/project_files/license_file_spec.rb +20 -18
  79. data/spec/licensee/project_files/package_info_spec.rb +5 -1
  80. data/spec/licensee/project_files/project_file_spec.rb +8 -2
  81. data/spec/licensee/project_files/readme_file_spec.rb +4 -1
  82. data/spec/licensee/project_spec.rb +24 -17
  83. data/spec/licensee/projects/git_project_spec.rb +23 -0
  84. data/spec/licensee/projects/github_project_spec.rb +8 -5
  85. data/spec/licensee/rule_spec.rb +6 -3
  86. data/spec/licensee_spec.rb +12 -9
  87. data/spec/spec_helper.rb +27 -9
  88. data/spec/vendored_license_spec.rb +29 -10
  89. data/vendor/choosealicense.com/_data/meta.yml +0 -4
  90. data/vendor/choosealicense.com/_data/rules.yml +3 -0
  91. data/vendor/choosealicense.com/_licenses/0bsd.txt +39 -0
  92. data/vendor/choosealicense.com/_licenses/afl-3.0.txt +7 -6
  93. data/vendor/choosealicense.com/_licenses/agpl-3.0.txt +0 -1
  94. data/vendor/choosealicense.com/_licenses/apache-2.0.txt +1 -2
  95. data/vendor/choosealicense.com/_licenses/artistic-2.0.txt +1 -2
  96. data/vendor/choosealicense.com/_licenses/bsd-2-clause.txt +8 -6
  97. data/vendor/choosealicense.com/_licenses/bsd-3-clause-clear.txt +2 -2
  98. data/vendor/choosealicense.com/_licenses/bsd-3-clause.txt +12 -10
  99. data/vendor/choosealicense.com/_licenses/bsd-4-clause.txt +61 -0
  100. data/vendor/choosealicense.com/_licenses/bsl-1.0.txt +5 -2
  101. data/vendor/choosealicense.com/_licenses/cc-by-4.0.txt +16 -14
  102. data/vendor/choosealicense.com/_licenses/cc-by-sa-4.0.txt +16 -14
  103. data/vendor/choosealicense.com/_licenses/cc0-1.0.txt +113 -105
  104. data/vendor/choosealicense.com/_licenses/cecill-2.1.txt +579 -0
  105. data/vendor/choosealicense.com/_licenses/ecl-2.0.txt +1 -2
  106. data/vendor/choosealicense.com/_licenses/epl-1.0.txt +1 -2
  107. data/vendor/choosealicense.com/_licenses/epl-2.0.txt +3 -4
  108. data/vendor/choosealicense.com/_licenses/eupl-1.1.txt +0 -1
  109. data/vendor/choosealicense.com/_licenses/eupl-1.2.txt +0 -1
  110. data/vendor/choosealicense.com/_licenses/gpl-2.0.txt +0 -1
  111. data/vendor/choosealicense.com/_licenses/gpl-3.0.txt +1 -2
  112. data/vendor/choosealicense.com/_licenses/isc.txt +2 -3
  113. data/vendor/choosealicense.com/_licenses/lgpl-2.1.txt +0 -1
  114. data/vendor/choosealicense.com/_licenses/lgpl-3.0.txt +1 -3
  115. data/vendor/choosealicense.com/_licenses/lppl-1.3c.txt +1 -2
  116. data/vendor/choosealicense.com/_licenses/mit.txt +1 -2
  117. data/vendor/choosealicense.com/_licenses/mpl-2.0.txt +0 -1
  118. data/vendor/choosealicense.com/_licenses/ms-pl.txt +0 -1
  119. data/vendor/choosealicense.com/_licenses/ms-rl.txt +0 -1
  120. data/vendor/choosealicense.com/_licenses/ncsa.txt +21 -22
  121. data/vendor/choosealicense.com/_licenses/odbl-1.0.txt +573 -0
  122. data/vendor/choosealicense.com/_licenses/ofl-1.1.txt +4 -2
  123. data/vendor/choosealicense.com/_licenses/osl-3.0.txt +1 -2
  124. data/vendor/choosealicense.com/_licenses/postgresql.txt +4 -5
  125. data/vendor/choosealicense.com/_licenses/unlicense.txt +1 -2
  126. data/vendor/choosealicense.com/_licenses/upl-1.0.txt +4 -5
  127. data/vendor/choosealicense.com/_licenses/vim.txt +111 -0
  128. data/vendor/choosealicense.com/_licenses/wtfpl.txt +0 -1
  129. data/vendor/choosealicense.com/_licenses/zlib.txt +4 -2
  130. metadata +79 -28
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Ben Balter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is furnished
10
+ to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice (including the next
13
+ paragraph) shall be included in all copies or substantial portions of the
14
+ Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
19
+ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
21
+ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,30 @@
1
+ Copyright (c) 2018, Ben Balter
2
+ All rights reserved.
3
+
4
+ Copyright (c) 2020, Alice B. Carols
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice, this
11
+ list of conditions and the following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above copyright notice,
14
+ this list of conditions and the following disclaimer in the documentation
15
+ and/or other materials provided with the distribution.
16
+
17
+ * Neither the name of the copyright holder nor the names of its
18
+ contributors may be used to endorse or promote products derived from
19
+ this software without specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,24 @@
1
+ # Readme fixture
2
+
3
+ ## License
4
+
5
+ Copyright (c) 2016 Ben Balter
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+ ��
@@ -0,0 +1,22 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -1,9 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe 'integration test' do
2
4
  [
3
5
  Licensee::Projects::FSProject,
4
6
  Licensee::Projects::GitProject
5
7
  ].each do |project_type|
6
8
  context "with a #{project_type} project" do
9
+ subject { project_type.new(project_path, **arguments) }
10
+
7
11
  let(:filename) { 'LICENSE' }
8
12
  let(:license) { Licensee::License.find('mit') }
9
13
  let(:other_license) { Licensee::License.find('other') }
@@ -11,8 +15,6 @@ RSpec.describe 'integration test' do
11
15
  let(:license_path) { File.expand_path(filename, project_path) }
12
16
  let(:arguments) { {} }
13
17
 
14
- subject { project_type.new(project_path, arguments) }
15
-
16
18
  context 'fixtures' do
17
19
  let(:fixture) { 'mit' }
18
20
  let(:project_path) { fixture_path(fixture) }
@@ -20,6 +22,7 @@ RSpec.describe 'integration test' do
20
22
 
21
23
  if project_type == Licensee::Projects::GitProject
22
24
  before { git_init(project_path) }
25
+
23
26
  after { FileUtils.rm_rf(git_path) }
24
27
  end
25
28
 
@@ -71,6 +74,15 @@ RSpec.describe 'integration test' do
71
74
  end
72
75
  end
73
76
 
77
+ context 'with multiple all rights reserved lines' do
78
+ let(:license) { Licensee::License.find('bsd-3-clause') }
79
+ let(:fixture) { 'multiple-arrs' }
80
+
81
+ it 'matches other' do
82
+ expect(subject.license).to eql(license)
83
+ end
84
+ end
85
+
74
86
  context 'with CC-BY-NC-SA' do
75
87
  let(:fixture) { 'cc-by-nc-sa' }
76
88
 
@@ -158,6 +170,42 @@ RSpec.describe 'integration test' do
158
170
  end
159
171
  end
160
172
 
173
+ context 'CC0 as published by CC' do
174
+ let(:license) { Licensee::License.find('cc0-1.0') }
175
+ let(:fixture) { 'cc0-cc' }
176
+
177
+ it 'returns cc0-1.0' do
178
+ expect(subject.license).to eql(license)
179
+ end
180
+ end
181
+
182
+ context 'CC0 as published on choosealicense.com 2013-2019' do
183
+ let(:license) { Licensee::License.find('cc0-1.0') }
184
+ let(:fixture) { 'cc0-cal2013' }
185
+
186
+ it 'returns cc0-1.0' do
187
+ expect(subject.license).to eql(license)
188
+ end
189
+ end
190
+
191
+ context 'Unlicense without optional line' do
192
+ let(:license) { Licensee::License.find('unlicense') }
193
+ let(:fixture) { 'unlicense-noinfo' }
194
+
195
+ it 'returns unlicense' do
196
+ expect(subject.license).to eql(license)
197
+ end
198
+ end
199
+
200
+ context 'MIT w/optional phrase' do
201
+ let(:license) { Licensee::License.find('mit') }
202
+ let(:fixture) { 'mit-optional' }
203
+
204
+ it 'returns mit' do
205
+ expect(subject.license).to eql(license)
206
+ end
207
+ end
208
+
161
209
  context 'license + README reference' do
162
210
  let(:license) { Licensee::License.find('mit') }
163
211
  let(:fixture) { 'license-with-readme-reference' }
@@ -195,6 +243,24 @@ RSpec.describe 'integration test' do
195
243
  expect(subject.license).to eql(license)
196
244
  end
197
245
  end
246
+
247
+ context 'BSD-3-Clause no-endorsement name with slashes' do
248
+ let(:license) { Licensee::License.find('bsd-3-clause') }
249
+ let(:fixture) { 'bsd-3-noendorseslash' }
250
+
251
+ it 'determines the project is BSD-3-Clause' do
252
+ expect(subject.license).to eql(license)
253
+ end
254
+ end
255
+
256
+ context 'HTML license file' do
257
+ let(:license) { Licensee::License.find('epl-1.0') }
258
+ let(:fixture) { 'html' }
259
+
260
+ it 'matches to GPL3' do
261
+ expect(subject.license).to eql(license)
262
+ end
263
+ end
198
264
  end
199
265
 
200
266
  context 'with the license file stubbed' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe 'detect command' do
2
4
  let(:command) { ['bundle', 'exec', 'bin/licensee', 'detect'] }
3
5
  let(:arguments) { [] }
@@ -10,14 +12,14 @@ RSpec.describe 'detect command' do
10
12
  let(:stdout) { output[0] }
11
13
  let(:stderr) { output[1] }
12
14
  let(:status) { output[2] }
13
- let(:hash) { '46cdc03462b9af57968df67b450cc4372ac41f53' }
15
+ let(:hash) { license_hashes['mit'] }
14
16
  let(:expected) do
15
17
  {
16
18
  'License' => 'MIT',
17
19
  'Matched files' => 'LICENSE.md, licensee.gemspec',
18
20
  'LICENSE.md' => {
19
21
  'Content hash' => hash,
20
- 'Attribution' => 'Copyright (c) 2014-2017 Ben Balter',
22
+ 'Attribution' => 'Copyright (c) 2014-2020 Ben Balter and Licensee contributors',
21
23
  'Confidence' => '100.00%',
22
24
  'Matcher' => 'Licensee::Matchers::Exact',
23
25
  'License' => 'MIT'
@@ -39,7 +41,7 @@ RSpec.describe 'detect command' do
39
41
  let(:arguments) { args }
40
42
 
41
43
  it 'Returns a zero exit code' do
42
- expect(status.exitstatus).to eql(0)
44
+ expect(status.exitstatus).to be(0)
43
45
  end
44
46
 
45
47
  it 'returns the exected values' do
@@ -60,15 +62,17 @@ RSpec.describe 'detect command' do
60
62
  let(:expected) { JSON.parse fixture_contents('detect.json') }
61
63
 
62
64
  it 'Returns a zero exit code' do
63
- expect(status.exitstatus).to eql(0)
65
+ expect(status.exitstatus).to be(0)
64
66
  end
65
67
 
66
68
  it 'returns valid JSON' do
67
- expect { JSON.parse(stdout) }.to_not raise_error
69
+ expect { JSON.parse(stdout) }.not_to raise_error
68
70
  end
69
71
 
70
72
  it 'returns the expected output' do
71
- expect(JSON.parse(stdout)).to eql(expected)
73
+ msg = '`licensee detect --json` output did not match expectations. '.dup
74
+ msg << 'Run `script/dump-detect-json-fixture` and verify the output.'
75
+ expect(JSON.parse(stdout)).to eql(expected), msg
72
76
  end
73
77
  end
74
78
 
@@ -76,7 +80,7 @@ RSpec.describe 'detect command' do
76
80
  let(:command) { ['bundle', 'exec', 'bin/licensee'] }
77
81
 
78
82
  it 'Returns a zero exit code' do
79
- expect(status.exitstatus).to eql(0)
83
+ expect(status.exitstatus).to be(0)
80
84
  end
81
85
 
82
86
  it 'returns the exected values' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe 'license-path command' do
2
4
  let(:command) { ['bundle', 'exec', 'bin/licensee', 'license-path'] }
3
5
  let(:arguments) { [project_root] }
@@ -16,6 +18,6 @@ RSpec.describe 'license-path command' do
16
18
  end
17
19
 
18
20
  it 'Returns a zero exit code' do
19
- expect(status.exitstatus).to eql(0)
21
+ expect(status.exitstatus).to be(0)
20
22
  end
21
23
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe 'version command' do
2
4
  let(:command) { ['bundle', 'exec', 'bin/licensee', 'version'] }
3
5
  let(:arguments) { [] }
@@ -16,6 +18,6 @@ RSpec.describe 'version command' do
16
18
  end
17
19
 
18
20
  it 'Returns a zero exit code' do
19
- expect(status.exitstatus).to eql(0)
21
+ expect(status.exitstatus).to be(0)
20
22
  end
21
23
  end
@@ -1,15 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ContentHelperTestHelper
2
4
  include Licensee::ContentHelper
3
- attr_accessor :content
5
+ attr_accessor :content, :data
4
6
 
5
- def initialize(content = nil)
7
+ def initialize(content = nil, data = {})
6
8
  @content = content
9
+ @data = data
10
+ end
11
+
12
+ def filename
13
+ @data[:filename]
7
14
  end
8
15
  end
9
16
 
10
17
  RSpec.describe Licensee::ContentHelper do
18
+ subject { ContentHelperTestHelper.new(content, filename: filename) }
19
+
11
20
  let(:content) do
12
- <<-LICENSE.freeze.gsub(/^\s*/, '')
21
+ <<-LICENSE.gsub(/^\s*/, '')
13
22
  # The MIT License
14
23
  =================
15
24
 
@@ -27,8 +36,10 @@ RSpec.describe Licensee::ContentHelper do
27
36
  -----------
28
37
  LICENSE
29
38
  end
30
- subject { ContentHelperTestHelper.new(content) }
39
+ let(:filename) { 'license.md' }
40
+
31
41
  let(:mit) { Licensee::License.find('mit') }
42
+ let(:normalized_content) { subject.content_normalized }
32
43
 
33
44
  it 'creates the wordset' do
34
45
  wordset = Set.new(
@@ -41,25 +52,25 @@ RSpec.describe Licensee::ContentHelper do
41
52
  end
42
53
 
43
54
  it 'knows the length' do
44
- expect(subject.length).to eql(135)
55
+ expect(subject.length).to be(135)
45
56
  end
46
57
 
47
58
  context 'a very long license' do
48
59
  let(:content) { 'license' * 1000 }
49
60
 
50
61
  it 'returns the max delta' do
51
- expect(subject.max_delta).to eql(140)
62
+ expect(subject.max_delta).to be(140)
52
63
  end
53
64
  end
54
65
 
55
66
  it 'knows the length delta' do
56
- expect(subject.length_delta(mit)).to eql(884)
57
- expect(subject.length_delta(subject)).to eql(0)
67
+ expect(subject.length_delta(mit)).to be(885)
68
+ expect(subject.length_delta(subject)).to be(0)
58
69
  end
59
70
 
60
71
  it 'knows the similarity' do
61
72
  expect(subject.similarity(mit)).to be_within(1).of(11)
62
- expect(subject.similarity(subject)).to eql(100.0)
73
+ expect(subject.similarity(subject)).to be(100.0)
63
74
  end
64
75
 
65
76
  it 'calculates the hash' do
@@ -68,75 +79,103 @@ RSpec.describe Licensee::ContentHelper do
68
79
  end
69
80
 
70
81
  it 'wraps' do
71
- content = Licensee::ContentHelper.wrap(mit.content, 40)
82
+ content = described_class.wrap(mit.content, 40)
72
83
  lines = content.split("\n")
73
84
  expect(lines.first.length).to be <= 40
74
85
  end
75
86
 
76
87
  it 'formats percents' do
77
- percent = Licensee::ContentHelper.format_percent(12.3456789)
88
+ percent = described_class.format_percent(12.3456789)
78
89
  expect(percent).to eql('12.35%')
79
90
  end
80
91
 
81
- context 'normalizing' do
82
- let(:normalized_content) { subject.content_normalized }
83
-
84
- it 'strips copyright' do
85
- expect(normalized_content).to_not match 'Copyright'
86
- expect(normalized_content).to_not match 'Ben Balter'
92
+ describe '#strip' do
93
+ {
94
+ version: "The MIT License\nVersion 1.0\nfoo",
95
+ hrs: "The MIT License\n=====\n-----\n*******\nfoo",
96
+ markdown_headings: "# The MIT License\n\nfoo",
97
+ whitespace: "The MIT License\n\n foo ",
98
+ all_rights_reserved: "Copyright 2016 Ben Balter\n\nfoo",
99
+ urls: "https://example.com\nfoo",
100
+ developed_by: "Developed By: Ben Balter\n\nFoo",
101
+ borders: '* Foo *',
102
+ title: "The MIT License\nfoo",
103
+ copyright: "The MIT License\nCopyright 2018 Ben Balter\nFoo",
104
+ end_of_terms: "Foo\nend of terms and conditions\nbar",
105
+ end_of_terms_hashes: "Foo\n# end of terms and conditions ####\nbar",
106
+ block_markup: '> Foo',
107
+ link_markup: '[Foo](http://exmaple.com)',
108
+ comment_markup: "/*\n* The MIT License\n* Foo\n*/",
109
+ copyright_title: "Copyright 2019 Ben Balter\nMIT License\nFoo"
110
+ }.each do |field, fixture|
111
+ context "#strip_#{field}" do
112
+ let(:content) { fixture }
113
+
114
+ it "strips #{field}" do
115
+ expect(normalized_content).to eql('foo')
116
+ end
117
+ end
87
118
  end
88
119
 
89
- it 'downcases' do
90
- expect(normalized_content).to_not match 'The'
91
- expect(normalized_content).to match 'the'
120
+ context 'span markup' do
121
+ let(:content) { '_foo_ *foo* **foo** ~foo~' }
122
+
123
+ it 'strips span markup' do
124
+ expect(normalized_content).to eql('foo foo foo foo')
125
+ end
92
126
  end
93
127
 
94
- it 'strips HRs' do
95
- expect(normalized_content).to_not match '---'
96
- expect(normalized_content).to_not match '==='
97
- expect(normalized_content).to_not include '***'
98
- expect(normalized_content).to_not include '* *'
128
+ context 'HTML' do
129
+ let(:content) { '<ul><li>foo</li></ul>' }
130
+ let(:filename) { 'license.html' }
131
+
132
+ it 'strips HTML' do
133
+ expect(normalized_content).to eql('- foo')
134
+ end
99
135
  end
136
+ end
100
137
 
101
- it 'strips formatting from the MPL' do
102
- license = Licensee::License.find('mpl-2.0')
103
- expect(license.content_normalized).to_not include('* *')
138
+ context 'integration fixture' do
139
+ it 'strips copyright' do
140
+ expect(normalized_content).not_to match 'Copyright'
141
+ expect(normalized_content).not_to match 'Ben Balter'
104
142
  end
105
143
 
106
- it 'normalizes http: to https:' do
107
- license = Licensee::License.find('mpl-2.0')
108
- expect(license.content).to include('http:')
109
- expect(license.content_normalized).to_not include('http:')
144
+ it 'downcases' do
145
+ expect(normalized_content).not_to match 'The'
146
+ expect(normalized_content).to match 'the'
110
147
  end
111
148
 
112
- it 'wraps' do
113
- lines = mit.content_normalized(wrap: 40).split("\n")
114
- expect(lines.first.length).to be <= 40
149
+ it 'strips HRs' do
150
+ expect(normalized_content).not_to match '---'
151
+ expect(normalized_content).not_to match '==='
152
+ expect(normalized_content).not_to include '***'
153
+ expect(normalized_content).not_to include '* *'
115
154
  end
116
155
 
117
156
  it 'squeezes whitespace' do
118
- expect(normalized_content).to_not match ' '
157
+ expect(normalized_content).not_to match ' '
119
158
  end
120
159
 
121
160
  it 'strips whitespace' do
122
- expect(normalized_content).to_not match(/\n/)
123
- expect(normalized_content).to_not match(/\t/)
161
+ expect(normalized_content).not_to match(/\n/)
162
+ expect(normalized_content).not_to match(/\t/)
124
163
  end
125
164
 
126
165
  it 'strips markdown headings' do
127
- expect(normalized_content).to_not match('#')
166
+ expect(normalized_content).not_to match('#')
128
167
  end
129
168
 
130
169
  it 'strips all rights reserved' do
131
- expect(normalized_content).to_not match(/all rights reserved/i)
170
+ expect(normalized_content).not_to match(/all rights reserved/i)
132
171
  end
133
172
 
134
173
  it 'strips markup' do
135
- expect(normalized_content).to_not match(/[*=_-]+/)
174
+ expect(normalized_content).not_to match(/[*=_-]+/)
136
175
  end
137
176
 
138
177
  it 'normalizes quotes' do
139
- expect(normalized_content).to_not match("'as is'")
178
+ expect(normalized_content).not_to match("'as is'")
140
179
  end
141
180
 
142
181
  it 'preserves possessives' do
@@ -148,55 +187,120 @@ RSpec.describe Licensee::ContentHelper do
148
187
  expect(normalized_content).to match('"software"')
149
188
  end
150
189
 
190
+ it 'strips the title' do
191
+ expect(normalized_content).not_to match('MIT')
192
+ end
193
+
194
+ it 'normalize the content' do
195
+ expected = 'the made up license. this license provided "as is". '.dup
196
+ expected << "please respect the contributors' wishes when implementing "
197
+ expected << "the license's \"software\"."
198
+ expect(normalized_content).to eql(expected)
199
+ end
200
+ end
201
+
202
+ context 'normalizing' do
203
+ context 'https' do
204
+ let(:content) { 'http://example.com' }
205
+
206
+ it 'normalized URL protocals' do
207
+ expect(subject.content_normalized).to eql('https://example.com')
208
+ end
209
+ end
210
+
211
+ context 'ampersands' do
212
+ let(:content) { 'Foo & Bar' }
213
+
214
+ it 'normalized ampersands' do
215
+ expect(subject.content_normalized).to eql('foo and bar')
216
+ end
217
+ end
218
+
219
+ context 'lists' do
220
+ let(:content) { "1. Foo\n * Bar" }
221
+
222
+ it 'normalizes lists' do
223
+ expect(subject.content_normalized).to eql('- foo - bar')
224
+ end
225
+ end
226
+
227
+ context 'dashes' do
228
+ let(:content) { 'Foo-Bar—–baz-buzz' }
229
+
230
+ it 'normalizes dashes' do
231
+ expect(subject.content_normalized).to eql('foo-bar-baz-buzz')
232
+ end
233
+ end
234
+
235
+ context 'quotes' do
236
+ let(:content) { "`a` 'b' \"c\" ‘d’ “e”" }
237
+
238
+ it 'normalizes quotes' do
239
+ expect(subject.content_normalized).to eql('"a" "b" "c" "d" "e"')
240
+ end
241
+ end
242
+
243
+ it 'strips formatting from the MPL' do
244
+ license = Licensee::License.find('mpl-2.0')
245
+ expect(license.content_normalized).not_to include('* *')
246
+ end
247
+
248
+ it 'normalizes http: to https:' do
249
+ license = Licensee::License.find('mpl-2.0')
250
+ expect(license.content).to include('http:')
251
+ expect(license.content_normalized).not_to include('http:')
252
+ end
253
+
254
+ it 'wraps' do
255
+ lines = mit.content_normalized(wrap: 40).split("\n")
256
+ expect(lines.first.length).to be <= 40
257
+ end
258
+
259
+ context 'spelling' do
260
+ let(:content) { 'licence' }
261
+
262
+ it 'normalizes' do
263
+ expect(subject.content_normalized).to eql('license')
264
+ end
265
+ end
266
+
151
267
  Licensee::License.all(hidden: true).each do |license|
152
268
  context license.name do
153
269
  let(:stripped_content) { subject.content_without_title_and_version }
154
270
 
155
271
  it 'strips the title' do
156
- regex = Licensee::ContentHelper::ALT_TITLE_REGEX[license.key]
157
- regex ||= /\A#{license.name_without_version}/i
158
- expect(license.content_normalized).to_not match(regex)
159
- expect(stripped_content).to_not match(regex)
272
+ regex = /\A#{license.name_without_version}/i
273
+ expect(stripped_content).not_to match(regex)
274
+ expect(license.content_normalized).not_to match(regex)
160
275
  end
161
276
 
162
277
  it 'strips the version' do
163
- expect(license.content_normalized).to_not match(/\Aversion/i)
164
- expect(stripped_content).to_not match(/\Aversion/i)
278
+ expect(license.content_normalized).not_to match(/\Aversion/i)
279
+ expect(stripped_content).not_to match(/\Aversion/i)
165
280
  end
166
281
 
167
282
  it 'strips all rights reserved' do
168
283
  regex = /all rights reserved/i
169
- expect(license.content_normalized).to_not match(regex)
284
+ expect(license.content_normalized).not_to match(regex)
170
285
  end
171
286
 
172
287
  it 'strips the copyright' do
173
- expect(license.content_normalized).to_not match(/\Acopyright/i)
288
+ expect(license.content_normalized).not_to match(/\Acopyright/i)
174
289
  end
175
290
 
176
291
  it 'strips the implementation instructions' do
177
292
  end_terms_regex = /END OF TERMS AND CONDITIONS/i
178
- expect(license.content_normalized).to_not match(end_terms_regex)
179
- expect(license.content_normalized).to_not match(/How to apply/i)
293
+ expect(license.content_normalized).not_to match(end_terms_regex)
294
+ expect(license.content_normalized).not_to match(/How to apply/i)
180
295
  end
181
296
  end
182
297
  end
183
298
 
184
- it 'strips the title' do
185
- expect(normalized_content).to_not match('MIT')
186
- end
187
-
188
- it 'normalize the content' do
189
- expected = 'the made up license. this license provided "as is". '
190
- expected << "please respect the contributors' wishes when implementing "
191
- expected << "the license's \"software\"."
192
- expect(normalized_content).to eql(expected)
193
- end
194
-
195
299
  context 'a title in parenthesis' do
196
300
  let(:content) { "(The MIT License)\n\nfoo" }
197
301
 
198
302
  it 'strips the title' do
199
- expect(normalized_content).to_not match('MIT')
303
+ expect(normalized_content).not_to match('MIT')
200
304
  expect(normalized_content).to eql('foo')
201
305
  end
202
306
  end
@@ -205,7 +309,7 @@ RSpec.describe Licensee::ContentHelper do
205
309
  let(:content) { "Copyright 2016 Ben Balter\nCopyright 2017 Bob\nFoo" }
206
310
 
207
311
  it 'strips multiple copyrights' do
208
- expect(normalized_content).to_not match('Ben')
312
+ expect(normalized_content).not_to match('Ben')
209
313
  expect(normalized_content).to eql('foo')
210
314
  end
211
315
  end
@@ -259,7 +363,7 @@ RSpec.describe Licensee::ContentHelper do
259
363
  let(:text) { 'gpl-3 0' }
260
364
 
261
365
  it 'escapes' do
262
- expect(text).to_not match(described_class.title_regex)
366
+ expect(text).not_to match(described_class.title_regex)
263
367
  end
264
368
  end
265
369
 
@@ -269,10 +373,24 @@ RSpec.describe Licensee::ContentHelper do
269
373
  end
270
374
 
271
375
  it 'matches' do
272
- expect(text).to_not match(described_class.title_regex)
376
+ expect(text).not_to match(described_class.title_regex)
273
377
  end
274
378
  end
275
379
  end
276
380
  end
277
381
  end
382
+
383
+ context 'metaprogramming' do
384
+ it 'raises on invalid normalization' do
385
+ expect { subject.send(:normalize, :foo) }.to raise_error(ArgumentError)
386
+ end
387
+
388
+ it 'raises on invalid strip' do
389
+ expect { subject.send(:strip, :foo) }.to raise_error(ArgumentError)
390
+ end
391
+
392
+ it 'backwards compatibalizes regexes' do
393
+ expect(described_class::WHITESPACE_REGEX).to eql(/\s+/)
394
+ end
395
+ end
278
396
  end