lector 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+
5
+ # Only build master branch
6
+ branches:
7
+ only:
8
+ - master
9
+
10
+ # To stop Travis from running tests for a new commit,
11
+ # add the following to your commit message: [ci skip]
12
+ # You should add this when you edit documentation or comments, etc.
data/Gemfile CHANGED
@@ -1,3 +1,7 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ group :test do
6
+ gem 'rake'
7
+ end
data/Gemfile.lock CHANGED
@@ -24,6 +24,7 @@ GEM
24
24
  method_source (~> 0.6.7)
25
25
  ruby_parser (>= 2.3.1)
26
26
  slop (~> 2.1.0)
27
+ rake (0.9.2.2)
27
28
  rspec (2.7.0)
28
29
  rspec-core (~> 2.7.0)
29
30
  rspec-expectations (~> 2.7.0)
@@ -50,5 +51,6 @@ DEPENDENCIES
50
51
  guard-rspec
51
52
  lector!
52
53
  pry
54
+ rake
53
55
  rspec
54
56
  simplecov
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
- `lector` reads Ruby data as a string or from a file without evaluating the code it reads.
1
+ `lector` reads Ruby data as a string or from a file without evaluating the code it reads. [![Build Status](https://secure.travis-ci.org/alandipert/lector.png)](http://travis-ci.org/alandipert/lector)
2
2
 
3
3
  # Usage
4
4
 
5
+ ## Reading Strings
5
6
  ```
6
7
  > require 'lector'
7
8
  => true
@@ -9,6 +10,17 @@
9
10
  => {:x=>11, :pants?=>false}
10
11
  ```
11
12
 
13
+ ## Read-Eval
14
+ ```
15
+ # read-eval is off by default:
16
+ > Lector::read_s("{three: #='1+2'}")
17
+ => {:three=>nil}
18
+
19
+ # but you can turn it on...
20
+ > Lector::read_s("{three: #='1+2'}", :read_eval => true)
21
+ => {:three=>3}
22
+ ```
23
+
12
24
  Please see the
13
25
  [tests](https://github.com/alandipert/lector/tree/master/spec/lector)
14
26
  for more usage examples.
@@ -9,7 +9,7 @@ grammar Lector::RubyParse
9
9
  end
10
10
 
11
11
  rule literal
12
- nil | boolean | string | symbol | hashkey | number
12
+ nil | boolean | string | code | symbol | hashkey | number
13
13
  end
14
14
 
15
15
  rule nil
@@ -21,11 +21,19 @@ grammar Lector::RubyParse
21
21
  end
22
22
 
23
23
  rule string
24
- ("\"" content:string_content* "\"") <Lector::Types::String>
24
+ single_quoted_string | double_quoted_string
25
25
  end
26
26
 
27
- rule string_content
28
- (/[^"\\]/ | /\\./)
27
+ rule double_quoted_string
28
+ ("\"" content:(/[^"\\]/ | /\\./)* "\"") <Lector::Types::String>
29
+ end
30
+
31
+ rule single_quoted_string
32
+ ("'" content:(/[^'\\]/ | /\\./)* "'") <Lector::Types::String>
33
+ end
34
+
35
+ rule code
36
+ ("#=" code:string) <Lector::Types::Code>
29
37
  end
30
38
 
31
39
  rule symbol
data/lib/lector/types.rb CHANGED
@@ -11,6 +11,14 @@ module Lector
11
11
  module HashKey; def val; to_sym; end; end
12
12
  module String; def val; captures[:content].first.gsub(/\\\"/,"\""); end; end
13
13
 
14
+ module Code
15
+ def val
16
+ if $_LECTOR_READ_EVAL
17
+ eval(code.to_s.slice(3..-2))
18
+ end
19
+ end
20
+ end
21
+
14
22
  module Array
15
23
  def val
16
24
  captures[:form].map(&:val)
@@ -1,3 +1,3 @@
1
1
  module Lector
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/lector.rb CHANGED
@@ -7,10 +7,11 @@ end
7
7
 
8
8
  module Lector
9
9
  module RubyParse; end
10
- def self.read_s(string)
10
+ def self.read_s(string, opts = {})
11
+ $_LECTOR_READ_EVAL = opts[:read_eval]
11
12
  Lector::RubyParse::parse(string).val
12
13
  end
13
- def self.read_file(file)
14
- Lector::RubyParse::parse(File.read(file)).val
14
+ def self.read_file(file, opts = {})
15
+ read_s(File.read(file), opts)
15
16
  end
16
17
  end
@@ -2,107 +2,114 @@ require File.join(File.dirname(__FILE__), *%w[.. spec_helper.rb])
2
2
  require 'pry'
3
3
  require 'tempfile'
4
4
 
5
- def read_s(string)
6
- Lector::read_s(string)
7
- end
8
-
9
- def read_file(file)
10
- Lector::read_file(file)
11
- end
12
-
13
5
  describe Lector do
14
6
  context 'reading strings' do
15
7
  it 'parses integers' do
16
- read_s("+42").should == 42
17
- read_s("-42").should == -42
18
- read_s("42").should == 42
19
- read_s("-42").should == -42
20
- read_s("-0").should == 0
21
- read_s("+0").should == 0
8
+ Lector::read_s("+42").should == 42
9
+ Lector::read_s("-42").should == -42
10
+ Lector::read_s("42").should == 42
11
+ Lector::read_s("-42").should == -42
12
+ Lector::read_s("-0").should == 0
13
+ Lector::read_s("+0").should == 0
22
14
  end
23
15
 
24
16
  it "parses hex integers" do
25
- read_s("0xF").should == 15
26
- read_s("+0xF").should == 15
27
- read_s("-0xF").should == -15
17
+ Lector::read_s("0xF").should == 15
18
+ Lector::read_s("+0xF").should == 15
19
+ Lector::read_s("-0xF").should == -15
28
20
  end
29
21
 
30
22
  it "parses floating point numbers" do
31
- read_s("1.1").should == 1.1
32
- read_s("-1.1").should == -1.1
33
- read_s("-1.21e10").should == -12_100_000_000.0
34
- read_s("+1.21e10").should == 12_100_000_000.0
35
- read_s("1e4").should == 10_000
23
+ Lector::read_s("1.1").should == 1.1
24
+ Lector::read_s("-1.1").should == -1.1
25
+ Lector::read_s("-1.21e10").should == -12_100_000_000.0
26
+ Lector::read_s("+1.21e10").should == 12_100_000_000.0
27
+ Lector::read_s("1e4").should == 10_000
36
28
  end
37
29
 
38
30
  it "parses true and false" do
39
- read_s("true").should == true
40
- read_s("false").should == false
31
+ Lector::read_s("true").should == true
32
+ Lector::read_s("false").should == false
41
33
  end
42
34
 
43
35
  it "parses nil" do
44
- read_s("nil").should == nil
36
+ Lector::read_s("nil").should == nil
45
37
  end
46
38
 
47
39
  it 'parses symbols' do
48
- read_s(":sym").should == :sym
49
- read_s(':"blah"').should == :blah
50
- read_s(':"blah blah"').should == :"blah blah"
40
+ Lector::read_s(":sym").should == :sym
41
+ Lector::read_s(':"blah"').should == :blah
42
+ Lector::read_s(':"blah blah"').should == :"blah blah"
43
+ Lector::read_s(":'foo foo'").should == :"foo foo"
51
44
  end
52
45
 
53
46
  it 'parses arrays of single elements' do
54
- read_s('[42]').should == [42]
47
+ Lector::read_s('[42]').should == [42]
55
48
  end
56
49
 
57
50
  it 'ignores whitespace' do
58
- read_s("[ 42 ]").should == [42]
51
+ Lector::read_s("[ 42 ]").should == [42]
59
52
  end
60
53
 
61
54
  it 'parses arrays of multiple elements' do
62
- read_s("[42, -1]").should == [42, -1]
55
+ Lector::read_s("[42, -1]").should == [42, -1]
63
56
  end
64
57
 
65
58
  it 'parses hashes' do
66
- read_s("{a: 7, b: 6}").should == {:a => 7, :b => 6}
67
- read_s("{b: 6}").should == {:b => 6}
68
- read_s("{:a => 7, :b => 6}").should == {:a => 7, :b => 6}
69
- read_s("{:a => 7, b: 6}").should == {:a => 7, :b => 6}
59
+ Lector::read_s("{a: 7, b: 6}").should == {:a => 7, :b => 6}
60
+ Lector::read_s("{b: 6}").should == {:b => 6}
61
+ Lector::read_s("{:a => 7, :b => 6}").should == {:a => 7, :b => 6}
62
+ Lector::read_s("{:a => 7, b: 6}").should == {:a => 7, :b => 6}
70
63
  end
71
64
 
72
65
  it 'parses nested collections' do
73
- read_s("[[1,2], 3, 4]").should == [[1, 2], 3, 4]
66
+ Lector::read_s("[[1,2], 3, 4]").should == [[1, 2], 3, 4]
74
67
  end
75
68
 
76
69
  it 'has no problem with hashes of arrays' do
77
- read_s("{a: [1, 2], b: [3, 4]}").should == {:a => [1, 2], :b => [3, 4]}
78
- read_s("{:a => [1, 2], :b => [3, 4]}").should == {:a => [1, 2], :b => [3, 4]}
70
+ Lector::read_s("{a: [1, 2], b: [3, 4]}").should == {:a => [1, 2], :b => [3, 4]}
71
+ Lector::read_s("{:a => [1, 2], :b => [3, 4]}").should == {:a => [1, 2], :b => [3, 4]}
79
72
  end
80
73
 
81
74
  it 'copes when data is surrounded by whitespace' do
82
- read_s("
75
+ Lector::read_s("
83
76
  {a: 7, b: 6} ").should == {:a => 7, :b => 6}
84
77
  end
85
78
 
86
- it 'reads strings' do
87
- read_s('"a string by any other name is just as tangly"').should == 'a string by any other name is just as tangly'
79
+ it 'reads double-quoted strings' do
80
+ Lector::read_s('"a string by any other name is just as tangly"').should == 'a string by any other name is just as tangly'
81
+ end
82
+
83
+ it 'reads single-quoted strings' do
84
+ Lector::read_s("'i only have single quotes'").should == 'i only have single quotes'
88
85
  end
89
86
 
90
87
  it 'reads strings with escaped quotes' do
91
- read_s('"a string with an \"escaped quote\""').should == 'a string with an "escaped quote"'
88
+ Lector::read_s('"a string with an \"escaped quote\""').should == 'a string with an "escaped quote"'
92
89
  end
93
90
 
94
91
  it 'preserves other escaped characters' do
95
- read_s('"a string with a\nnewline"').should == 'a string with a\nnewline'
92
+ Lector::read_s('"a string with a\nnewline"').should == 'a string with a\nnewline'
96
93
  end
97
94
  end
98
95
 
96
+ context 'read-evaling' do
97
+ it "shouldn't eval the code" do
98
+ Lector::read_s("#='1+2'").should == nil
99
+ end
100
+ it "should eval the code" do
101
+ Lector::read_s("#='1+2'", :read_eval => true).should == 3
102
+ end
103
+
104
+ end
105
+
99
106
  context 'reading files' do
100
107
  it 'should be able to round-trip data to file' do
101
108
  hsh = {:a => [1, 2], nil => false, :b => [3, 4], blah: [1.2, {:x => 20}]}
102
109
  Tempfile.new('lector').tap do |f|
103
110
  f.write(hsh.to_s)
104
111
  f.rewind
105
- read_file(f).should == hsh
112
+ Lector::read_file(f).should == hsh
106
113
  end
107
114
  end
108
115
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -119,6 +119,7 @@ files:
119
119
  - .document
120
120
  - .gitignore
121
121
  - .rvmrc
122
+ - .travis.yml
122
123
  - Gemfile
123
124
  - Gemfile.lock
124
125
  - Guardfile