metaheader 1.2.1 → 1.3beta1
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 +4 -4
- data/lib/metaheader/version.rb +1 -1
- data/lib/metaheader.rb +58 -22
- data/test/test_parser.rb +66 -2
- data/test/test_validator.rb +9 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2785ed7e70b818e49c72e9f8d8dfa868f382936
|
4
|
+
data.tar.gz: 69186b6be145a432dc9dc81efbc1d86f9c6b8c1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cda458f1ad6a0a11c97018655aae2b66656b497316c35826d3f6567eabf7f84482f12a3591f8bd163ce80c40c332db3c211849f57e98afb7d7e8e901305e61b
|
7
|
+
data.tar.gz: 0bfe9167f00907300ceccadcc662287081036e70b251f637209c11048932f10fbe99fe09eaf7852c66a7bb5f67862a86400f72dd5b0f0dbecdb8380f7154aed1
|
data/lib/metaheader/version.rb
CHANGED
data/lib/metaheader.rb
CHANGED
@@ -64,7 +64,6 @@ class MetaHeader
|
|
64
64
|
@data = {}
|
65
65
|
|
66
66
|
@last_key = nil
|
67
|
-
@last_prefix = String.new
|
68
67
|
|
69
68
|
input = input.encode universal_newline: true
|
70
69
|
input.each_line {|line|
|
@@ -120,7 +119,7 @@ class MetaHeader
|
|
120
119
|
# @param tag [Symbol] the tag to lookup
|
121
120
|
# @return [Boolean]
|
122
121
|
def has?(tag)
|
123
|
-
@data.has_key? tag
|
122
|
+
@data.has_key? tag
|
124
123
|
end
|
125
124
|
|
126
125
|
# Removes a given tag from the list.
|
@@ -158,8 +157,8 @@ class MetaHeader
|
|
158
157
|
errors = Array.new
|
159
158
|
|
160
159
|
if @strict
|
161
|
-
@data.
|
162
|
-
errors << "unknown tag '%s'" %
|
160
|
+
@data.each {|key, tag|
|
161
|
+
errors << "unknown tag '%s'" % tag.name unless rules.has_key? key
|
163
162
|
}
|
164
163
|
end
|
165
164
|
|
@@ -172,6 +171,28 @@ class MetaHeader
|
|
172
171
|
errors unless errors.empty?
|
173
172
|
end
|
174
173
|
|
174
|
+
# Rename one or more tags.
|
175
|
+
# @param old [Symbol, Hash]
|
176
|
+
# @param new [Symbol]
|
177
|
+
# @example
|
178
|
+
# mh.alias :old, :new
|
179
|
+
# mh.alias :old1, :old2, :new
|
180
|
+
# mh.alias [:old1, :old2], :new
|
181
|
+
# mh.alias old1: :new1, old2: :new2
|
182
|
+
def alias(*args)
|
183
|
+
raise ArgumentError, 'wrong number of arguments' unless args.size.between? 1, 2
|
184
|
+
|
185
|
+
tags, new = args
|
186
|
+
|
187
|
+
if args.size == 1
|
188
|
+
tags.each {|k, v| self.alias k, v }
|
189
|
+
else
|
190
|
+
Array(tags).each {|old|
|
191
|
+
@data[new] = delete old if has? old
|
192
|
+
}
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
175
196
|
private
|
176
197
|
# @api private
|
177
198
|
Tag = Struct.new :name, :value
|
@@ -182,29 +203,19 @@ private
|
|
182
203
|
\Z/x.freeze
|
183
204
|
|
184
205
|
def parse(line)
|
185
|
-
line.
|
186
|
-
|
187
|
-
# multiline value must have the same prefix
|
188
|
-
if @last_key && line.index(@last_prefix) == 0
|
189
|
-
# remove the line prefix
|
190
|
-
mline = line[@last_prefix.size..-1]
|
191
|
-
stripped = mline.strip
|
192
|
-
|
193
|
-
indent_level = mline.index stripped
|
194
|
-
|
195
|
-
if indent_level > 0
|
196
|
-
tag = @data[@last_key]
|
197
|
-
|
198
|
-
tag.value = @raw_value.to_s unless tag.value.is_a? String
|
199
|
-
tag.value += "\n" unless tag.value.empty?
|
200
|
-
tag.value += stripped
|
206
|
+
line.chomp!
|
201
207
|
|
208
|
+
# multiline value must have the same line prefix as the key
|
209
|
+
if @last_key && line.start_with?(@last_prefix.rstrip)
|
210
|
+
if append line
|
202
211
|
return
|
203
212
|
else
|
204
213
|
@last_key = nil
|
205
214
|
end
|
206
215
|
end
|
207
216
|
|
217
|
+
line.rstrip!
|
218
|
+
|
208
219
|
return unless match = REGEX.match(line)
|
209
220
|
|
210
221
|
# single line
|
@@ -216,16 +227,41 @@ private
|
|
216
227
|
|
217
228
|
@last_key = key.to_sym
|
218
229
|
@data[@last_key] = Tag.new match[:key].freeze, value
|
230
|
+
@line_breaks = 0
|
219
231
|
end
|
220
232
|
|
221
|
-
def
|
222
|
-
|
233
|
+
def append(line)
|
234
|
+
if line.rstrip == @last_prefix.rstrip
|
235
|
+
@line_breaks += 1
|
236
|
+
return true # add the line break later
|
237
|
+
elsif line.start_with? @last_prefix
|
238
|
+
mline = line[@last_prefix.size..-1]
|
239
|
+
stripped = mline.lstrip
|
240
|
+
indent_level = mline.index stripped
|
241
|
+
return if indent_level < 1
|
242
|
+
else
|
243
|
+
return
|
244
|
+
end
|
245
|
+
|
246
|
+
tag = @data[@last_key]
|
247
|
+
tag.value = @raw_value.to_s unless tag.value.is_a? String
|
223
248
|
|
249
|
+
@line_breaks += 1 unless tag.value.empty?
|
250
|
+
tag.value += "\n" * @line_breaks
|
251
|
+
@line_breaks = 0
|
252
|
+
|
253
|
+
tag.value += stripped
|
254
|
+
stripped
|
255
|
+
end
|
256
|
+
|
257
|
+
def parse_value(key, value)
|
224
258
|
case value
|
225
259
|
when 'true'
|
226
260
|
value = true
|
227
261
|
when 'false'
|
228
262
|
value = false
|
263
|
+
when nil
|
264
|
+
value = true
|
229
265
|
when String
|
230
266
|
value = nil if value.empty?
|
231
267
|
end
|
data/test/test_parser.rb
CHANGED
@@ -109,6 +109,11 @@ class TestParser < MiniTest::Test
|
|
109
109
|
assert_equal 2, mh.size
|
110
110
|
end
|
111
111
|
|
112
|
+
def test_trailing_whitespace
|
113
|
+
mh = MetaHeader.new '@hello world '
|
114
|
+
assert_equal 'world', mh[:hello]
|
115
|
+
end
|
116
|
+
|
112
117
|
def test_multiline
|
113
118
|
mh = MetaHeader.new <<-IN
|
114
119
|
@test Lorem
|
@@ -137,8 +142,8 @@ class TestParser < MiniTest::Test
|
|
137
142
|
test\x20
|
138
143
|
IN
|
139
144
|
|
140
|
-
assert_equal 'test', mh[:hello]
|
141
|
-
assert_equal 'test', mh[:world]
|
145
|
+
assert_equal 'test ', mh[:hello]
|
146
|
+
assert_equal 'test ', mh[:world]
|
142
147
|
end
|
143
148
|
|
144
149
|
def test_multiline_prefix
|
@@ -182,6 +187,32 @@ class TestParser < MiniTest::Test
|
|
182
187
|
assert_equal "true\ntest", mh[:test]
|
183
188
|
end
|
184
189
|
|
190
|
+
def test_multiline_empty_line
|
191
|
+
mh = MetaHeader.new <<-IN
|
192
|
+
--@test
|
193
|
+
-- Hello
|
194
|
+
--
|
195
|
+
-- World
|
196
|
+
--
|
197
|
+
--@chunky
|
198
|
+
-- bacon
|
199
|
+
IN
|
200
|
+
|
201
|
+
assert_equal "Hello\n\nWorld", mh[:test]
|
202
|
+
assert_equal 'bacon', mh[:chunky] # no leading newline
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_multiline_empty_line_space_prefix
|
206
|
+
mh = MetaHeader.new <<-IN
|
207
|
+
-- @test
|
208
|
+
-- Hello
|
209
|
+
--
|
210
|
+
-- World
|
211
|
+
IN
|
212
|
+
|
213
|
+
assert_equal "Hello\n\nWorld", mh[:test]
|
214
|
+
end
|
215
|
+
|
185
216
|
def test_read_file
|
186
217
|
path = File.expand_path '../input/basic_tag', __FILE__
|
187
218
|
mh = MetaHeader.from_file path
|
@@ -271,5 +302,38 @@ class TestParser < MiniTest::Test
|
|
271
302
|
def test_construct_from_instance
|
272
303
|
mh = MetaHeader.new '@hello world'
|
273
304
|
assert_same mh, MetaHeader.parse(mh)
|
305
|
+
assert_equal mh.to_h, MetaHeader.parse('@hello world').to_h
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_alias
|
309
|
+
mh = MetaHeader.new '@a 1'
|
310
|
+
mh.alias :a, :b
|
311
|
+
refute mh.has?(:a)
|
312
|
+
assert_equal '1', mh[:b]
|
313
|
+
|
314
|
+
mh[:d] = '2'
|
315
|
+
mh.alias :c, :d
|
316
|
+
refute mh.has?(:c)
|
317
|
+
assert_equal '2', mh[:d]
|
318
|
+
end
|
319
|
+
|
320
|
+
def test_alias_hash
|
321
|
+
mh = MetaHeader.new "@a 1\n@b 2"
|
322
|
+
mh.alias a: :c, b: :d
|
323
|
+
assert_equal '1', mh[:c]
|
324
|
+
assert_equal '2', mh[:d]
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_alias_array
|
328
|
+
mh = MetaHeader.new "@a 1\n@b 2"
|
329
|
+
mh.alias [:a, :b, :c], :d
|
330
|
+
assert [:a, :b, :c].none? {|t| mh.has? t }
|
331
|
+
assert_equal '2', mh[:d]
|
332
|
+
end
|
333
|
+
|
334
|
+
def test_alias_invalid_args
|
335
|
+
mh = MetaHeader.new "@a 1\n@b 2"
|
336
|
+
assert_raises(ArgumentError) { mh.alias }
|
337
|
+
assert_raises(ArgumentError) { mh.alias 1, 2, 3 }
|
274
338
|
end
|
275
339
|
end
|
data/test/test_validator.rb
CHANGED
@@ -6,11 +6,11 @@ class TestValidator < MiniTest::Test
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def test_unknown_strict
|
9
|
-
mh = MetaHeader.new "@hello\n@
|
9
|
+
mh = MetaHeader.new "@hello\n@WORLD"
|
10
10
|
mh.strict = true
|
11
11
|
|
12
12
|
actual = mh.validate Hash.new
|
13
|
-
assert_equal ["unknown tag 'hello'", "unknown tag '
|
13
|
+
assert_equal ["unknown tag 'hello'", "unknown tag 'WORLD'"], actual
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_unknown_tolerant
|
@@ -107,4 +107,11 @@ class TestValidator < MiniTest::Test
|
|
107
107
|
hello: MetaHeader::BOOLEAN
|
108
108
|
assert_equal ["tag 'hello' cannot have a value"], actual
|
109
109
|
end
|
110
|
+
|
111
|
+
def test_alias
|
112
|
+
mh = MetaHeader.new "@a"
|
113
|
+
mh.alias :a, :b
|
114
|
+
assert_equal ["missing value for tag 'a'"],
|
115
|
+
mh.validate(b: [MetaHeader::REQUIRED, MetaHeader::VALUE])
|
116
|
+
end
|
110
117
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metaheader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- cfillion
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -118,9 +118,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
118
|
version: '2.3'
|
119
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
120
|
requirements:
|
121
|
-
- - "
|
121
|
+
- - ">"
|
122
122
|
- !ruby/object:Gem::Version
|
123
|
-
version:
|
123
|
+
version: 1.3.1
|
124
124
|
requirements: []
|
125
125
|
rubyforge_project:
|
126
126
|
rubygems_version: 2.5.1
|