literal_parser 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.
data/README.markdown ADDED
@@ -0,0 +1,53 @@
1
+ README
2
+ ======
3
+
4
+
5
+ Summary
6
+ -------
7
+ Parse Strings containing ruby literals and return a proper ruby object.
8
+
9
+
10
+ Features
11
+ --------
12
+
13
+ * Recognizes about all Ruby literals: nil, true, false, Symbols, Integers, Floats, Hashes,
14
+ Arrays
15
+ * Additionally parses Constants, Dates and Times
16
+ * Very easy to use
17
+
18
+
19
+ Installation
20
+ ------------
21
+ `gem install literal_parser`
22
+
23
+
24
+ Usage
25
+ -----
26
+
27
+ A couple of examples:
28
+
29
+ LiteralParser.parse("nil") # => nil
30
+ LiteralParser.parse(":foo") # => :foo
31
+ LiteralParser.parse("123") # => 123
32
+ LiteralParser.parse("1.5") # => 1.5
33
+ LiteralParser.parse("1.5", use_big_decimal: true) # => #<BigDecimal:…,'0.15E1',18(18)>
34
+ LiteralParser.parse("[1, 2, 3]") # => [1, 2, 3]
35
+ LiteralParser.parse("{:a => 1, :b => 2}") # => {:a => 1, :b => 2}
36
+
37
+
38
+
39
+
40
+ Links
41
+ -----
42
+
43
+ * [Online API Documentation](http://rdoc.info/github/apeiros/literal_parser/)
44
+ * [Public Repository](https://github.com/apeiros/literal_parser)
45
+ * [Bug Reporting](https://github.com/apeiros/literal_parser/issues)
46
+ * [RubyGems Site](https://rubygems.org/gems/literal_parser)
47
+
48
+
49
+ License
50
+ -------
51
+
52
+ You can use this code under the {file:LICENSE.txt BSD-2-Clause License}, free of charge.
53
+ If you need a different license, please ask the author.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../rake/lib', __FILE__))
2
+ Dir.glob(File.expand_path('../rake/tasks/**/*.{rake,task,rb}', __FILE__)) do |task_file|
3
+ begin
4
+ import task_file
5
+ rescue LoadError => e
6
+ warn "Failed to load task file #{task_file}"
7
+ warn " #{e.class} #{e.message}"
8
+ warn " #{e.backtrace.first}"
9
+ end
10
+ end
@@ -0,0 +1,323 @@
1
+ # encoding: utf-8
2
+
3
+
4
+
5
+ require 'literal_parser/version'
6
+ require 'strscan'
7
+ require 'bigdecimal'
8
+ require 'date'
9
+
10
+
11
+
12
+ # LiteralParser
13
+ #
14
+ # Parse Strings containing ruby literals.
15
+ #
16
+ # @example
17
+ # LiteralParser.parse("nil") # => nil
18
+ # LiteralParser.parse(":foo") # => :foo
19
+ # LiteralParser.parse("123") # => 123
20
+ # LiteralParser.parse("1.5") # => 1.5
21
+ # LiteralParser.parse("1.5", use_big_decimal: true) # => #<BigDecimal:…,'0.15E1',18(18)>
22
+ # LiteralParser.parse("[1, 2, 3]") # => [1, 2, 3]
23
+ # LiteralParser.parse("{:a => 1, :b => 2}") # => {:a => 1, :b => 2}
24
+ #
25
+ # LiteralParser recognizes constants and the following literals:
26
+ #
27
+ # nil # nil
28
+ # true # true
29
+ # false # false
30
+ # -123 # Fixnum/Bignum (decimal)
31
+ # 0b1011 # Fixnum/Bignum (binary)
32
+ # 0755 # Fixnum/Bignum (octal)
33
+ # 0xff # Fixnum/Bignum (hexadecimal)
34
+ # 120.30 # Float (optional: BigDecimal)
35
+ # 1e0 # Float
36
+ # "foo" # String, no interpolation, but \t etc. work
37
+ # 'foo' # String, only \\ and \' are escaped
38
+ # /foo/ # Regexp
39
+ # :foo # Symbol
40
+ # :"foo" # Symbol
41
+ # 2012-05-20 # Date
42
+ # 2012-05-20T18:29:52 # DateTime
43
+ # [Any, Literals, Here] # Array
44
+ # {Any => Literals} # Hash
45
+ #
46
+ #
47
+ # @note Limitations
48
+ #
49
+ # * LiteralParser does not support ruby 1.9's `{key: value}` syntax.
50
+ # * LiteralParser does not currently support all of rubys escape sequences in strings
51
+ # and symbols, e.g. "\C-…" type sequences don't work.
52
+ # * Trailing commas in Array and Hash are not supported.
53
+ #
54
+ # @note BigDecimals
55
+ #
56
+ # You can instruct LiteralParser to parse "12.5" as a bigdecimal and use "12.5e" to have
57
+ # it parsed as float (short for "12.5e0", equivalent to "1.25e1")
58
+ #
59
+ # @note Date & Time
60
+ #
61
+ # LiteralParser supports a subset of ISO-8601 for Date and Time which are not actual
62
+ # valid ruby literals. The form YYYY-MM-DD (e.g. 2012-05-20) is translated to a Date
63
+ # object, and YYYY-MM-DD"T"HH:MM:SS (e.g. 2012-05-20T18:29:52) is translated to a
64
+ # Time object.
65
+ #
66
+ class LiteralParser
67
+
68
+ # Raised when a String could not be parsed
69
+ class SyntaxError < StandardError; end
70
+
71
+ # @private
72
+ # All the expressions used to parse the literals
73
+ module Expressions
74
+
75
+ RArrayBegin = /\[/ # Match begin of an array
76
+
77
+ RArrayVoid = /\s*/ # Match whitespace between elements in an array
78
+
79
+ RArraySeparator = /#{RArrayVoid},#{RArrayVoid}/ # Match the separator of array elements
80
+
81
+ RArrayEnd = /\]/ # Match end of an array
82
+
83
+ RHashBegin = /\{/ # Match begin of a hash
84
+
85
+ RHashVoid = /\s*/ # Match whitespace between elements in a hash
86
+
87
+ RHashSeparator = /#{RHashVoid},#{RHashVoid}/ # Match the separator of hash key/value pairs
88
+
89
+ RHashArrow = /#{RHashVoid}=>#{RHashVoid}/ # Match the separator between a key and a value in a hash
90
+
91
+ RHashEnd = /\}/ # Match end of a hash
92
+
93
+ RConstant = /[A-Z]\w*(?:::[A-Z]\w*)*/ # Match constant names (with nesting)
94
+
95
+ RNil = /nil/ # Match nil
96
+
97
+ RFalse = /false/ # Match false
98
+
99
+ RTrue = /true/ # Match true
100
+
101
+ RInteger = /[+-]?\d[\d_]*/ # Match an Integer in decimal notation
102
+
103
+ RBinaryInteger = /[+-]?0b[01][01_]*/ # Match an Integer in binary notation
104
+
105
+ RHexInteger = /[+-]?0x[A-Fa-f\d][A-Fa-f\d_]*/ # Match an Integer in hexadecimal notation
106
+
107
+ ROctalInteger = /[+-]?0[0-7][0-7'_,]*/ # Match an Integer in octal notation
108
+
109
+ RBigDecimal = /#{RInteger}\.\d+/ # Match a decimal number (Float or BigDecimal)
110
+
111
+ RFloat = /#{RBigDecimal}(?:f|e#{RInteger})/ # Match a decimal number in scientific notation
112
+
113
+ RSString = /'(?:[^\\']+|\\.)*'/ # Match a single quoted string
114
+
115
+ RDString = /"(?:[^\\"]+|\\.)*"/ # Match a double quoted string
116
+
117
+ RRegexp = %r{/((?:[^\\/]+|\\.)*)/([imxnNeEsSuU]*)} # Match a regular expression
118
+
119
+ RSymbol = /:\w+|:#{RSString}|:#{RDString}/ # Match a symbol
120
+
121
+ RDate = /(\d{4})-(\d{2})-(\d{2})/ # Match a date
122
+
123
+ RTimeZone = /(Z|[A-Z]{3,4}|[+-]\d{4})/ # Match a timezone
124
+
125
+ RTime = /(\d{2}):(\d{2}):(\d{2})(?:RTimeZone)?/ # Match a time (without date)
126
+
127
+ RDateTime = /#{RDate}T#{RTime}/ # Match a datetime
128
+
129
+ # Map escape sequences in double quoted strings
130
+ DStringEscapes = {
131
+ '\\\\' => "\\",
132
+ "\\'" => "'",
133
+ '\\"' => '"',
134
+ '\t' => "\t",
135
+ '\f' => "\f",
136
+ '\r' => "\r",
137
+ '\n' => "\n",
138
+ }
139
+ 256.times do |i|
140
+ DStringEscapes["\\%o" % i] = i.chr
141
+ DStringEscapes["\\%03o" % i] = i.chr
142
+ DStringEscapes["\\x%02x" % i] = i.chr
143
+ DStringEscapes["\\x%02X" % i] = i.chr
144
+ end
145
+ end
146
+ include Expressions
147
+
148
+ # Parse a String, returning the object which it contains.
149
+ #
150
+ # @example
151
+ # LiteralParser.parse(":foo") # => :foo
152
+ #
153
+ # @param [String] string
154
+ # The string which should be parsed
155
+ # @param [nil, Hash] options
156
+ # An options-hash
157
+ #
158
+ # @option options [Boolean] :use_big_decimal
159
+ # Whether to use BigDecimal instead of Float for objects like "1.23".
160
+ # Defaults to false.
161
+ # @option options [Boolean] :constant_base
162
+ # Determines from what constant other constants are searched.
163
+ # Defaults to Object (nil is treated as Object too, Object is the toplevel-namespace).
164
+ #
165
+ # @return [Object] The object in the string.
166
+ #
167
+ # @raise [LiteralParser::SyntaxError]
168
+ # If the String does not contain exactly one valid literal, a SyntaxError is raised.
169
+ def self.parse(string, options=nil)
170
+ parser = new(string, options)
171
+ value = parser.scan_value
172
+ raise SyntaxError, "Unexpected superfluous data: #{parser.rest.inspect}" unless parser.end_of_string?
173
+
174
+ value
175
+ end
176
+
177
+ # @return [Module, nil]
178
+ # Where to lookup constants. Nil is toplevel (equivalent to Object).
179
+ attr_reader :constant_base
180
+
181
+ # @return [Boolean]
182
+ # True if "1.25" should be parsed into a big-decimal, false if it should be parsed as
183
+ # Float.
184
+ attr_reader :use_big_decimal
185
+
186
+ #
187
+ # Parse a String, returning the object which it contains.
188
+ #
189
+ # @param [String] string
190
+ # The string which should be parsed
191
+ # @param [nil, Hash] options
192
+ # An options-hash
193
+ #
194
+ # @option options [Boolean] :use_big_decimal
195
+ # Whether to use BigDecimal instead of Float for objects like "1.23".
196
+ # Defaults to false.
197
+ # @option options [Boolean] :constant_base
198
+ # Determines from what constant other constants are searched.
199
+ # Defaults to Object (nil is treated as Object too, Object is the toplevel-namespace).
200
+ def initialize(string, options=nil)
201
+ options = options ? options.dup : {}
202
+ @constant_base = options[:constant_base] # nil means toplevel
203
+ @use_big_decimal = options.delete(:use_big_decimal) { false }
204
+ @string = string
205
+ @scanner = StringScanner.new(string)
206
+ end
207
+
208
+ # @return [Integer] The position of the scanner in the string
209
+ def position
210
+ @scanner.pos
211
+ end
212
+
213
+ # Moves the scanners position to the given character-index.
214
+ #
215
+ # @param [Integer] value
216
+ # The new position of the scanner
217
+ def position=(value)
218
+ @scanner.pos = value
219
+ end
220
+
221
+ # @return [Boolean] Whether the scanner reached the end of the string.
222
+ def end_of_string?
223
+ @scanner.eos?
224
+ end
225
+
226
+ # @return [String] The currently unprocessed rest of the string.
227
+ def rest
228
+ @scanner.rest
229
+ end
230
+
231
+ # Scans the string for a single value and advances the parsers position
232
+ #
233
+ # @return [Object] the scanned value
234
+ #
235
+ # @raise [LiteralParser::SyntaxError]
236
+ # When no valid ruby object could be scanned at the given position, a
237
+ # LiteralParser::SyntaxError is raised.
238
+ def scan_value
239
+ case
240
+ when @scanner.scan(RArrayBegin) then
241
+ value = []
242
+ @scanner.scan(RArrayVoid)
243
+ if @scanner.scan(RArrayEnd)
244
+ value
245
+ else
246
+ value << scan_value
247
+ while @scanner.scan(RArraySeparator)
248
+ value << scan_value
249
+ end
250
+ raise SyntaxError, "Expected ]" unless @scanner.scan(RArrayVoid) && @scanner.scan(RArrayEnd)
251
+
252
+ value
253
+ end
254
+ when @scanner.scan(RHashBegin) then
255
+ value = {}
256
+ @scanner.scan(RHashVoid)
257
+ if @scanner.scan(RHashEnd)
258
+ value
259
+ else
260
+ key = scan_value
261
+ raise SyntaxError, "Expected =>" unless @scanner.scan(RHashArrow)
262
+ val = scan_value
263
+ value[key] = val
264
+ while @scanner.scan(RHashSeparator)
265
+ key = scan_value
266
+ raise SyntaxError, "Expected =>" unless @scanner.scan(RHashArrow)
267
+ val = scan_value
268
+ value[key] = val
269
+ end
270
+ raise SyntaxError, "Expected }" unless @scanner.scan(RHashVoid) && @scanner.scan(RHashEnd)
271
+
272
+ value
273
+ end
274
+ when @scanner.scan(RConstant) then eval("#{@constant_base}::#{@scanner[0]}") # yes, I know it's evil, but it's sane due to the regex, also it's less annoying than deep_const_get
275
+ when @scanner.scan(RNil) then nil
276
+ when @scanner.scan(RTrue) then true
277
+ when @scanner.scan(RFalse) then false
278
+ when @scanner.scan(RDateTime) then
279
+ Time.mktime(@scanner[1], @scanner[2], @scanner[3], @scanner[4], @scanner[5], @scanner[6])
280
+ when @scanner.scan(RDate) then
281
+ date = @scanner[1].to_i, @scanner[2].to_i, @scanner[3].to_i
282
+ Date.civil(*date)
283
+ when @scanner.scan(RTime) then
284
+ now = Time.now
285
+ Time.mktime(now.year, now.month, now.day, @scanner[1].to_i, @scanner[2].to_i, @scanner[3].to_i)
286
+ when @scanner.scan(RFloat) then Float(@scanner.matched.delete('^0-9.e-'))
287
+ when @scanner.scan(RBigDecimal) then
288
+ data = @scanner.matched.delete('^0-9.-')
289
+ @use_big_decimal ? BigDecimal(data) : Float(data)
290
+ when @scanner.scan(ROctalInteger) then Integer(@scanner.matched.delete('^0-9-'))
291
+ when @scanner.scan(RHexInteger) then Integer(@scanner.matched.delete('^xX0-9A-Fa-f-'))
292
+ when @scanner.scan(RBinaryInteger) then Integer(@scanner.matched.delete('^bB01-'))
293
+ when @scanner.scan(RInteger) then @scanner.matched.delete('^0-9-').to_i
294
+ when @scanner.scan(RRegexp) then
295
+ source = @scanner[1]
296
+ flags = 0
297
+ lang = nil
298
+ if @scanner[2] then
299
+ flags |= Regexp::IGNORECASE if @scanner[2].include?('i')
300
+ flags |= Regexp::EXTENDED if @scanner[2].include?('m')
301
+ flags |= Regexp::MULTILINE if @scanner[2].include?('x')
302
+ lang = @scanner[2].delete('^nNeEsSuU')[-1,1]
303
+ end
304
+ Regexp.new(source, flags, lang)
305
+ when @scanner.scan(RSymbol) then
306
+ case @scanner.matched[1,1]
307
+ when '"'
308
+ @scanner.matched[2..-2].gsub(/\\(?:[0-3]?\d\d?|x[A-Fa-f\d]{2}|.)/) { |m|
309
+ DStringEscapes[m]
310
+ }.to_sym
311
+ when "'"
312
+ @scanner.matched[2..-2].gsub(/\\'/, "'").gsub(/\\\\/, "\\").to_sym
313
+ else
314
+ @scanner.matched[1..-1].to_sym
315
+ end
316
+ when @scanner.scan(RSString) then
317
+ @scanner.matched[1..-2].gsub(/\\'/, "'").gsub(/\\\\/, "\\")
318
+ when @scanner.scan(RDString) then
319
+ @scanner.matched[1..-2].gsub(/\\(?:[0-3]?\d\d?|x[A-Fa-f\d]{2}|.)/) { |m| DStringEscapes[m] }
320
+ else raise SyntaxError, "Unrecognized pattern: #{@scanner.rest.inspect}"
321
+ end
322
+ end
323
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'rubygems/version' # newer rubygems use this
5
+ rescue LoadError
6
+ require 'gem/version' # older rubygems use this
7
+ end
8
+
9
+ class LiteralParser
10
+
11
+ # The version of the LiteralParser library
12
+ Version = Gem::Version.new("1.0.0")
13
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "literal_parser"
5
+ s.version = "1.0.0"
6
+ s.authors = "Stefan Rusterholz"
7
+ s.email = "stefan.rusterholz@gmail.com"
8
+ s.homepage = "https://github.com/apeiros/literal_parser"
9
+
10
+ s.description = <<-DESCRIPTION.gsub(/^ /, '').chomp
11
+ Parse Strings containing ruby literals and return a proper ruby object.
12
+ DESCRIPTION
13
+ s.summary = <<-SUMMARY.gsub(/^ /, '').chomp
14
+ Parse Strings containing ruby literals and return a proper ruby object.
15
+ SUMMARY
16
+
17
+ s.files =
18
+ Dir['bin/**/*'] +
19
+ Dir['lib/**/*'] +
20
+ Dir['rake/**/*'] +
21
+ Dir['test/**/*'] +
22
+ Dir['*.gemspec'] +
23
+ %w[
24
+ Rakefile
25
+ README.markdown
26
+ ]
27
+
28
+ if File.directory?('bin') then
29
+ executables = Dir.chdir('bin') { Dir.glob('**/*').select { |f| File.executable?(f) } }
30
+ s.executables = executables unless executables.empty?
31
+ end
32
+
33
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1")
34
+ s.rubygems_version = "1.3.1"
35
+ s.specification_version = 3
36
+ end
@@ -0,0 +1,31 @@
1
+ require 'stringio'
2
+
3
+ module TestSuite
4
+ attr_accessor :name
5
+ end
6
+
7
+ module Kernel
8
+ def suite(name, &block)
9
+ klass = Class.new(Test::Unit::TestCase, &block)
10
+ klass.extend TestSuite
11
+ klass.name = "Suite #{name}"
12
+
13
+ klass
14
+ end
15
+ module_function :suite
16
+ end
17
+
18
+ class Test::Unit::TestCase
19
+ def self.test(desc, &impl)
20
+ define_method("test #{desc}", &impl)
21
+ end
22
+
23
+ def capture_stdout
24
+ captured = StringIO.new
25
+ $stdout = captured
26
+ yield
27
+ captured.string
28
+ ensure
29
+ $stdout = STDOUT
30
+ end
31
+ end
data/test/runner.rb ADDED
@@ -0,0 +1,20 @@
1
+ # run with `ruby test/runner.rb`
2
+ # if you only want to run a single test-file: `ruby test/runner.rb testfile.rb`
3
+
4
+ $LOAD_PATH << File.expand_path('../../lib', __FILE__)
5
+ $LOAD_PATH << File.expand_path('../../test/lib', __FILE__)
6
+ TEST_DIR = File.expand_path('../../test', __FILE__)
7
+
8
+ require 'test/unit'
9
+ require 'helper'
10
+
11
+ if ENV['COVERAGE']
12
+ require 'simplecov'
13
+ SimpleCov.start
14
+ end
15
+
16
+ units = ARGV.empty? ? Dir["#{TEST_DIR}/unit/**/*.rb"] : ARGV
17
+
18
+ units.each do |unit|
19
+ load unit
20
+ end
@@ -0,0 +1,89 @@
1
+ # encoding: utf-8
2
+
3
+ require 'literal_parser'
4
+
5
+ suite "LiteralParser" do
6
+ test "Parse nil" do
7
+ assert_equal nil, LiteralParser.parse('nil')
8
+ end
9
+ test "Parse true" do
10
+ assert_equal true, LiteralParser.parse('true')
11
+ end
12
+ test "Parse false" do
13
+ assert_equal false, LiteralParser.parse('false')
14
+ end
15
+ test "Parse Integers" do
16
+ assert_equal 123, LiteralParser.parse('123')
17
+ assert_equal -123, LiteralParser.parse('-123')
18
+ assert_equal 1_234_567, LiteralParser.parse('1_234_567')
19
+ assert_equal 0b1011, LiteralParser.parse('0b1011')
20
+ assert_equal 0xe3, LiteralParser.parse('0xe3')
21
+ end
22
+ test "Parse Floats" do
23
+ assert_equal 12.37, LiteralParser.parse('12.37')
24
+ assert_equal -31.59, LiteralParser.parse('-31.59')
25
+ assert_equal 1.2e5, LiteralParser.parse('1.2e5')
26
+ assert_equal 1.2e-5, LiteralParser.parse('1.2e-5')
27
+ assert_equal -1.2e5, LiteralParser.parse('-1.2e5')
28
+ assert_equal -1.2e-5, LiteralParser.parse('-1.2e-5')
29
+ end
30
+ test "Parse BigDecimals" do
31
+ assert_equal BigDecimal("12.37"), LiteralParser.parse('12.37', use_big_decimal: true)
32
+ end
33
+ test "Parse Symbols" do
34
+ assert_equal :simple_symbol, LiteralParser.parse(':simple_symbol')
35
+ assert_equal :"double quoted symbol", LiteralParser.parse(':"double quoted symbol"')
36
+ assert_equal :'single quoted symbol', LiteralParser.parse(":'single quoted symbol'")
37
+ end
38
+ test "Parse Strings" do
39
+ assert_equal 'Single Quoted String', LiteralParser.parse(%q{'Single Quoted String'})
40
+ assert_equal "Double Quoted String", LiteralParser.parse(%q{"Double Quoted String"})
41
+ assert_equal 'Single Quoted String \t\n\r\'\"', LiteralParser.parse(%q{'Single Quoted String \t\n\r\'\"'})
42
+ assert_equal "Double Quoted String \t\n\r\'\"", LiteralParser.parse(%q{"Double Quoted String \t\n\r\'\""})
43
+ end
44
+ test "Parse Regexes" do
45
+ assert_equal /some_regex/, LiteralParser.parse('/some_regex/')
46
+ assert_equal /some_regex/imx, LiteralParser.parse('/some_regex/imx')
47
+ end
48
+ test "Parse Date" do
49
+ assert_equal Date.civil(2012,5,20), LiteralParser.parse('2012-05-20')
50
+ end
51
+ test "Parse Time" do
52
+ assert_equal Time.mktime(2012,5,20,18,29,52), LiteralParser.parse('2012-05-20T18:29:52')
53
+ end
54
+ test "Parse Array" do
55
+ array_string = '[nil, false, true, 123, 12.5, 2012-05-20, :sym, "str"]'
56
+ expected_array = [nil, false, true, 123, 12.5, Date.civil(2012,5,20), :sym, "str"]
57
+ assert_equal expected_array, LiteralParser.parse(array_string)
58
+ end
59
+ test "Parse Hash" do
60
+ array_string = '{nil => false, true => 123, 12.5 => 2012-05-20, :sym => "str"}'
61
+ expected_array = {nil => false, true => 123, 12.5 => Date.civil(2012,5,20), :sym => "str"}
62
+ assert_equal expected_array, LiteralParser.parse(array_string)
63
+ end
64
+ test "Parse Constants" do
65
+ assert_equal Time, LiteralParser.parse('Time')
66
+ end
67
+ test "Perform manual parsing" do
68
+ parser = LiteralParser.new("'hello'\n12\ntrue")
69
+ assert_equal 0, parser.position
70
+ assert_equal 'hello', parser.scan_value
71
+ assert_equal "\n12\ntrue", parser.rest
72
+ assert_equal 7, parser.position
73
+ assert_equal false, parser.end_of_string?
74
+
75
+ parser.position += 1
76
+ assert_equal 8, parser.position
77
+ assert_equal 12, parser.scan_value
78
+ assert_equal "\ntrue", parser.rest
79
+ assert_equal 10, parser.position
80
+ assert_equal false, parser.end_of_string?
81
+
82
+ parser.position += 1
83
+ assert_equal 11, parser.position
84
+ assert_equal true, parser.scan_value
85
+ assert_equal "", parser.rest
86
+ assert_equal 15, parser.position
87
+ assert_equal true, parser.end_of_string?
88
+ end
89
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: literal_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stefan Rusterholz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-20 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Parse Strings containing ruby literals and return a proper ruby object.
15
+ email: stefan.rusterholz@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/literal_parser/version.rb
21
+ - lib/literal_parser.rb
22
+ - test/lib/helper.rb
23
+ - test/runner.rb
24
+ - test/unit/lib/literal_parser.rb
25
+ - literal_parser.gemspec
26
+ - Rakefile
27
+ - README.markdown
28
+ homepage: https://github.com/apeiros/literal_parser
29
+ licenses: []
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>'
44
+ - !ruby/object:Gem::Version
45
+ version: 1.3.1
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 1.8.24
49
+ signing_key:
50
+ specification_version: 3
51
+ summary: Parse Strings containing ruby literals and return a proper ruby object.
52
+ test_files: []
53
+ has_rdoc: