front_matter_parser 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +19 -0
  3. data/.gitignore +1 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +50 -0
  6. data/.travis.yml +19 -1
  7. data/CHANGELOG.md +30 -0
  8. data/Dockerfile +5 -0
  9. data/Gemfile +0 -2
  10. data/README.md +76 -38
  11. data/Rakefile +5 -3
  12. data/bin/console +15 -0
  13. data/bin/setup +8 -0
  14. data/docker-compose.yml +12 -0
  15. data/front_matter_parser.gemspec +12 -6
  16. data/lib/front_matter_parser.rb +10 -114
  17. data/lib/front_matter_parser/loader.rb +11 -0
  18. data/lib/front_matter_parser/loader/yaml.rb +26 -0
  19. data/lib/front_matter_parser/parsed.rb +25 -14
  20. data/lib/front_matter_parser/parser.rb +82 -0
  21. data/lib/front_matter_parser/syntax_parser.rb +28 -0
  22. data/lib/front_matter_parser/syntax_parser/factorizable.rb +30 -0
  23. data/lib/front_matter_parser/syntax_parser/indentation_comment.rb +49 -0
  24. data/lib/front_matter_parser/syntax_parser/multi_line_comment.rb +50 -0
  25. data/lib/front_matter_parser/syntax_parser/single_line_comment.rb +64 -0
  26. data/lib/front_matter_parser/version.rb +3 -1
  27. data/spec/fixtures/example +6 -0
  28. data/spec/front_matter_parser/loader/yaml_spec.rb +24 -0
  29. data/spec/front_matter_parser/parsed_spec.rb +11 -21
  30. data/spec/front_matter_parser/parser_spec.rb +111 -0
  31. data/spec/front_matter_parser/syntax_parser/indentation_comment_spec.rb +166 -0
  32. data/spec/front_matter_parser/syntax_parser/multi_line_comment_spec.rb +267 -0
  33. data/spec/front_matter_parser/syntax_parser/single_line_comment_spec.rb +175 -0
  34. data/spec/front_matter_parser_spec.rb +3 -296
  35. data/spec/spec_helper.rb +9 -3
  36. data/spec/support/matcher.rb +8 -0
  37. metadata +110 -46
  38. data/spec/fixtures/example.coffee +0 -4
  39. data/spec/fixtures/example.erb +0 -6
  40. data/spec/fixtures/example.foo +0 -0
  41. data/spec/fixtures/example.haml +0 -5
  42. data/spec/fixtures/example.liquid +0 -6
  43. data/spec/fixtures/example.md +0 -4
  44. data/spec/fixtures/example.sass +0 -4
  45. data/spec/fixtures/example.scss +0 -4
  46. data/spec/fixtures/example.slim +0 -5
  47. data/spec/support/strings.rb +0 -41
  48. data/spec/support/syntaxs.rb +0 -14
  49. data/spec/support/utils.rb +0 -6
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe FrontMatterParser::SyntaxParser::SingleLineComment do
6
+ subject(:parsed) { FrontMatterParser::Parser.new(syntax).call(string) }
7
+
8
+ let(:front_matter) { { 'title' => 'hello', 'author' => 'me' } }
9
+ let(:content) { "Content\n" }
10
+
11
+ context 'when syntax is coffee' do
12
+ let(:syntax) { :coffee }
13
+ let(:string) do
14
+ <<~STRING
15
+ #---
16
+ #title: hello
17
+ #author: me
18
+ #---
19
+ Content
20
+ STRING
21
+ end
22
+
23
+ it 'can parse it' do
24
+ expect(parsed).to be_parsed_result_with(front_matter, content)
25
+ end
26
+ end
27
+
28
+ context 'when syntax is sass' do
29
+ let(:syntax) { :sass }
30
+ let(:string) do
31
+ <<~STRING
32
+ //---
33
+ //title: hello
34
+ //author: me
35
+ //---
36
+ Content
37
+ STRING
38
+ end
39
+
40
+ it 'can parse it' do
41
+ expect(parsed).to be_parsed_result_with(front_matter, content)
42
+ end
43
+ end
44
+
45
+ context 'when syntax is scss' do
46
+ let(:syntax) { :scss }
47
+ let(:string) do
48
+ <<~STRING
49
+ //---
50
+ //title: hello
51
+ //author: me
52
+ //---
53
+ Content
54
+ STRING
55
+ end
56
+
57
+ it 'can parse it' do
58
+ expect(parsed).to be_parsed_result_with(front_matter, content)
59
+ end
60
+ end
61
+
62
+ context 'with space before comment delimiters' do
63
+ let(:syntax) { :coffee }
64
+ let(:string) do
65
+ <<~STRING
66
+ #---
67
+ #title: hello
68
+ #author: me
69
+ #---
70
+ Content
71
+ STRING
72
+ end
73
+
74
+ it 'can parse it' do
75
+ expect(parsed).to be_parsed_result_with(front_matter, content)
76
+ end
77
+ end
78
+
79
+ context 'with space between comment delimiters and front matter' do
80
+ let(:syntax) { :coffee }
81
+ let(:string) do
82
+ <<~STRING
83
+ # ---
84
+ # title: hello
85
+ # author: me
86
+ # ---
87
+ Content
88
+ STRING
89
+ end
90
+
91
+ it 'can parse it' do
92
+ expect(parsed).to be_parsed_result_with(front_matter, content)
93
+ end
94
+ end
95
+
96
+ context 'with space within front matter' do
97
+ let(:syntax) { :coffee }
98
+ let(:string) do
99
+ <<~STRING
100
+ # ---
101
+ # title: hello
102
+ #
103
+ # author: me
104
+ # ---
105
+ Content
106
+ STRING
107
+ end
108
+
109
+ it 'can parse it' do
110
+ expect(parsed).to be_parsed_result_with(front_matter, content)
111
+ end
112
+ end
113
+
114
+ context 'with uncommented lines between front matter' do
115
+ let(:syntax) { :coffee }
116
+ let(:string) do
117
+ <<~STRING
118
+ # ---
119
+ # title: hello
120
+
121
+ # author: me
122
+ # ---
123
+ Content
124
+ STRING
125
+ end
126
+
127
+ it 'can parse it' do
128
+ expect(parsed).to be_parsed_result_with(front_matter, content)
129
+ end
130
+ end
131
+
132
+ context 'with comment delimiter in the front matter' do
133
+ let(:syntax) { :sass }
134
+ let(:string) do
135
+ <<~STRING
136
+ //---
137
+ //title: //hello
138
+ //author: me
139
+ //---
140
+ Content
141
+ STRING
142
+ end
143
+
144
+ it 'can parse it' do
145
+ front_matter = { 'title' => '//hello', 'author' => 'me' }
146
+
147
+ expect(parsed).to be_parsed_result_with(front_matter, content)
148
+ end
149
+ end
150
+
151
+ context 'with front matter delimiter chars in the content' do
152
+ let(:syntax) { :sass }
153
+ let(:string) do
154
+ <<~STRING
155
+ //---
156
+ //title: hello
157
+ //---
158
+ //---
159
+ Content
160
+ STRING
161
+ end
162
+
163
+ it 'is not greedy' do
164
+ front_matter = { 'title' => 'hello' }
165
+
166
+ expect(parsed).to be_parsed_result_with(front_matter, "//---\nContent\n")
167
+ end
168
+ end
169
+
170
+ it 'returns nil if no front matter is found' do
171
+ string = 'Content'
172
+
173
+ expect(FrontMatterParser::SyntaxParser::Coffee.new.call(string)).to be_nil
174
+ end
175
+ end
@@ -1,302 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe FrontMatterParser do
4
- let(:sample_fm) { {'title' => 'hello'} }
5
- let(:sample_c) { 'Content' }
6
-
7
6
  it 'has a version number' do
