front_matter_parser 0.0.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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