comment_extractor 1.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +132 -0
- data/bin/comment_parser_debug +45 -0
- data/lib/comment_extractor/code_object/comment.rb +19 -0
- data/lib/comment_extractor/code_object.rb +12 -0
- data/lib/comment_extractor/code_objects.rb +46 -0
- data/lib/comment_extractor/configuration.rb +50 -0
- data/lib/comment_extractor/encoding.rb +40 -0
- data/lib/comment_extractor/extractor/c.rb +8 -0
- data/lib/comment_extractor/extractor/cc.rb +8 -0
- data/lib/comment_extractor/extractor/class.rb +8 -0
- data/lib/comment_extractor/extractor/clojure.rb +11 -0
- data/lib/comment_extractor/extractor/coffee.rb +13 -0
- data/lib/comment_extractor/extractor/concerns/simple_extractor.rb +189 -0
- data/lib/comment_extractor/extractor/concerns/slash_extractor.rb +16 -0
- data/lib/comment_extractor/extractor/cpp.rb +8 -0
- data/lib/comment_extractor/extractor/cs.rb +8 -0
- data/lib/comment_extractor/extractor/css.rb +8 -0
- data/lib/comment_extractor/extractor/cxx.rb +8 -0
- data/lib/comment_extractor/extractor/d.rb +9 -0
- data/lib/comment_extractor/extractor/erlang.rb +12 -0
- data/lib/comment_extractor/extractor/fortran.rb +11 -0
- data/lib/comment_extractor/extractor/go.rb +8 -0
- data/lib/comment_extractor/extractor/h.rb +8 -0
- data/lib/comment_extractor/extractor/haml.rb +49 -0
- data/lib/comment_extractor/extractor/haskell.rb +12 -0
- data/lib/comment_extractor/extractor/hpp.rb +8 -0
- data/lib/comment_extractor/extractor/html.rb +13 -0
- data/lib/comment_extractor/extractor/java.rb +8 -0
- data/lib/comment_extractor/extractor/java_script.rb +12 -0
- data/lib/comment_extractor/extractor/lisp.rb +11 -0
- data/lib/comment_extractor/extractor/lua.rb +12 -0
- data/lib/comment_extractor/extractor/m.rb +9 -0
- data/lib/comment_extractor/extractor/markdown.rb +7 -0
- data/lib/comment_extractor/extractor/mm.rb +8 -0
- data/lib/comment_extractor/extractor/perl.rb +12 -0
- data/lib/comment_extractor/extractor/php.rb +8 -0
- data/lib/comment_extractor/extractor/python.rb +13 -0
- data/lib/comment_extractor/extractor/ruby.rb +40 -0
- data/lib/comment_extractor/extractor/sass.rb +8 -0
- data/lib/comment_extractor/extractor/scala.rb +8 -0
- data/lib/comment_extractor/extractor/scss.rb +8 -0
- data/lib/comment_extractor/extractor/shell.rb +11 -0
- data/lib/comment_extractor/extractor/sqf.rb +8 -0
- data/lib/comment_extractor/extractor/sql.rb +12 -0
- data/lib/comment_extractor/extractor/sqs.rb +7 -0
- data/lib/comment_extractor/extractor/tex.rb +12 -0
- data/lib/comment_extractor/extractor/text.rb +10 -0
- data/lib/comment_extractor/extractor/yaml.rb +12 -0
- data/lib/comment_extractor/extractor.rb +96 -0
- data/lib/comment_extractor/extractor_manager.rb +158 -0
- data/lib/comment_extractor/file.rb +42 -0
- data/lib/comment_extractor/parser.rb +33 -0
- data/lib/comment_extractor/smart_string_scanner.rb +11 -0
- data/lib/comment_extractor/version.rb +4 -0
- data/lib/comment_extractor.rb +18 -0
- data/spec/assets/binary_file +0 -0
- data/spec/assets/shebang_file +3 -0
- data/spec/assets/source_code/c.c +158 -0
- data/spec/assets/source_code/cc.cc +24 -0
- data/spec/assets/source_code/class +0 -0
- data/spec/assets/source_code/clojure.clj +41 -0
- data/spec/assets/source_code/coffee.coffee +27 -0
- data/spec/assets/source_code/cpp.cpp +130 -0
- data/spec/assets/source_code/cs.cs +53 -0
- data/spec/assets/source_code/css.css +37 -0
- data/spec/assets/source_code/cxx +0 -0
- data/spec/assets/source_code/d.d +110 -0
- data/spec/assets/source_code/erlang.es +34 -0
- data/spec/assets/source_code/fortran.f +41 -0
- data/spec/assets/source_code/golang.go +61 -0
- data/spec/assets/source_code/h +0 -0
- data/spec/assets/source_code/haml.haml +26 -0
- data/spec/assets/source_code/haskell.hs +36 -0
- data/spec/assets/source_code/hpp +0 -0
- data/spec/assets/source_code/html.html +139 -0
- data/spec/assets/source_code/java.java +39 -0
- data/spec/assets/source_code/java_script.js +164 -0
- data/spec/assets/source_code/lisp.el +18 -0
- data/spec/assets/source_code/lua.lua +34 -0
- data/spec/assets/source_code/m +0 -0
- data/spec/assets/source_code/mm +0 -0
- data/spec/assets/source_code/perl.pl +36 -0
- data/spec/assets/source_code/php.php +31 -0
- data/spec/assets/source_code/python.py +139 -0
- data/spec/assets/source_code/ruby.rb +36 -0
- data/spec/assets/source_code/sass.sass +77 -0
- data/spec/assets/source_code/scala.scala +46 -0
- data/spec/assets/source_code/scss.scss +93 -0
- data/spec/assets/source_code/shell.sh +5 -0
- data/spec/assets/source_code/sqf +0 -0
- data/spec/assets/source_code/sql.sql +11 -0
- data/spec/assets/source_code/sqs +0 -0
- data/spec/assets/source_code/tex.tex +20 -0
- data/spec/assets/source_code/text.txt +15 -0
- data/spec/assets/source_code/vim +17 -0
- data/spec/assets/source_code/yaml.yml +44 -0
- data/spec/assets/stripper/children/children +0 -0
- data/spec/assets/stripper/children/children.c +0 -0
- data/spec/assets/stripper/children/children.js +0 -0
- data/spec/assets/stripper/children/children.o +0 -0
- data/spec/assets/stripper/children/children.rb +1 -0
- data/spec/assets/stripper/test +0 -0
- data/spec/assets/stripper/test.c +0 -0
- data/spec/assets/stripper/test.js +0 -0
- data/spec/assets/stripper/test.o +0 -0
- data/spec/assets/stripper/test.rb +1 -0
- data/spec/comment_extractor/code_object/comment_spec.rb +15 -0
- data/spec/comment_extractor/code_object_spec.rb +18 -0
- data/spec/comment_extractor/code_objects_spec.rb +66 -0
- data/spec/comment_extractor/configuration_spec.rb +68 -0
- data/spec/comment_extractor/encoding_spec.rb +77 -0
- data/spec/comment_extractor/extractor/c_spec.rb +9 -0
- data/spec/comment_extractor/extractor/cc_spec.rb +9 -0
- data/spec/comment_extractor/extractor/class_spec.rb +9 -0
- data/spec/comment_extractor/extractor/clojure_spec.rb +9 -0
- data/spec/comment_extractor/extractor/coffee_spec.rb +9 -0
- data/spec/comment_extractor/extractor/cpp_spec.rb +9 -0
- data/spec/comment_extractor/extractor/cs_spec.rb +9 -0
- data/spec/comment_extractor/extractor/css_spec.rb +9 -0
- data/spec/comment_extractor/extractor/cxx_spec.rb +9 -0
- data/spec/comment_extractor/extractor/d_spec.rb +10 -0
- data/spec/comment_extractor/extractor/erlang_spec.rb +10 -0
- data/spec/comment_extractor/extractor/fortran_spec.rb +9 -0
- data/spec/comment_extractor/extractor/go_spec.rb +9 -0
- data/spec/comment_extractor/extractor/h_spec.rb +9 -0
- data/spec/comment_extractor/extractor/haml_spec.rb +9 -0
- data/spec/comment_extractor/extractor/haskell_spec.rb +9 -0
- data/spec/comment_extractor/extractor/hpp_spec.rb +9 -0
- data/spec/comment_extractor/extractor/html_spec.rb +9 -0
- data/spec/comment_extractor/extractor/java_script_spec.rb +10 -0
- data/spec/comment_extractor/extractor/java_spec.rb +9 -0
- data/spec/comment_extractor/extractor/lisp_spec.rb +9 -0
- data/spec/comment_extractor/extractor/lua_spec.rb +9 -0
- data/spec/comment_extractor/extractor/m_spec.rb +9 -0
- data/spec/comment_extractor/extractor/markdown_spec.rb +8 -0
- data/spec/comment_extractor/extractor/mm_spec.rb +9 -0
- data/spec/comment_extractor/extractor/perl_spec.rb +9 -0
- data/spec/comment_extractor/extractor/php_spec.rb +9 -0
- data/spec/comment_extractor/extractor/python_spec.rb +9 -0
- data/spec/comment_extractor/extractor/ruby_spec.rb +12 -0
- data/spec/comment_extractor/extractor/sass_spec.rb +9 -0
- data/spec/comment_extractor/extractor/scala_spec.rb +9 -0
- data/spec/comment_extractor/extractor/scss_spec.rb +9 -0
- data/spec/comment_extractor/extractor/shell_spec.rb +9 -0
- data/spec/comment_extractor/extractor/sqf_spec.rb +9 -0
- data/spec/comment_extractor/extractor/sql_spec.rb +9 -0
- data/spec/comment_extractor/extractor/sqs_spec.rb +9 -0
- data/spec/comment_extractor/extractor/tex_spec.rb +9 -0
- data/spec/comment_extractor/extractor/text_spec.rb +7 -0
- data/spec/comment_extractor/extractor/yaml_spec.rb +9 -0
- data/spec/comment_extractor/extractor_manager_spec.rb +233 -0
- data/spec/comment_extractor/extractor_spec.rb +102 -0
- data/spec/comment_extractor/file_spec.rb +100 -0
- data/spec/comment_extractor/parser_spec.rb +67 -0
- data/spec/comment_extractor/smart_string_scanner_spec.rb +24 -0
- data/spec/comment_extractor/version_spec.rb +8 -0
- data/spec/comment_extractor_spec.rb +15 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/rspec/comment_extractor/extractor_example_group.rb +115 -0
- data/spec/support/rspec/comment_extractor/matchers/extract_comment.rb +58 -0
- data/spec/support/rspec/comment_extractor/matchers.rb +7 -0
- data/spec/support/rspec/comment_extractor.rb +6 -0
- metadata +370 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'comment_extractor/extractor_manager'
|
|
3
|
+
|
|
4
|
+
module CommentExtractor
|
|
5
|
+
describe ExtractorManager do
|
|
6
|
+
after do
|
|
7
|
+
if described_class.instance_variable_defined?(:@extractors)
|
|
8
|
+
described_class.send(:remove_instance_variable, :@extractors)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def registered_extractors
|
|
13
|
+
described_class.instance_variable_get(:@extractors)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe 'PublicModuleMethods' do
|
|
17
|
+
describe '.regist_extractor' do
|
|
18
|
+
subject { registered_extractors }
|
|
19
|
+
|
|
20
|
+
before do
|
|
21
|
+
described_class.regist_extractor(extractor)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
let(:extractor) { :Object }
|
|
25
|
+
|
|
26
|
+
context "given a extractor's symbol or Klass" do
|
|
27
|
+
it 'registers a extractor to self' do
|
|
28
|
+
expect(subject).to have_key(extractor)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe '.default_extractors' do
|
|
34
|
+
subject { described_class.default_extractors }
|
|
35
|
+
|
|
36
|
+
it 'returns Array contains default extractors' do
|
|
37
|
+
expect(subject).to be_an_instance_of Array
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe 'Finding extractor methods' do
|
|
43
|
+
before do
|
|
44
|
+
described_class.instance_variable_set(:@extractor_definitions, definitions)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
let(:definitions) do
|
|
48
|
+
{
|
|
49
|
+
shebang: {
|
|
50
|
+
regexp: /(\/node$)|(ruby$)/,
|
|
51
|
+
values: ['JavaScript', 'Ruby']
|
|
52
|
+
},
|
|
53
|
+
filename: {
|
|
54
|
+
regexp: /(\.js$)|(\.rb$|Gemfile$|Rakefile)/,
|
|
55
|
+
values: ['JavaScript', 'Ruby']
|
|
56
|
+
},
|
|
57
|
+
filetype: {
|
|
58
|
+
'key' => 'value',
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
shared_context 'trying to find extractor' do
|
|
64
|
+
context 'given a registered value' do
|
|
65
|
+
let(:test_value) { registed_value }
|
|
66
|
+
it 'finds ExtractorKlass' do
|
|
67
|
+
should eql 'Ruby'
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'given a non-matching string' do
|
|
72
|
+
let(:test_value) { '' }
|
|
73
|
+
it { should be_nil }
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe '.find_extractor_by_shebang' do
|
|
78
|
+
subject { described_class.find_extractor_by_shebang(test_value) }
|
|
79
|
+
let(:registed_value) { '#! /usr/local/ruby' }
|
|
80
|
+
|
|
81
|
+
it_behaves_like 'trying to find extractor'
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe '.find_extractor_by_filename' do
|
|
85
|
+
subject { described_class.find_extractor_by_filename(test_value) }
|
|
86
|
+
let(:registed_value) { 'path/to/file.rb' }
|
|
87
|
+
|
|
88
|
+
it_behaves_like 'trying to find extractor'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
describe '.find_extractor_by_filetype' do
|
|
92
|
+
subject { described_class.find_extractor_by_filetype('key') }
|
|
93
|
+
|
|
94
|
+
it 'finds ExtractorKlass by matching file type' do
|
|
95
|
+
should eql 'value'
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe '.can_extract' do
|
|
100
|
+
subject { described_class.can_extract(file_path) }
|
|
101
|
+
|
|
102
|
+
before do
|
|
103
|
+
allow(File).to receive(:binary?).with(file_path) { binary? }
|
|
104
|
+
allow(File).to receive(:shebang).with(file_path) { shebang }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
let(:file_path) { '/path/to/file' }
|
|
108
|
+
let(:shebang) { nil }
|
|
109
|
+
let(:binary?) { false }
|
|
110
|
+
|
|
111
|
+
context 'given a binary file' do
|
|
112
|
+
let(:binary?) { true }
|
|
113
|
+
it { should be_nil }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context 'given a file that does not contain shebang' do
|
|
117
|
+
let(:file_path) { '/path/to/ruby.rb' }
|
|
118
|
+
|
|
119
|
+
it 'finds ExtractorKlass by file name' do
|
|
120
|
+
should eql 'Ruby'
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context 'given a file that contains shebang' do
|
|
125
|
+
let(:shebang) { '/usr/bin/node' }
|
|
126
|
+
|
|
127
|
+
it 'finds ExtractorKlass by shebang' do
|
|
128
|
+
should eql 'JavaScript'
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context 'when extractor is not found' do
|
|
133
|
+
before do
|
|
134
|
+
allow(::CommentExtractor).to receive(:configuration).
|
|
135
|
+
and_return(stub_configuration)
|
|
136
|
+
allow(ExtractorManager).to receive(:find_extractor_by_shebang).
|
|
137
|
+
and_return(nil)
|
|
138
|
+
allow(ExtractorManager).to receive(:find_extractor_by_filename).
|
|
139
|
+
and_return(nil)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
let(:stub_configuration) do
|
|
143
|
+
double.tap do |c|
|
|
144
|
+
allow(c).to receive(:default_extractor).and_return(default_extractor)
|
|
145
|
+
allow(c).to receive(:use_default_extractor).and_return(use_default_extractor)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
let(:default_extractor) { Extractor }
|
|
149
|
+
|
|
150
|
+
context 'when configuration.use_default_extractor is true' do
|
|
151
|
+
let(:use_default_extractor) { true }
|
|
152
|
+
it 'uses default extractor as an alternative to specific scanner' do
|
|
153
|
+
expect(subject).to eql default_extractor
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
context 'when configuration.use_default_extractor is true' do
|
|
158
|
+
let(:use_default_extractor) { false }
|
|
159
|
+
it 'does not uses default extractor as an alternative to specific scanner' do
|
|
160
|
+
expect(subject).to be_nil
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
context 'PrivateModuleMethods' do
|
|
168
|
+
describe '.initialize_extractors!' do
|
|
169
|
+
subject { registered_extractors }
|
|
170
|
+
|
|
171
|
+
let(:described_method) { described_class.send(:initialize_extractors!) }
|
|
172
|
+
let(:default_extractors) { ExtractorManager.default_extractors }
|
|
173
|
+
|
|
174
|
+
it 'initializes extractors' do
|
|
175
|
+
expect(subject).to be_nil
|
|
176
|
+
described_method
|
|
177
|
+
expect(registered_extractors.keys).to match_array default_extractors
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
describe '.build_extractor_definitions' do
|
|
182
|
+
subject { described_class.send(:build_extractor_definitions) }
|
|
183
|
+
|
|
184
|
+
before do
|
|
185
|
+
allow(described_class).to receive(:extractors).and_return(extractors)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def build_extractor(name)
|
|
189
|
+
double.tap do |e|
|
|
190
|
+
allow(e).to receive(:disabled?).and_return(false)
|
|
191
|
+
allow(e).to receive(:shebang).and_return(/#{name}/)
|
|
192
|
+
allow(e).to receive(:filetype).and_return(name)
|
|
193
|
+
allow(e).to receive(:filename).and_return(/\.#{name}$/)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
let(:extractors) do
|
|
198
|
+
{
|
|
199
|
+
Ruby: ruby_extractor,
|
|
200
|
+
Php: php_extractor,
|
|
201
|
+
}
|
|
202
|
+
end
|
|
203
|
+
let(:php_extractor) { build_extractor('php') }
|
|
204
|
+
let(:ruby_extractor) { build_extractor('ruby') }
|
|
205
|
+
let(:expected_regexp) do
|
|
206
|
+
{
|
|
207
|
+
shebang: /(ruby)|(php)/,
|
|
208
|
+
filename: /(\.ruby$)|(\.php$)/,
|
|
209
|
+
filetype: {
|
|
210
|
+
'php' => php_extractor,
|
|
211
|
+
'ruby' => ruby_extractor,
|
|
212
|
+
},
|
|
213
|
+
}
|
|
214
|
+
end
|
|
215
|
+
let(:defined_extractor_finders) do
|
|
216
|
+
described_class.send(:defined_extractor_finders)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
it 'builds extractor definitions' do
|
|
220
|
+
expect(subject).to be_an_instance_of Hash
|
|
221
|
+
|
|
222
|
+
[:filename, :shebang].each do |finder|
|
|
223
|
+
expect(subject[finder]).to be_an_instance_of Hash
|
|
224
|
+
expect(subject[finder][:regexp]).to eql expected_regexp[finder]
|
|
225
|
+
expect(subject[finder][:values]).to be_an_instance_of Array
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
expect(subject[:filetype]).to eql expected_regexp[:filetype]
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'comment_extractor/extractor'
|
|
3
|
+
|
|
4
|
+
module CommentExtractor
|
|
5
|
+
describe Extractor do
|
|
6
|
+
let(:content) { File.read(__FILE__) }
|
|
7
|
+
let(:scanner_object) { Extractor.new(content) }
|
|
8
|
+
|
|
9
|
+
describe 'ClassMethods' do
|
|
10
|
+
let(:scanner_klass) { Extractor }
|
|
11
|
+
|
|
12
|
+
describe '.new' do
|
|
13
|
+
subject { scanner_object }
|
|
14
|
+
it { expect { subject }.to_not raise_error }
|
|
15
|
+
|
|
16
|
+
it 'initializes attributes' do
|
|
17
|
+
expect(subject.content).to eql content
|
|
18
|
+
expect(subject.code_objects).to be_an_instance_of CodeObjects
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '.disable!' do
|
|
23
|
+
it 'disables own status' do
|
|
24
|
+
expect(scanner_klass.disabled?).to be_falsy
|
|
25
|
+
scanner_klass.disable!
|
|
26
|
+
expect(scanner_klass.disabled?).to be_truthy
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'schema' do
|
|
31
|
+
after do
|
|
32
|
+
scanner_klass.send(:remove_instance_variable, :@schema)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
shared_examples_for 'a setting schema' do
|
|
36
|
+
before do
|
|
37
|
+
scanner_klass.send(key, value)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'defines schemas for own' do
|
|
41
|
+
expect(scanner_klass.schema).to eql({ key => value })
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe '.shebang' do
|
|
46
|
+
let(:value) { %r!#\! path/to/test! }
|
|
47
|
+
let(:key) { :shebang }
|
|
48
|
+
it_should_behave_like 'a setting schema'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe '.filetype' do
|
|
52
|
+
let(:value) { 'ruby' }
|
|
53
|
+
let(:key) { :filetype }
|
|
54
|
+
it_should_behave_like 'a setting schema'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe '.filename' do
|
|
58
|
+
let(:value) { /\.rb$/ }
|
|
59
|
+
let(:key) { :filename }
|
|
60
|
+
it_should_behave_like 'a setting schema'
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe 'PublicInstanceMethods' do
|
|
66
|
+
describe '#extract_comments' do
|
|
67
|
+
subject { scanner_object.extract_comments }
|
|
68
|
+
it { expect { subject }.to raise_error(NotImplementedError) }
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe 'ProtectedInstanceMethods' do
|
|
73
|
+
describe '#scan' do
|
|
74
|
+
subject { scanner_object.send(:scan) }
|
|
75
|
+
it { expect { subject }.to raise_error(NotImplementedError) }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe '#scanner' do
|
|
79
|
+
subject { scanner_object.send(:scanner) }
|
|
80
|
+
it { should be_an_instance_of(StringScanner) }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe '#build_comment' do
|
|
84
|
+
subject { scanner_object.send(:build_comment, 1, 'comment') }
|
|
85
|
+
it { should be_an_instance_of CodeObject::Comment }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe '#content' do
|
|
89
|
+
subject { scanner_object.content }
|
|
90
|
+
it { should be_an_instance_of String }
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe 'PrivateInstanceMethods' do
|
|
95
|
+
describe '#raise_report' do
|
|
96
|
+
subject { scanner_object.send(:raise_report) }
|
|
97
|
+
|
|
98
|
+
it { expect { subject }.to raise_error(Extractor::SyntaxDefinitionError) }
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'comment_extractor/file'
|
|
3
|
+
require 'tempfile'
|
|
4
|
+
|
|
5
|
+
using CommentExtractor::DetectableSchemeFile
|
|
6
|
+
|
|
7
|
+
module CommentExtractor
|
|
8
|
+
describe DetectableSchemeFile do
|
|
9
|
+
let(:file) { File.new(file_path) }
|
|
10
|
+
let(:asset_dir) { File.expand_path('../../assets', __FILE__) }
|
|
11
|
+
let(:binary_path) { "#{asset_dir}/binary_file" }
|
|
12
|
+
|
|
13
|
+
describe 'ClassMethods' do
|
|
14
|
+
describe '.shebang' do
|
|
15
|
+
subject { File.shebang(file.path) }
|
|
16
|
+
let(:file_path) do
|
|
17
|
+
Tempfile.new('tempfile').tap do |f|
|
|
18
|
+
f.write(content)
|
|
19
|
+
f.flush
|
|
20
|
+
f.path
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
let(:content) { '' }
|
|
24
|
+
|
|
25
|
+
before do
|
|
26
|
+
allow(File).to receive(:extname).and_return(extname)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'when initialized file with a extension' do
|
|
30
|
+
let(:extname) { '.rb' }
|
|
31
|
+
it { should be_nil }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'when initialized file with no extension' do
|
|
35
|
+
let(:extname) { '' }
|
|
36
|
+
|
|
37
|
+
context 'content has no shebang' do
|
|
38
|
+
it 'does not detect shebang' do
|
|
39
|
+
should be_nil
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context 'content has a shebang' do
|
|
44
|
+
let(:content) { "#! /usr/local/bin/ruby\n" }
|
|
45
|
+
|
|
46
|
+
it 'detects shebang' do
|
|
47
|
+
should eql '/usr/local/bin/ruby'
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe '.binary?' do
|
|
54
|
+
subject { File.binary?(file_path) }
|
|
55
|
+
|
|
56
|
+
context 'given the binary file' do
|
|
57
|
+
let(:file_path) { binary_path }
|
|
58
|
+
it { should be_truthy }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context 'given the source file' do
|
|
62
|
+
let(:file_path) { __FILE__ }
|
|
63
|
+
it { should be_falsy }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe '#read_content' do
|
|
69
|
+
subject { file.read_content }
|
|
70
|
+
|
|
71
|
+
context 'given a binary_file' do
|
|
72
|
+
let(:file_path) { binary_path }
|
|
73
|
+
it { should be_nil }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'given a source code file' do
|
|
77
|
+
let(:file_path) { __FILE__ }
|
|
78
|
+
|
|
79
|
+
it "returns file's content" do
|
|
80
|
+
should eql File.read(file_path)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context 'contains shebang' do
|
|
84
|
+
let(:body) { 'HelloWorld' }
|
|
85
|
+
let(:file_path) do
|
|
86
|
+
Tempfile.new('tempfile').tap do |f|
|
|
87
|
+
f.write("#! /usr/local/shebang\n#{body}")
|
|
88
|
+
f.flush
|
|
89
|
+
f.path
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'equals the result without shebang' do
|
|
94
|
+
should eql body
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'comment_extractor/parser'
|
|
3
|
+
|
|
4
|
+
using CommentExtractor::DetectableSchemeFile
|
|
5
|
+
|
|
6
|
+
module CommentExtractor
|
|
7
|
+
describe Parser do
|
|
8
|
+
let(:expected_comments) { [] }
|
|
9
|
+
let(:stub_extractor) do
|
|
10
|
+
Class.new(CommentExtractor::Extractor).tap do |extractor|
|
|
11
|
+
allow(extractor).to receive(:extract_comments).and_return(expected_comments)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe 'InstanceMethods' do
|
|
16
|
+
let(:parser) { described_class.new(stub_extractor) }
|
|
17
|
+
|
|
18
|
+
describe '#extract_comments' do
|
|
19
|
+
subject { parser.extract_comments }
|
|
20
|
+
|
|
21
|
+
context 'when initialized by a correct type Extractor' do
|
|
22
|
+
before do
|
|
23
|
+
expect(stub_extractor).to receive(:extract_comments).once
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'parses file and returns comments' do
|
|
27
|
+
expect(subject).to be_an_instance_of Array
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'when initialized by not instance of Extractor' do
|
|
32
|
+
let(:parser) { described_class.new(nil) }
|
|
33
|
+
it { expect { subject }.to raise_error(TypeError) }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe 'ClassMethods' do
|
|
39
|
+
describe '.for' do
|
|
40
|
+
subject { described_class.for(file_path) }
|
|
41
|
+
let(:file_path) { __FILE__ }
|
|
42
|
+
|
|
43
|
+
context 'when extractor is found' do
|
|
44
|
+
before do
|
|
45
|
+
allow(ExtractorManager).to receive(:can_extract).
|
|
46
|
+
and_return(stub_extractor)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'initializes extractor' do
|
|
50
|
+
expect(subject).to be_an_instance_of described_class
|
|
51
|
+
extractor = subject.extractor
|
|
52
|
+
expect(extractor).to be_a Extractor
|
|
53
|
+
expect(extractor.code_objects.file).to eql file_path
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe '.new' do
|
|
59
|
+
subject { described_class.new(stub_extractor) }
|
|
60
|
+
|
|
61
|
+
it 'initializes a instance of Parser' do
|
|
62
|
+
expect { subject }.to_not raise_error
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'comment_extractor/smart_string_scanner'
|
|
3
|
+
|
|
4
|
+
using CommentExtractor::SmartStringScanner
|
|
5
|
+
|
|
6
|
+
module CommentExtractor
|
|
7
|
+
describe SmartStringScanner do
|
|
8
|
+
let(:scanner) { StringScanner.new("...\n...") }
|
|
9
|
+
|
|
10
|
+
describe 'refines #current_line' do
|
|
11
|
+
context 'when scanner has already used' do
|
|
12
|
+
it 'returns current line number' do
|
|
13
|
+
expect(scanner.current_line).to eql 1
|
|
14
|
+
|
|
15
|
+
scanner.scan(/^.*$/) # Scanning one line
|
|
16
|
+
expect(scanner.current_line).to eql 1
|
|
17
|
+
|
|
18
|
+
scanner.scan(/\n/) # Go to next line
|
|
19
|
+
expect(scanner.current_line).to eql 2
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'comment_extractor'
|
|
3
|
+
|
|
4
|
+
describe CommentExtractor do
|
|
5
|
+
describe 'ClassMethods' do
|
|
6
|
+
describe '.configuration' do
|
|
7
|
+
subject { described_class.configuration }
|
|
8
|
+
it { should be_an_instance_of CommentExtractor::Configuration }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe '.configure' do
|
|
12
|
+
it { expect { |b| described_class.configure(&b) }.to yield_control }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'rspec'
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'coveralls'
|
|
5
|
+
Coveralls.wear!
|
|
6
|
+
rescue LoadError
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
|
10
|
+
$LOAD_PATH.unshift File.expand_path('../support', __FILE__)
|
|
11
|
+
require 'rspec/comment_extractor'
|
|
12
|
+
|
|
13
|
+
RSpec.configure do |config|
|
|
14
|
+
config.order = 'random'
|
|
15
|
+
config.run_all_when_everything_filtered = true
|
|
16
|
+
config.show_failures_in_pending_blocks = true
|
|
17
|
+
config.raise_errors_for_deprecations!
|
|
18
|
+
config.include RSpec::CommentExtractor::ExtractorExampleGroup, type: :extractor, example_group: {
|
|
19
|
+
file_path: Regexp.compile(%w[spec comment_extractor extractor .*.rb].join('[\\\/]'))
|
|
20
|
+
}
|
|
21
|
+
config.source_code_path = 'spec/assets/source_code'
|
|
22
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
RSpec.configure do |config|
|
|
2
|
+
config.add_setting :source_code_path, default: 'spec/assets/source_code'
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
module RSpec::CommentExtractor::ExtractorExampleGroup
|
|
6
|
+
include RSpec::CommentExtractor::Matchers::ExtractComment
|
|
7
|
+
|
|
8
|
+
def build_extractor(content = nil)
|
|
9
|
+
described_class.new(content)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def source_code_path(file_name = nil)
|
|
13
|
+
dir = RSpec.configuration.source_code_path
|
|
14
|
+
file_name ? "#{dir}/#{file_name}" : dir
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.included(k)
|
|
18
|
+
k.class_eval do
|
|
19
|
+
# Initialize shared_examples
|
|
20
|
+
shared_examples_for 'extracting comments from' do |*file_names|
|
|
21
|
+
context '.extract_comments' do
|
|
22
|
+
raise 'file_names did not given' if file_names.empty?
|
|
23
|
+
|
|
24
|
+
file_names.each do |file_name|
|
|
25
|
+
context "given a content in #{file_name}" do
|
|
26
|
+
let(:path) { source_code_path(file_name) }
|
|
27
|
+
let(:content) { File.open(path) { |f| f.read } }
|
|
28
|
+
let(:expected_comments) do
|
|
29
|
+
content.split("\n").each_with_object({}) do |line, memo|
|
|
30
|
+
if %r!(?<comment>\[-(?<line_number>\d+)-\].*)$! =~ line
|
|
31
|
+
comment.sub!(/(?<=\[-end-\]).*$/, '') if comment =~ /\[-end-\]/
|
|
32
|
+
memo[line_number.to_i] = comment
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
let(:extracted_comments) { extractor.extract_comments }
|
|
37
|
+
|
|
38
|
+
it 'scans content' do
|
|
39
|
+
expect { extracted_comments }.to extract_comment(expected_comments)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
shared_examples_for 'a schema' do |key, *expected_list|
|
|
47
|
+
let(:schema) { extractor.class.send(key) }
|
|
48
|
+
|
|
49
|
+
expected_list.each do |expected|
|
|
50
|
+
context "Given '#{expected}'" do
|
|
51
|
+
it "detects extractor" do
|
|
52
|
+
expect(expected).to match schema
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Schema does not have to contain group regexp because of the optimization.
|
|
58
|
+
it 'does not contain group regexp; You need to remove `/()/`' do
|
|
59
|
+
matcher = Regexp.new([schema.source, /.*/.source].join('|'))
|
|
60
|
+
|
|
61
|
+
expect(matcher.match('_').length).to eql 1
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
shared_examples_for 'detecting shebang' do |*shebangs|
|
|
66
|
+
describe '.shebang' do
|
|
67
|
+
it_behaves_like 'a schema', :shebang, *shebangs
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
shared_examples_for 'detecting filename' do |*filenames|
|
|
72
|
+
describe '.filename' do
|
|
73
|
+
it_behaves_like 'a schema', :filename, *filenames
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Initialize example groups and run test
|
|
78
|
+
metadata[:type] = :extractor
|
|
79
|
+
|
|
80
|
+
let(:content) { '' }
|
|
81
|
+
let(:extractor) { build_extractor(content) }
|
|
82
|
+
|
|
83
|
+
context '.filetype' do
|
|
84
|
+
subject { extractor.class.filetype }
|
|
85
|
+
|
|
86
|
+
it 'should be defined' do
|
|
87
|
+
should_not be_nil
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'defines a instance of Array or String' do
|
|
91
|
+
string_or_array = subject.is_a?(String) || subject.is_a?(Array)
|
|
92
|
+
expect(string_or_array).to be_truthy
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Skips test when extractor has already disabled
|
|
97
|
+
if metadata[:disabled]
|
|
98
|
+
shared_examples_for 'disabled' do
|
|
99
|
+
subject { described_class.disabled? }
|
|
100
|
+
it { expect(subject).to be_truthy }
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it_behaves_like 'disabled'
|
|
104
|
+
|
|
105
|
+
pending 'disabled extractor'
|
|
106
|
+
|
|
107
|
+
next
|
|
108
|
+
else
|
|
109
|
+
context '.new' do
|
|
110
|
+
it { expect { extractor }.to_not raise_error }
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|