format_engine 0.4.0 → 0.5.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 +4 -4
- data/README.md +1 -1
- data/format_engine.gemspec +2 -0
- data/lib/format_engine/engine.rb +15 -9
- data/lib/format_engine/format_spec/literal.rb +5 -0
- data/lib/format_engine/format_spec/set.rb +5 -1
- data/lib/format_engine/format_spec/variable.rb +0 -8
- data/lib/format_engine/format_spec.rb +4 -17
- data/lib/format_engine/spec_info.rb +61 -46
- data/lib/format_engine/version.rb +1 -1
- data/tests/formatter_engine_tests.rb +1 -9
- data/tests/literal_spec_tests.rb +1 -1
- data/tests/parser_engine_tests.rb +1 -1
- data/tests/scan_tests.rb +118 -14
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e58ab6d2894a40beaf8ca35a5ed4483cc577741a
|
4
|
+
data.tar.gz: 88e61103fdaf4e4dd5e0eec8c871dee94ff54e17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e45c594310117150e99b10b89a2f0ed9b2df80a80b5e0126037a90b62e04abbf9a596e1159328b69f6bf504d284423e16c634ce8c376227a19c2dc1e8a50054
|
7
|
+
data.tar.gz: 5e9fd537fb2ad8e03b3ce6cef6e4b779a809d514fa859c2d038b6b91c6df014b2a138ef52087ece7309d7303f19b731629826c8335f64b5032bb49dc67bd2322
|
data/README.md
CHANGED
@@ -181,7 +181,7 @@ most welcomed.
|
|
181
181
|
|
182
182
|
#### Plan A
|
183
183
|
|
184
|
-
1. Fork it ( https://github.com/
|
184
|
+
1. Fork it ( https://github.com/PeterCamilleri/format_engine/fork )
|
185
185
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
186
186
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
187
187
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/format_engine.gemspec
CHANGED
@@ -19,6 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
+
spec.required_ruby_version = '>= 1.9.3'
|
23
|
+
|
22
24
|
spec.add_development_dependency "bundler", "~> 1.7"
|
23
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
26
|
spec.add_development_dependency 'minitest', "~> 5.5.1"
|
data/lib/format_engine/engine.rb
CHANGED
@@ -31,10 +31,10 @@ module FormatEngine
|
|
31
31
|
#* src - The source object being formatted.
|
32
32
|
#* format_spec_str - The format specification string.
|
33
33
|
def do_format(src, format_spec_str)
|
34
|
-
spec_info = SpecInfo.new(src, "",
|
34
|
+
spec_info = SpecInfo.new(src, "", self)
|
35
35
|
|
36
|
-
due_process(spec_info, format_spec_str) do |
|
37
|
-
|
36
|
+
due_process(spec_info, format_spec_str) do |format|
|
37
|
+
spec_info.do_format(format)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -44,23 +44,29 @@ module FormatEngine
|
|
44
44
|
#* dst - The class of the object being created.
|
45
45
|
#* parse_spec_str - The format specification string.
|
46
46
|
def do_parse(src, dst, parse_spec_str)
|
47
|
-
spec_info = SpecInfo.new(src, dst,
|
47
|
+
spec_info = SpecInfo.new(src, dst, self)
|
48
48
|
|
49
|
-
due_process(spec_info, parse_spec_str) do |
|
50
|
-
|
49
|
+
due_process(spec_info, parse_spec_str) do |format|
|
50
|
+
spec_info.do_parse(format)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
private
|
55
|
+
|
54
56
|
#Do the actual work of parsing the formatted input.
|
55
57
|
#<br>Parameters
|
56
58
|
#* spec_info - The state of the process.
|
57
59
|
#* spec_str - The format specification string.
|
58
60
|
#* block - A code block performed for each format specification.
|
59
|
-
def due_process(spec_info, spec_str
|
60
|
-
|
61
|
+
def due_process(spec_info, spec_str)
|
62
|
+
format_spec = FormatSpec.get_spec(spec_str).validate(self)
|
61
63
|
|
62
64
|
spec_info.instance_exec(&self[:before])
|
63
|
-
|
65
|
+
|
66
|
+
format_spec.specs.each do |format|
|
67
|
+
break if yield(format) == :break
|
68
|
+
end
|
69
|
+
|
64
70
|
spec_info.instance_exec(&self[:after])
|
65
71
|
|
66
72
|
spec_info.dst
|
@@ -9,6 +9,11 @@ module FormatEngine
|
|
9
9
|
#The regular expression part of this set specification.
|
10
10
|
attr_reader :regex
|
11
11
|
|
12
|
+
#The width parameter. Handled internally so this is always zero.
|
13
|
+
def width
|
14
|
+
0
|
15
|
+
end
|
16
|
+
|
12
17
|
#Setup a variable format specification.
|
13
18
|
def initialize(format)
|
14
19
|
@raw = format
|
@@ -41,7 +46,6 @@ module FormatEngine
|
|
41
46
|
|
42
47
|
#Parse from the input string
|
43
48
|
def do_parse(spec_info)
|
44
|
-
spec_info.fmt = self
|
45
49
|
spec_info.instance_exec(&spec_info.engine[self.format])
|
46
50
|
end
|
47
51
|
|
@@ -67,21 +67,13 @@ module FormatEngine
|
|
67
67
|
has_prec? ? parms[1] : ""
|
68
68
|
end
|
69
69
|
|
70
|
-
#Build up a regular expression for parsing.
|
71
|
-
def regex(base)
|
72
|
-
qualifier = has_width? ? "{1,#{width}}": "+"
|
73
|
-
Regexp.new("#{base}#{qualifier}")
|
74
|
-
end
|
75
|
-
|
76
70
|
#Format onto the output string
|
77
71
|
def do_format(spec_info)
|
78
|
-
spec_info.fmt = self
|
79
72
|
spec_info.instance_exec(&spec_info.engine[self.format])
|
80
73
|
end
|
81
74
|
|
82
75
|
#Parse from the input string
|
83
76
|
def do_parse(spec_info)
|
84
|
-
spec_info.fmt = self
|
85
77
|
spec_info.instance_exec(&spec_info.engine[self.format])
|
86
78
|
end
|
87
79
|
|
@@ -4,21 +4,6 @@ require_relative 'format_spec/literal'
|
|
4
4
|
require_relative 'format_spec/variable'
|
5
5
|
require_relative 'format_spec/set'
|
6
6
|
|
7
|
-
# Format String Specification Syntax (BNF):
|
8
|
-
# spec = (text | item | set)+
|
9
|
-
# item = "%" flag* sign? (parm ("." parm)? )? command
|
10
|
-
# set = "%" flag* parm? "[" chrs "]"
|
11
|
-
# flag = ( "~" | "@" | "#" | "&" | "^" |
|
12
|
-
# "&" | "*" | "-" | "+" | "=" |
|
13
|
-
# "?" | "_" | "<" | ">" | "\\" |
|
14
|
-
# "/" | "." | "," | "|" | "!" )
|
15
|
-
# sign = ("+" | "-")
|
16
|
-
# parm = ("0" .. "9" )+
|
17
|
-
# chrs = (not_any("]") | "\\" "]")+
|
18
|
-
# command = ("a" .. "z" | "A" .. "Z")
|
19
|
-
#
|
20
|
-
# Sample: x = FormatSpec.get_spec "Elapsed = %*3.1H:%02M!"
|
21
|
-
|
22
7
|
module FormatEngine
|
23
8
|
|
24
9
|
#The format string parser.
|
@@ -27,8 +12,9 @@ module FormatEngine
|
|
27
12
|
REGEX = %r{(?<flags> [~@#$^&*\=?_<>\\\/\.,\|!]*){0}
|
28
13
|
(?<parms> [-+]?(\d+(\.\d+)?)?){0}
|
29
14
|
(?<var> %\g<flags>\g<parms>[a-zA-Z]){0}
|
30
|
-
(?<set> %\g<flags>\d*\[([^\]]
|
31
|
-
|
15
|
+
(?<set> %\g<flags>\d*\[([^\]\\]|\\.)+\]){0}
|
16
|
+
(?<per> %%){0}
|
17
|
+
\g<var> | \g<set> | \g<per>
|
32
18
|
}x
|
33
19
|
|
34
20
|
#Don't use new, use get_spec instead.
|
@@ -63,6 +49,7 @@ module FormatEngine
|
|
63
49
|
@specs << case
|
64
50
|
when match_data[:var] then FormatVariable.new(mid)
|
65
51
|
when match_data[:set] then FormatSet.new(mid)
|
52
|
+
when match_data[:per] then FormatLiteral.new("\%")
|
66
53
|
else fail "Impossible case in scan_spec."
|
67
54
|
end
|
68
55
|
fmt_string = match_data.post_match
|
@@ -1,43 +1,26 @@
|
|
1
1
|
module FormatEngine
|
2
2
|
|
3
3
|
#A little package of info about the engine's progress.
|
4
|
-
#In the context of a formatting / parsing block, the
|
5
|
-
#"self" of that block is an instance of SpecInfo.
|
6
|
-
#<br>
|
7
|
-
#<br>The components of that instance Struct are:
|
8
|
-
#<br>
|
9
|
-
#<br>When Formatting:
|
10
|
-
#* src - The object that is the source of the data.
|
11
|
-
#* dst - A string that receives the formatted output.
|
12
|
-
#* fmt - The format specification currently being processed.
|
13
|
-
#* engine - The formatting engine. Mostly for access to the library.
|
14
|
-
#* tmp - A utility hash so that the formatting process can retain state.
|
15
|
-
#<br>Methods
|
16
|
-
#* cat - Append the string that follows to the formatted output.
|
17
|
-
#<br>
|
18
|
-
#<br>When Parsing:
|
19
|
-
#* src - A string that is the source of formatted input.
|
20
|
-
#* dst - The class of the object being created.
|
21
|
-
#* fmt - The parse specification currently being processed.
|
22
|
-
#* engine - The parsing engine. Mostly for access to the library.
|
23
|
-
#* tmp - A utility hash so that the parsing process can retain state.
|
24
|
-
#<br>Methods
|
25
|
-
#* set - Set the return value of the parsing operation to the value that follows.
|
26
|
-
#* parse - Look for the string or regex parm that follows. Return the data found or nil.
|
27
|
-
#* parse! - Like parse but raises an exception (with optional msg) if not found.
|
28
|
-
#* found? - Did the last parse succeed?
|
29
|
-
#* found - The text found by the last parse (or parse!) operation.
|
30
4
|
class SpecInfo
|
31
5
|
|
32
|
-
#
|
33
|
-
attr_reader :src
|
6
|
+
#The source data for formatting, string input for parsing.
|
7
|
+
attr_reader :src
|
34
8
|
|
35
|
-
#
|
36
|
-
|
9
|
+
#The destination of the process.
|
10
|
+
attr_reader :dst
|
11
|
+
|
12
|
+
#The formatting engine.
|
13
|
+
attr_reader :engine
|
14
|
+
|
15
|
+
#A hash for state storage for the formatting/parsing process.
|
16
|
+
attr_reader :tmp
|
17
|
+
|
18
|
+
#The format specifier currently being processed.
|
19
|
+
attr_reader :fmt
|
37
20
|
|
38
21
|
# Set up the spec info.
|
39
|
-
def initialize(src, dst,
|
40
|
-
@src, @dst, @
|
22
|
+
def initialize(src, dst, engine)
|
23
|
+
@src, @dst, @engine, @tmp = src, dst, engine, {}
|
41
24
|
end
|
42
25
|
|
43
26
|
# Concatenate onto the formatted output string.
|
@@ -50,34 +33,66 @@ module FormatEngine
|
|
50
33
|
@dst = obj
|
51
34
|
end
|
52
35
|
|
53
|
-
#
|
54
|
-
def
|
55
|
-
@
|
36
|
+
#Pass the formatting action along to the current format element.
|
37
|
+
def do_format(fmt)
|
38
|
+
(@fmt = fmt).do_format(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
#Pass the parsing action along to the current format element.
|
42
|
+
def do_parse(fmt)
|
43
|
+
(@fmt = fmt).do_parse(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Parse the source string for a target string or regex or return nil.
|
47
|
+
def parse(target)
|
48
|
+
#Handle the width option if specified.
|
49
|
+
if (width = fmt.width) > 0
|
50
|
+
head, tail = src[0...width], src[width..-1] || ""
|
51
|
+
else
|
52
|
+
head, tail = src, ""
|
53
|
+
end
|
56
54
|
|
55
|
+
#Do the parse on the input string.
|
56
|
+
@prematch, @match, @postmatch = head.partition(target)
|
57
|
+
|
58
|
+
#Analyze the results.
|
57
59
|
if found?
|
58
|
-
@src = @
|
59
|
-
@
|
60
|
+
@src = @postmatch + tail
|
61
|
+
@match
|
60
62
|
else
|
61
63
|
nil
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
|
-
# Parse the source string for a string or regex or raise error.
|
66
|
-
def parse!(
|
67
|
-
fail "Parse error: #{msg}" unless parse(
|
68
|
-
|
67
|
+
# Parse the source string for a target string or regex or raise error.
|
68
|
+
def parse!(target, msg = "#{target.inspect} not found")
|
69
|
+
fail "Parse error: #{msg}" unless parse(target)
|
70
|
+
@match
|
71
|
+
end
|
72
|
+
|
73
|
+
#Grab some text
|
74
|
+
def grab
|
75
|
+
if (width = fmt.width) > 0
|
76
|
+
result, @src = src[0...width], src[width..-1] || ""
|
77
|
+
elsif width == -1
|
78
|
+
result, @src = src, ""
|
79
|
+
elsif width < 0
|
80
|
+
result, @src = src[0..width], src[(width+1)..-1] || ""
|
81
|
+
else
|
82
|
+
result, @src = src[0...1], src[1..-1] || ""
|
83
|
+
end
|
84
|
+
|
85
|
+
result
|
69
86
|
end
|
70
87
|
|
71
88
|
# Was the last parse a success?
|
72
89
|
def found?
|
73
|
-
@
|
90
|
+
@prematch.empty? && !@match.empty?
|
74
91
|
end
|
75
92
|
|
76
93
|
# What was found by the last parse?
|
77
94
|
def found
|
78
|
-
@
|
95
|
+
@match
|
79
96
|
end
|
80
|
-
|
81
97
|
end
|
82
|
-
|
83
|
-
end
|
98
|
+
end
|
@@ -24,16 +24,8 @@ class FormatterTester < Minitest::Test
|
|
24
24
|
TestPerson.new("Squidly", "Jones", 21)
|
25
25
|
end
|
26
26
|
|
27
|
-
def make_spec(str)
|
28
|
-
str
|
29
|
-
end
|
30
|
-
|
31
27
|
def make_all(str)
|
32
|
-
[make_formatter, make_person,
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_crazy
|
36
|
-
assert_equal("0.4.0", FormatEngine::VERSION)
|
28
|
+
[make_formatter, make_person, str]
|
37
29
|
end
|
38
30
|
|
39
31
|
def test_that_it_can_format_normally
|
data/tests/literal_spec_tests.rb
CHANGED
@@ -14,7 +14,7 @@ class LiteralSpecTester < Minitest::Test
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_that_it_formats
|
17
|
-
spec_info = FormatEngine::SpecInfo.new(nil, "", nil
|
17
|
+
spec_info = FormatEngine::SpecInfo.new(nil, "", nil)
|
18
18
|
test = FormatEngine::FormatLiteral.new("Test 1 2 3")
|
19
19
|
test.do_format(spec_info)
|
20
20
|
|
data/tests/scan_tests.rb
CHANGED
@@ -10,32 +10,127 @@ class ScanTester < Minitest::Test
|
|
10
10
|
#Track mini-test progress.
|
11
11
|
MinitestVisible.track self, __FILE__
|
12
12
|
|
13
|
+
DECIMAL = /[+-]?\d+/
|
14
|
+
HEX = /[+-]?(0[xX])?\h+/
|
15
|
+
OCTAL = /[+-]?(0[oO])?[0-7]+/
|
16
|
+
BINARY = /[+-]?(0[bB])?[01]+/
|
17
|
+
INTEGER = /[+-]?((0[xX]\h+)|(0[bB][01]+)|(0[oO]?[0-7]*)|([1-9]\d*))/
|
18
|
+
FLOAT = /[+-]?\d+(\.\d+)?([eE][+-]?\d+)?/
|
19
|
+
RATIONAL = /[+-]?\d+\/\d+(r)?/
|
20
|
+
COMPLEX = %r{(?<num> \d+(\.\d+)?([eE][+-]?\d+)?){0}
|
21
|
+
[+-]?\g<num>[+-]\g<num>[ij]
|
22
|
+
}x
|
23
|
+
QUOTED = /("([^\\"]|\\.)*")|('([^\\']|\\.)*')/
|
24
|
+
|
13
25
|
def make_parser
|
14
26
|
FormatEngine::Engine.new(
|
15
|
-
"%
|
16
|
-
|
17
|
-
end,
|
27
|
+
"%b" => lambda {parse(BINARY) ? dst << found.to_i(2) : :break},
|
28
|
+
"%*b" => lambda {parse(BINARY) || :break},
|
18
29
|
|
19
|
-
"
|
20
|
-
|
21
|
-
|
30
|
+
"%c" => lambda {dst << grab},
|
31
|
+
"%*c" => lambda {grab},
|
32
|
+
|
33
|
+
"%d" => lambda {parse(DECIMAL) ? dst << found.to_i : :break},
|
34
|
+
"%*d" => lambda {parse(DECIMAL) || :break},
|
35
|
+
|
36
|
+
"%f" => lambda {parse(FLOAT) ? dst << found.to_f : :break},
|
37
|
+
"%*f" => lambda {parse(FLOAT) || :break},
|
22
38
|
|
23
|
-
"%
|
24
|
-
|
39
|
+
"%i" => lambda {parse(INTEGER) ? dst << found.to_i(0) : :break},
|
40
|
+
"%*i" => lambda {parse(INTEGER) || :break},
|
41
|
+
|
42
|
+
"%j" => lambda {parse(COMPLEX) ? dst << Complex(found) : :break},
|
43
|
+
"%*j" => lambda {parse(COMPLEX) || :break},
|
44
|
+
|
45
|
+
"%o" => lambda {parse(OCTAL) ? dst << found.to_i(8) : :break},
|
46
|
+
"%*o" => lambda {parse(OCTAL) || :break},
|
47
|
+
|
48
|
+
"%q" => lambda do
|
49
|
+
parse(QUOTED) ? dst << found[1..-2].gsub(/\\./) {|seq| seq[-1]} : :break
|
25
50
|
end,
|
51
|
+
"%*q" => lambda {parse(QUOTED) || :break},
|
52
|
+
|
53
|
+
"%r" => lambda {parse(RATIONAL) ? dst << found.to_r : :break},
|
54
|
+
"%*r" => lambda {parse(RATIONAL) || :break},
|
26
55
|
|
27
|
-
"
|
28
|
-
|
29
|
-
|
56
|
+
"%s" => lambda {parse(/\S+/) ? dst << found : :break},
|
57
|
+
"%*s" => lambda {parse(/\S+/) || :break},
|
58
|
+
|
59
|
+
"%u" => lambda {parse(/\d+/) ? dst << found.to_i : :break},
|
60
|
+
"%*u" => lambda {parse(/\d+/) || :break},
|
61
|
+
|
62
|
+
"%x" => lambda {parse(HEX) ? dst << found.to_i(16) : :break},
|
63
|
+
"%*x" => lambda {parse(HEX) || :break},
|
64
|
+
|
65
|
+
"%[" => lambda {parse(fmt.regex) ? dst << found : :break},
|
66
|
+
"%*[" => lambda {parse(fmt.regex) || :break})
|
30
67
|
end
|
31
68
|
|
32
69
|
def test_that_it_can_scan
|
33
70
|
engine = make_parser
|
34
71
|
spec = "%d %2d %4d"
|
35
|
-
result = engine.do_parse("12 34 56", [], spec)
|
72
|
+
result = engine.do_parse("12 34 -56", [], spec)
|
73
|
+
assert_equal([12, 34, -56] , result)
|
36
74
|
|
37
|
-
|
38
|
-
|
75
|
+
spec = "%i %i %i %i %i"
|
76
|
+
result = engine.do_parse("255 0b11111111 0377 0xFF 0 ", [], spec)
|
77
|
+
assert_equal([255, 255, 255, 255, 0] , result)
|
78
|
+
|
79
|
+
spec = "%o %o %o"
|
80
|
+
result = engine.do_parse("7 10 377", [], spec)
|
81
|
+
assert_equal([7, 8, 255] , result)
|
82
|
+
|
83
|
+
spec = "%b %b %b"
|
84
|
+
result = engine.do_parse("10 10011 11110000", [], spec)
|
85
|
+
assert_equal([2, 19, 240] , result)
|
86
|
+
|
87
|
+
spec = "%x %x %x %x %x"
|
88
|
+
result = engine.do_parse("0 F FF FFF FFFF", [], spec)
|
89
|
+
assert_equal([0, 15, 255, 4095, 65535] , result)
|
90
|
+
|
91
|
+
spec = "%s %*s %s"
|
92
|
+
result = engine.do_parse("Hello Silly World", [], spec)
|
93
|
+
assert_equal(["Hello", "World"] , result)
|
94
|
+
|
95
|
+
spec = "%5c %*5c %5c"
|
96
|
+
result = engine.do_parse("Hello Silly World", [], spec)
|
97
|
+
assert_equal(["Hello", "World"] , result)
|
98
|
+
|
99
|
+
spec = "%i %-1c"
|
100
|
+
result = engine.do_parse("42 The secret is X", [], spec)
|
101
|
+
assert_equal([42, "The secret is X"] , result)
|
102
|
+
|
103
|
+
spec = "%i %-2c%c"
|
104
|
+
result = engine.do_parse("42 The secret is X", [], spec)
|
105
|
+
assert_equal([42, "The secret is ", "X"] , result)
|
106
|
+
|
107
|
+
spec = "%i %*-2c%c"
|
108
|
+
result = engine.do_parse("42 The secret is X", [], spec)
|
109
|
+
assert_equal([42, "X"] , result)
|
110
|
+
|
111
|
+
spec = "%f %f %f"
|
112
|
+
result = engine.do_parse("9.99 1.234e56 -1e100", [], spec)
|
113
|
+
assert_equal([9.99, 1.234e56, -1e100] , result)
|
114
|
+
|
115
|
+
spec = "%f%% %f%%"
|
116
|
+
result = engine.do_parse("85% 75%", [], spec)
|
117
|
+
assert_equal([85, 75] , result)
|
118
|
+
|
119
|
+
spec = "%u %u %u"
|
120
|
+
result = engine.do_parse("12 34 -56", [], spec)
|
121
|
+
assert_equal([12, 34] , result)
|
122
|
+
|
123
|
+
spec = "%r %r %r"
|
124
|
+
result = engine.do_parse("1/2 3/4r -5/6", [], spec)
|
125
|
+
assert_equal(['1/2'.to_r, '3/4'.to_r, '-5/6'.to_r] , result)
|
126
|
+
|
127
|
+
spec = "%j %j %j"
|
128
|
+
result = engine.do_parse("1+2i 3+4j -5e10-6.2i", [], spec)
|
129
|
+
assert_equal([Complex('1+2i'), Complex('3+4j'), Complex('-5e10-6.2i')] , result)
|
130
|
+
|
131
|
+
spec = "%q %*q %q %q"
|
132
|
+
result = engine.do_parse("'quote' 'silly' \"un quote\" 'a \\'' ", [], spec)
|
133
|
+
assert_equal(["quote", "un quote", "a '"] , result)
|
39
134
|
end
|
40
135
|
|
41
136
|
def test_missing_data
|
@@ -56,6 +151,15 @@ class ScanTester < Minitest::Test
|
|
56
151
|
assert_equal([12, 34, 56] , result)
|
57
152
|
end
|
58
153
|
|
154
|
+
def test_malformed_data
|
155
|
+
engine = make_parser
|
156
|
+
spec = "%d %d %d"
|
157
|
+
result = engine.do_parse("12 igloo 34 56", [], spec)
|
158
|
+
|
159
|
+
assert_equal(Array, result.class)
|
160
|
+
assert_equal([12] , result)
|
161
|
+
end
|
162
|
+
|
59
163
|
def test_skipped_data
|
60
164
|
engine = make_parser
|
61
165
|
spec = "%d %2d %*d %d"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: format_engine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -132,7 +132,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
132
|
requirements:
|
133
133
|
- - ">="
|
134
134
|
- !ruby/object:Gem::Version
|
135
|
-
version:
|
135
|
+
version: 1.9.3
|
136
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
137
|
requirements:
|
138
138
|
- - ">="
|