edn 1.0.3 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,10 @@
1
1
  require 'rspec'
2
2
  require 'edn'
3
- require 'parslet/rig/rspec'
4
- require 'parslet/convenience'
5
3
  require 'rantly'
6
4
  require 'date'
7
5
  require 'time'
8
6
 
9
- REPEAT = (ENV["REPEAT"] || 100).to_i
7
+ REPEAT = (ENV["REPEAT"] || 150).to_i
10
8
 
11
9
  RSpec.configure do |c|
12
10
  c.fail_fast = true
@@ -19,6 +17,10 @@ RSpec.configure do |c|
19
17
  c.run_all_when_everything_filtered = true
20
18
  end
21
19
 
20
+ def io_for(s)
21
+ StringIO.new(s)
22
+ end
23
+
22
24
  module RantlyHelpers
23
25
 
24
26
  KEYWORD = lambda { |_|
@@ -47,7 +49,9 @@ module RantlyHelpers
47
49
 
48
50
  STRING = lambda { |_| sized(range(1, 100)) { string.to_edn } }
49
51
 
50
- FLOAT = lambda { |_| (float * range(-1000, 1000)).to_edn }
52
+ RUBY_STRING = lambda { |_| sized(range(1, 100)) { string } }
53
+
54
+ FLOAT = lambda { |_| (float * range(-4000, 5000)).to_edn }
51
55
 
52
56
  FLOAT_WITH_EXP = lambda { |_|
53
57
  # limited range because of Infinity
@@ -59,6 +63,14 @@ module RantlyHelpers
59
63
  join("")
60
64
  }
61
65
 
66
+ RUBY_CHAR = lambda { |_|
67
+ "\\" +
68
+ sized(1) {
69
+ freq([1, [:choose, "\n", "\r", " ", "\t"]],
70
+ [5, [:string, :graph]])
71
+ }
72
+ }
73
+
62
74
  CHARACTER = lambda { |_|
63
75
  "\\" +
64
76
  sized(1) {
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: edn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
- - Clinton N. Dreisbach
7
+ - Clinton N. Dreisbach & Russ Olsen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-17 00:00:00.000000000 Z
11
+ date: 2014-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: parslet
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 1.4.0
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 1.4.0
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: pry
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -82,7 +68,7 @@ dependencies:
82
68
  version: 10.0.3
83
69
  description: "'edn implements a reader for Extensible Data Notation by Rich Hickey.'"
84
70
  email:
85
- - clinton@thinkrelevance.com
71
+ - russ@russolsen.com
86
72
  executables: []
87
73
  extensions: []
88
74
  extra_rdoc_files: []
@@ -96,27 +82,26 @@ files:
96
82
  - Rakefile
97
83
  - edn.gemspec
98
84
  - lib/edn.rb
85
+ - lib/edn/char_stream.rb
99
86
  - lib/edn/core_ext.rb
100
87
  - lib/edn/metadata.rb
101
88
  - lib/edn/parser.rb
102
89
  - lib/edn/reader.rb
103
- - lib/edn/string_transformer.rb
104
- - lib/edn/transform.rb
105
90
  - lib/edn/type/list.rb
106
91
  - lib/edn/type/symbol.rb
107
92
  - lib/edn/type/unknown.rb
108
93
  - lib/edn/type/uuid.rb
109
94
  - lib/edn/types.rb
110
95
  - lib/edn/version.rb
111
- - lib/parslet/ignore.rb
96
+ - spec/edn/char_stream_spec.rb
112
97
  - spec/edn/metadata_spec.rb
113
98
  - spec/edn/parser_spec.rb
114
99
  - spec/edn/reader_spec.rb
115
- - spec/edn/transform_spec.rb
116
100
  - spec/edn_spec.rb
117
101
  - spec/spec_helper.rb
118
- homepage: ''
119
- licenses: []
102
+ homepage: https://github.com/relevance/edn-ruby
103
+ licenses:
104
+ - MIT
120
105
  metadata: {}
121
106
  post_install_message:
122
107
  rdoc_options: []
@@ -134,14 +119,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
119
  version: '0'
135
120
  requirements: []
136
121
  rubyforge_project:
137
- rubygems_version: 2.2.2
122
+ rubygems_version: 2.2.1
138
123
  signing_key:
139
124
  specification_version: 4
140
125
  summary: "'edn implements a reader for Extensible Data Notation by Rich Hickey.'"
141
126
  test_files:
127
+ - spec/edn/char_stream_spec.rb
142
128
  - spec/edn/metadata_spec.rb
143
129
  - spec/edn/parser_spec.rb
144
130
  - spec/edn/reader_spec.rb
145
- - spec/edn/transform_spec.rb
146
131
  - spec/edn_spec.rb
147
132
  - spec/spec_helper.rb
@@ -1,46 +0,0 @@
1
- module EDN
2
- module StringTransformer
3
- # Unescape characters in strings.
4
- # Borrowed from json-pure gem.
5
- UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
6
- UNESCAPE_MAP.update({ ?" => '"',
7
- ?\\ => '\\',
8
- ?/ => '/',
9
- #' Clear messed up syntax highlighting with Emacs.
10
- ?b => "\b",
11
- ?f => "\f",
12
- ?n => "\n",
13
- ?r => "\r",
14
- ?t => "\t",
15
- ?u => nil,
16
- })
17
-
18
- EMPTY_8BIT_STRING = ''
19
- if ::String.method_defined?(:encode)
20
- EMPTY_8BIT_STRING.force_encoding Encoding::ASCII_8BIT
21
- end
22
-
23
- def self.parse_string(string)
24
- string = string.to_s
25
- return '' if string.empty?
26
- string = string.gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n) do |c|
27
- #" Clear messed up syntax highlighting with Emacs.
28
- if u = UNESCAPE_MAP[$&[1]]
29
- u
30
- else # \uXXXX
31
- bytes = EMPTY_8BIT_STRING.dup
32
- i = 0
33
- while c[6 * i] == ?\\ && c[6 * i + 1] == ?u
34
- bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16)
35
- i += 1
36
- end
37
- JSON.iconv('utf-8', 'utf-16be', bytes)
38
- end
39
- end
40
- if string.respond_to?(:force_encoding)
41
- string.force_encoding(::Encoding::UTF_8)
42
- end
43
- string
44
- end
45
- end
46
- end
@@ -1,59 +0,0 @@
1
- require 'edn/string_transformer'
2
- require 'edn/types'
3
- require 'edn/metadata'
4
- require 'bigdecimal'
5
-
6
- module EDN
7
- class Transform < Parslet::Transform
8
- rule(:true => simple(:x)) { true }
9
- rule(:false => simple(:x)) { false }
10
- rule(:nil => simple(:x)) { nil }
11
-
12
- rule(:integer => simple(:num), :precision => simple(:n)) {
13
- Integer(num)
14
- }
15
- rule(:float => simple(:num), :precision => simple(:n)) {
16
- if n
17
- BigDecimal(num)
18
- else
19
- Float(num)
20
- end
21
- }
22
-
23
- rule(:string => []) { "" }
24
- rule(:string => simple(:x)) { EDN::StringTransformer.parse_string(x) }
25
- rule(:keyword => simple(:x)) { x.to_sym }
26
- rule(:symbol => simple(:x)) { EDN::Type::Symbol.new(x) }
27
- rule(:character => simple(:x)) {
28
- case x
29
- when "newline" then "\n"
30
- when "return" then "\r"
31
- when "tab" then "\t"
32
- when "space" then " "
33
- else x.to_s
34
- end
35
- }
36
-
37
- rule(:vector => subtree(:array)) { array }
38
- rule(:list => subtree(:array)) { EDN::Type::List.new(*array) }
39
- rule(:set => subtree(:array)) { Set.new(array) }
40
- rule(:map => subtree(:array)) { Hash[array.map { |hash| [hash[:key], hash[:value]] }] }
41
-
42
- rule(:tag => simple(:tag), :element => subtree(:element)) {
43
- EDN.tagged_element(tag.to_s, element)
44
- }
45
-
46
- rule(:metadata => subtree(:raw_metadata), :element => subtree(:element)) {
47
- metadata = raw_metadata.reverse.reduce({}) do |acc, m|
48
- case m
49
- when Symbol then acc.merge(m => true)
50
- when EDN::Type::Symbol then acc.merge(:tag => m)
51
- else acc.merge(m)
52
- end
53
- end
54
- element.extend EDN::Metadata
55
- element.metadata = metadata
56
- element
57
- }
58
- end
59
- end
@@ -1,24 +0,0 @@
1
- class IgnoreParslet < Parslet::Atoms::Base
2
- def initialize(parslet)
3
- @parslet = parslet
4
- end
5
- def to_s_inner(prec)
6
- @parslet.to_s(prec)
7
- end
8
- def try(source, context)
9
- success, value = result = @parslet.try(source, context)
10
-
11
- return succ(nil) if success
12
- return result
13
- end
14
- end
15
-
16
- module IgnoreDSL
17
- def ignore
18
- IgnoreParslet.new(self)
19
- end
20
- end
21
-
22
- class Parslet::Atoms::Base
23
- include IgnoreDSL
24
- end
@@ -1,176 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe EDN::Transform do
4
- context "integer" do
5
- it "should emit an integer" do
6
- subject.apply(:integer => "1", :precision => nil).should == 1
7
- end
8
- end
9
-
10
- context "float" do
11
- it "should emit an float" do
12
- subject.apply(:float => "1.0", :precision => nil).should == 1.0
13
- end
14
-
15
- it "should emit a BigDecimal if suffixed with M" do
16
- subject.apply(:float => "1.0", :precision => "M").should == BigDecimal("1.0")
17
- end
18
- end
19
-
20
- context "string" do
21
- it "should emit a string with control characters substituted" do
22
- subject.apply(:string => 'hello\nworld').should == "hello\nworld"
23
- end
24
-
25
- it "should not evaluate interpolated Ruby code" do
26
- subject.apply(:string => 'hello\n#{world}').should == "hello\n\#{world}"
27
- end
28
-
29
- it "should emit empty strings as strings" do
30
- subject.apply(:string => []).should == ""
31
- end
32
- end
33
-
34
- context "keyword" do
35
- it "should emit a Ruby symbol" do
36
- subject.apply(:keyword => "test").should == :test
37
- end
38
- end
39
-
40
- context "symbol" do
41
- it "should emit an EDN symbol" do
42
- subject.apply(:symbol => "test").should == ~'test'
43
- end
44
- end
45
-
46
- context "boolean" do
47
- it "should emit true or false" do
48
- subject.apply(:true => "true").should == true
49
- subject.apply(:false => "false").should == false
50
- end
51
- end
52
-
53
- context "nil" do
54
- it "should emit nil" do
55
- subject.apply(:nil => "nil").should == nil
56
- end
57
- end
58
-
59
- context "character" do
60
- it "should emit a string" do
61
- subject.apply(:character => "&").should == "&"
62
- end
63
-
64
- it "should handle newline, space, and tab special cases" do
65
- subject.apply(:character => "newline").should == "\n"
66
- subject.apply(:character => "space").should == " "
67
- subject.apply(:character => "tab").should == "\t"
68
- end
69
- end
70
-
71
- context "vector" do
72
- it "should emit an array" do
73
- subject.apply(:vector => []).should == []
74
- subject.apply(:vector => [{:integer => "1", :precision => nil}, {:string => "abc"}]).should == [1, "abc"]
75
- subject.apply(:vector => [{:vector => [{:integer => "1", :precision => nil}, {:string => "abc"}]}, {:float => "3.14", :precision => nil}]).should == [[1, "abc"], 3.14]
76
- end
77
- end
78
-
79
- context "list" do
80
- it "should emit a list" do
81
- subject.apply(:list => []).should == EDN.list
82
- subject.apply(:list => [{:integer => "1", :precision => nil}, {:string => "abc"}]).should == ~[1, "abc"]
83
- subject.apply(:list => [{:list => [{:integer => "1", :precision => nil}, {:string => "abc"}]}, {:float => "3.14", :precision => nil}]).should == \
84
- ~[~[1, "abc"], 3.14]
85
- end
86
-
87
- it "should be type-compatible with arrays" do
88
- subject.apply(:list => [{:integer => "1", :precision => nil}, {:string => "abc"}]).should == [1, "abc"]
89
- end
90
- end
91
-
92
- context "set" do
93
- it "should emit a set" do
94
- subject.apply(:set => []).should == Set.new
95
- subject.apply(:set => [1, "abc", 2]).should == Set.new([1, "abc", 2])
96
- end
97
- end
98
-
99
- context "map" do
100
- it "should emit a hash" do
101
- map_tree = {:map=>
102
- [ {:key=>{:keyword=>{:symbol=>"a"}}, :value=>{:integer=>"1", :precision => nil}},
103
- {:key=>{:keyword=>{:symbol=>"b"}}, :value=>{:integer=>"2", :precision => nil}}
104
- ]
105
- }
106
-
107
- subject.apply(map_tree).should == {:a => 1, :b => 2}
108
- end
109
-
110
- it "should work with nested maps" do
111
- map_tree = {:map=>
112
- [{:key=>{:keyword=>{:symbol=>"a"}}, :value=>{:integer=>"1", :precision => nil}},
113
- {:key=>{:keyword=>{:symbol=>"b"}}, :value=>{:integer=>"2", :precision => nil}},
114
- {:key=>
115
- {:map=>
116
- [{:key=>{:keyword=>{:symbol=>"c"}}, :value=>{:integer=>"3", :precision => nil}}]},
117
- :value=>{:integer=>"4", :precision => nil}}]}
118
- subject.apply(map_tree).should == {:a => 1, :b => 2, {:c => 3} => 4}
119
- end
120
- end
121
-
122
- context "tagged element" do
123
- it "should emit a EDN::Type::Unknown if the tag is not registered" do
124
- subject.apply({:tag => {:symbol => 'uri'}, :element => {:string => 'http://google.com'}}).should == EDN::Type::Unknown.new("uri", "http://google.com")
125
- end
126
-
127
- it "should emit the transformed element if the tag is registered" do
128
- EDN.register("uri", lambda { |uri| URI(uri) })
129
- subject.apply({:tag => {:symbol => 'uri'}, :element => {:string => 'http://google.com'}}).should == URI("http://google.com")
130
- EDN.unregister("uri") # cleanup
131
- end
132
-
133
- it "should work with nested elements" do
134
- tree = {
135
- :tag=>{:symbol=>"cnd/awesome"},
136
- :element=>
137
- {:vector=>
138
- [{:keyword=>{:symbol=>"a"}},
139
- {:list=>
140
- [{:integer=>"1", :precision=>nil},
141
- {:list=>
142
- [{:integer=>"2", :precision=>nil},
143
- {:integer=>"3", :precision=>nil}]}]},
144
- {:keyword=>{:symbol=>"b"}},
145
- {:keyword=>{:symbol=>"c"}},
146
- {:set=>
147
- [{:integer=>"1", :precision=>nil},
148
- {:integer=>"2", :precision=>nil},
149
- {:integer=>"3", :precision=>nil}]},
150
- {:vector=>
151
- [{:vector=>
152
- [{:vector=>[{:integer=>"42", :precision=>nil}]},
153
- {:integer=>"42", :precision=>nil}]}]}]}}
154
- expected = EDN::Type::Unknown.new('cnd/awesome',
155
- [:a, [1, [2, 3]], :b, :c,
156
- Set.new([1, 2, 3]), [[[42], 42]]])
157
- subject.apply(tree).should == expected
158
- end
159
- end
160
-
161
- context "element with metadata" do
162
- it "should tag the element with metadata" do
163
- tree = {
164
- :metadata =>
165
- [:map =>
166
- [
167
- {:key=>{:keyword=>{:symbol=>"a"}}, :value=>{:integer=>"1", :precision => nil}},
168
- {:key=>{:keyword=>{:symbol=>"b"}}, :value=>{:integer=>"2", :precision => nil}}]],
169
- :element => {:vector => [{:integer => "1", :precision => nil}, {:string => "abc"}]}}
170
-
171
- element = subject.apply(tree)
172
- element.should == [1, "abc"]
173
- element.metadata.should == {:a => 1, :b => 2}
174
- end
175
- end
176
- end