8
- expect(FrontMatterParser::VERSION).to_not be_nil
9
- end
10
-
11
- describe "#parse" do
12
- context "when the string has both front matter and content" do
13
- let(:parsed) { FrontMatterParser.parse(string) }
14
-
15
- it "parses the front matter as a hash" do
16
- expect(parsed.front_matter).to eq(sample_fm)
17
- end
18
-
19
- it "parses the content as a string" do
20
- expect(parsed.content).to eq(sample_c)
21
- end
22
- end
23
-
24
- context "when the string only has front matter" do
25
- let(:parsed) { FrontMatterParser.parse(string_no_content) }
26
-
27
- it "parses the front matter as a hash" do
28
- expect(parsed.front_matter).to eq(sample_fm)
29
- end
30
-
31
- it "parses the content as an empty string" do
32
- expect(parsed.content).to eq('')
33
- end
34
- end
35
-
36
- context "when an empty front matter is supplied" do
37
- let(:parsed) { FrontMatterParser.parse(string_no_front_matter) }
38
-
39
- it "parses the front matter as an empty hash" do
40
- expect(parsed.front_matter).to eq({})
41
- end
42
-
43
- it "parses the content as the whole string" do
44
- expect(parsed.content).to eq(sample_c)
45
- end
46
- end
47
-
48
- context "when an empty string is supplied" do
49
- let(:parsed) { FrontMatterParser.parse('') }
50
-
51
- it "parses the front matter as an empty hash" do
52
- expect(parsed.front_matter).to eq({})
53
- end
54
-
55
- it "parses the content as an empty string" do
56
- expect(parsed.content).to eq('')
57
- end
58
- end
59
-
60
- context "when :comment option is given" do
61
- it "takes it as the single line comment mark for the front matter" do
62
- parsed = FrontMatterParser.parse(string_comment('#'), comment: '#')
63
- expect(parsed.front_matter).to eq(sample_fm)
64
- end
65
-
66
- context "when :start_comment is given" do
67
- it "raises an ArgumentError" do
68
- expect { FrontMatterParser.parse(string_comment('#'), comment: '#', start_comment: '/')}.to raise_error ArgumentError
69
- end
70
- end
71
- end
72
-
73
- context "when :start_comment option is given" do
74
- context "when :end_comment option is not given" do
75
- it "takes :start_comment as the mark for a multiline comment closed by indentation for the front matter" do
76
- parsed = FrontMatterParser.parse(string_start_comment('/'), start_comment: '/')
77
- expect(parsed.front_matter).to eq(sample_fm)
78
- end
79
- end
80
-
81
- context "when :end_comment option is provided" do
82
- it "takes :start_comment and :end_comment as the multiline comment mark delimiters for the front matter" do
83
- parsed = FrontMatterParser.parse(string_start_end_comment('<!--', '-->'), start_comment: '<!--', end_coment: '-->')
84
- expect(parsed.front_matter).to eq(sample_fm)
85
- end
86
- end
87
- end
88
-
89
- context "when :end_comment option is given but :start_comment is not" do
90
- it "raises an ArgumentError" do
91
- expect {FrontMatterParser.parse(string_start_end_comment, end_comment: '-->')}.to raise_error(ArgumentError)
92
- end
93
- end
94
-
95
- context "when :syntax is given" do
96
- context "when :comment and :start_comment are not given" do
97
- syntaxs.each_pair do |name, value|
98
- it "can detect a #{name} syntax when its value is #{value}" do
99
- parsed = FrontMatterParser.parse(File.read(File.expand_path("../fixtures/example.#{value}", __FILE__)), syntax: value)
100
- expect(parsed.front_matter).to eq(sample_fm)
101
- end
102
- end
103
-
104
- it "raises an ArgumentError if syntax is not whithin COMMENT_DELIMITERS keys" do
105
- expect { FrontMatterParser.parse(string, syntax: :foo) }.to raise_error ArgumentError
106
- end
107
- end
108
-
109
- context "when :comment is given" do
110
- it ":syntax is ignored" do
111
- parsed = FrontMatterParser.parse(File.read(File.expand_path("../fixtures/example.coffee", __FILE__)), syntax: :slim, comment: '#' )
112
- expect(parsed.front_matter).to eq(sample_fm)
113
- end
114
- end
115
-
116
- context "when :start_comment is given" do
117
- it ":syntax is ignored" do
118
- parsed = FrontMatterParser.parse(File.read(File.expand_path("../fixtures/example.slim", __FILE__)), syntax: :coffee, start_comment: '/' )
119
- expect(parsed.front_matter).to eq(sample_fm)
120
- end
121
- end
122
- end
123
- end
124
-
125
- describe "#parse_file" do
126
- context "when the file has both front matter and content" do
127
- let(:parsed) { FrontMatterParser.parse_file(file_fixture(string), comment: '') }
128
-
129
- it "parses the front matter as a hash" do
130
- expect(parsed.front_matter).to eq(sample_fm)
131
- end
132
-
133
- it "parses the content as a string" do
134
- expect(parsed.content).to eq(sample_c)
135
- end
136
- end
137
-
138
- context "when the file only has front matter" do
139
- let(:parsed) { FrontMatterParser.parse_file(file_fixture(string_no_content), comment: '') }
140
-
141
- it "parses the front matter as a hash" do
142
- expect(parsed.front_matter).to eq(sample_fm)
143
- end
144
-
145
- it "parses the content as an empty string" do
146
- expect(parsed.content).to eq('')
147
- end
148
- end
149
-
150
- context "when the file has an empty front matter is supplied" do
151
- let(:parsed) { FrontMatterParser.parse_file(file_fixture(string_no_front_matter), comment: '') }
152
-
153
- it "parses the front matter as an empty hash" do
154
- expect(parsed.front_matter).to eq({})
155
- end
156
-
157
- it "parses the content as the whole string" do
158
- expect(parsed.content).to eq(sample_c)
159
- end
160
- end
161
-
162
- context "when the file has no content" do
163
- let(:parsed) { FrontMatterParser.parse_file(file_fixture(''), comment: '') }
164
-
165
- it "parses the front matter as an empty hash" do
166
- expect(parsed.front_matter).to eq({})
167
- end
168
-
169
- it "parses the content as an empty string" do
170
- expect(parsed.content).to eq('')
171
- end
172
- end
173
-
174
- context "when :comment option is given" do
175
- it "takes it as the single line comment mark for the front matter" do
176
- parsed = FrontMatterParser.parse_file(file_fixture(string_comment('#')), comment: '#')
177
- expect(parsed.front_matter).to eq(sample_fm)
178
- end
179
-
180
- context "when :start_comment is given" do
181
- it "raises an ArgumentError" do
182
- expect { FrontMatterParser.parse_file(file_fixture(string_comment('#')), comment: '#', start_comment: '/')}.to raise_error ArgumentError
183
- end
184
- end
185
- end
186
-
187
- context "when :start_comment option is given" do
188
- context "when :end_comment option is not given" do
189
- it "takes :start_comment as the mark for a multiline comment closed by indentation for the front matter" do
190
- parsed = FrontMatterParser.parse_file(file_fixture(string_start_comment('/')), start_comment: '/')
191
- expect(parsed.front_matter).to eq(sample_fm)
192
- end
193
- end
194
-
195
- context "when :end_comment option is provided" do
196
- it "takes :start_comment and :end_comment as the multiline comment mark delimiters for the front matter" do
197
- parsed = FrontMatterParser.parse_file(file_fixture(string_start_end_comment('<!--', '-->')), start_comment: '<!--', end_coment: '-->')
198
- expect(parsed.front_matter).to eq(sample_fm)
199
- end
200
- end
201
- end
202
-
203
- context "when :end_comment option is given but :start_comment is not" do
204
- it "raises an ArgumentError" do
205
- expect {FrontMatterParser.parse_file(file_fixture(string_start_end_comment), end_comment: '-->')}.to raise_error(ArgumentError)
206
- end
207
- end
208
-
209
- context "when :comment and :start_comment are not given" do
210
- syntaxs.each_pair do |name, value|
211
- it "can detect a #{name} syntax file when its extension is #{value}" do
212
- parsed = FrontMatterParser.parse_file(File.expand_path("../fixtures/example.#{value}", __FILE__))
213
- expect(parsed.front_matter).to eq(sample_fm)
214
- end
215
- end
216
-
217
- it "raises an ArgumentError if the file extension is not whithin COMMENT_DELIMITERS keys" do
218
- expect { FrontMatterParser.parse_file(File.expand_path("../fixtures/example.foo, __FILE__")) }.to raise_error RuntimeError
219
- end
220
-
221
- it "raises an ArgumentError if the file has no extension" do
222
- expect { FrontMatterParser.parse_file(File.expand_path("../fixtures/example, __FILE__")) }.to raise_error RuntimeError
223
- end
224
- end
225
- end
226
- end
227
-
228
- describe "the front matter" do
229
- let(:sample_fm) { {'title' => 'hello'} }
230
-
231
- it "can be indented" do
232
- string = %Q(
233
- ---
234
- title: hello
235
- ---
236
- Content)
237
- expect(FrontMatterParser.parse(string).front_matter).to eq(sample_fm)
238
- end
239
-
240
- it "can have each line commented" do
241
- string = %Q(
242
- #---
243
- #title: hello
244
- #---
245
- Content)
246
- expect(FrontMatterParser.parse(string, comment: '#').front_matter).to eq(sample_fm)
247
- end
248
-
249
- it "can be indented after the comment delimiter" do
250
- string = %Q(
251
- # ---
252
- # title: hello
253
- # ---
254
- Content)
255
- expect(FrontMatterParser.parse(string, comment: '#').front_matter).to eq(sample_fm)
256
- end
257
-
258
- it "can be between a multiline comment" do
259
- string = %Q(
260
- <!--
261
- ---
262
- title: hello
263
- ---
264
- -->
265
- Content)
266
- expect(FrontMatterParser.parse(string, start_comment: '<!--', end_comment: '-->').front_matter).to eq(sample_fm)
267
- end
268
-
269
- it "can have the multiline comment delimiters indented" do
270
- string = %Q(
271
- <!--
272
- ---
273
- title: hello
274
- ---
275
- -->
276
- Content)
277
- expect(FrontMatterParser.parse(string, start_comment: '<!--', end_comment: '-->').front_matter).to eq(sample_fm)
278
- end
279
-
280
- it "can have empty lines between the multiline comment delimiters and the front matter" do
281
- string = %Q(
282
- <!--
283
-
284
- ---
285
- title: hello
286
- ---
287
-
288
- -->
289
- Content)
290
- expect(FrontMatterParser.parse(string, start_comment: '<!--', end_comment: '-->').front_matter).to eq(sample_fm)
291
- end
292
-
293
- it "can have multiline comment delimited by indentation" do
294
- string = %Q(
295
- /
296
- ---
297
- title: hello
298
- ---
299
- Content)
300
- expect(FrontMatterParser.parse(string, start_comment: '/').front_matter).to eq(sample_fm)
7
+ expect(FrontMatterParser::VERSION).not_to be_nil
301
8
  end
302
9
  end