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.
- checksums.yaml +5 -5
- data/.codeclimate.yml +19 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rubocop.yml +50 -0
- data/.travis.yml +19 -1
- data/CHANGELOG.md +30 -0
- data/Dockerfile +5 -0
- data/Gemfile +0 -2
- data/README.md +76 -38
- data/Rakefile +5 -3
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/docker-compose.yml +12 -0
- data/front_matter_parser.gemspec +12 -6
- data/lib/front_matter_parser.rb +10 -114
- data/lib/front_matter_parser/loader.rb +11 -0
- data/lib/front_matter_parser/loader/yaml.rb +26 -0
- data/lib/front_matter_parser/parsed.rb +25 -14
- data/lib/front_matter_parser/parser.rb +82 -0
- data/lib/front_matter_parser/syntax_parser.rb +28 -0
- data/lib/front_matter_parser/syntax_parser/factorizable.rb +30 -0
- data/lib/front_matter_parser/syntax_parser/indentation_comment.rb +49 -0
- data/lib/front_matter_parser/syntax_parser/multi_line_comment.rb +50 -0
- data/lib/front_matter_parser/syntax_parser/single_line_comment.rb +64 -0
- data/lib/front_matter_parser/version.rb +3 -1
- data/spec/fixtures/example +6 -0
- data/spec/front_matter_parser/loader/yaml_spec.rb +24 -0
- data/spec/front_matter_parser/parsed_spec.rb +11 -21
- data/spec/front_matter_parser/parser_spec.rb +111 -0
- data/spec/front_matter_parser/syntax_parser/indentation_comment_spec.rb +166 -0
- data/spec/front_matter_parser/syntax_parser/multi_line_comment_spec.rb +267 -0
- data/spec/front_matter_parser/syntax_parser/single_line_comment_spec.rb +175 -0
- data/spec/front_matter_parser_spec.rb +3 -296
- data/spec/spec_helper.rb +9 -3
- data/spec/support/matcher.rb +8 -0
- metadata +110 -46
- data/spec/fixtures/example.coffee +0 -4
- data/spec/fixtures/example.erb +0 -6
- data/spec/fixtures/example.foo +0 -0
- data/spec/fixtures/example.haml +0 -5
- data/spec/fixtures/example.liquid +0 -6
- data/spec/fixtures/example.md +0 -4
- data/spec/fixtures/example.sass +0 -4
- data/spec/fixtures/example.scss +0 -4
- data/spec/fixtures/example.slim +0 -5
- data/spec/support/strings.rb +0 -41
- data/spec/support/syntaxs.rb +0 -14
- 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).
|
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
|