lector 0.0.1 → 0.0.2

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/.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