metaheader 1.2.1 → 1.3beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|