literal_parser 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: