edn2023 1.1.4

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.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +29 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE +22 -0
  7. data/README.md +268 -0
  8. data/Rakefile +12 -0
  9. data/edn2023.gemspec +22 -0
  10. data/lib/edn/char_stream.rb +84 -0
  11. data/lib/edn/core_ext.rb +112 -0
  12. data/lib/edn/metadata.rb +27 -0
  13. data/lib/edn/parser.rb +92 -0
  14. data/lib/edn/reader.rb +23 -0
  15. data/lib/edn/ruby_edn_parser.rb +266 -0
  16. data/lib/edn/type/list.rb +13 -0
  17. data/lib/edn/type/symbol.rb +39 -0
  18. data/lib/edn/type/unknown.rb +9 -0
  19. data/lib/edn/type/uuid.rb +9 -0
  20. data/lib/edn/types.rb +3 -0
  21. data/lib/edn/version.rb +3 -0
  22. data/lib/edn.rb +80 -0
  23. data/spec/edn/char_stream_spec.rb +111 -0
  24. data/spec/edn/metadata_spec.rb +38 -0
  25. data/spec/edn/parser_spec.rb +162 -0
  26. data/spec/edn/reader_spec.rb +23 -0
  27. data/spec/edn_spec.rb +114 -0
  28. data/spec/exemplars/big_decimal.edn +1 -0
  29. data/spec/exemplars/big_decimal.rb +1 -0
  30. data/spec/exemplars/big_int.edn +1 -0
  31. data/spec/exemplars/big_int.rb +1 -0
  32. data/spec/exemplars/char.edn +1 -0
  33. data/spec/exemplars/char.rb +1 -0
  34. data/spec/exemplars/empty_string.edn +1 -0
  35. data/spec/exemplars/empty_string.rb +1 -0
  36. data/spec/exemplars/false.edn +1 -0
  37. data/spec/exemplars/false.rb +1 -0
  38. data/spec/exemplars/float.edn +1 -0
  39. data/spec/exemplars/float.rb +1 -0
  40. data/spec/exemplars/float_neg_exp.edn +1 -0
  41. data/spec/exemplars/float_neg_exp.rb +1 -0
  42. data/spec/exemplars/float_point_dec_neg_exp.edn +1 -0
  43. data/spec/exemplars/float_point_dec_neg_exp.rb +1 -0
  44. data/spec/exemplars/float_point_plus_exp.edn +1 -0
  45. data/spec/exemplars/float_point_plus_exp.rb +1 -0
  46. data/spec/exemplars/float_pointneg_exp.edn +1 -0
  47. data/spec/exemplars/float_pointneg_exp.rb +1 -0
  48. data/spec/exemplars/float_pos_exp.edn +1 -0
  49. data/spec/exemplars/float_pos_exp.rb +1 -0
  50. data/spec/exemplars/float_sign_exp.edn +1 -0
  51. data/spec/exemplars/float_sign_exp.rb +1 -0
  52. data/spec/exemplars/float_with_exp.edn +1 -0
  53. data/spec/exemplars/float_with_exp.rb +1 -0
  54. data/spec/exemplars/float_with_exp_no_dec.edn +1 -0
  55. data/spec/exemplars/float_with_exp_no_dec.rb +1 -0
  56. data/spec/exemplars/gt_symbol.edn +1 -0
  57. data/spec/exemplars/gt_symbol.rb +1 -0
  58. data/spec/exemplars/integer.edn +1 -0
  59. data/spec/exemplars/integer.rb +1 -0
  60. data/spec/exemplars/keyword.edn +1 -0
  61. data/spec/exemplars/keyword.rb +1 -0
  62. data/spec/exemplars/keyword_with_namespace.edn +1 -0
  63. data/spec/exemplars/keyword_with_namespace.rb +1 -0
  64. data/spec/exemplars/list_empty.edn +1 -0
  65. data/spec/exemplars/list_empty.rb +1 -0
  66. data/spec/exemplars/list_mixed.edn +1 -0
  67. data/spec/exemplars/list_mixed.rb +1 -0
  68. data/spec/exemplars/list_nested.edn +1 -0
  69. data/spec/exemplars/list_nested.rb +1 -0
  70. data/spec/exemplars/list_one_element.edn +1 -0
  71. data/spec/exemplars/list_one_element.rb +1 -0
  72. data/spec/exemplars/long_string.edn +1 -0
  73. data/spec/exemplars/long_string.rb +1 -0
  74. data/spec/exemplars/map_empty.edn +1 -0
  75. data/spec/exemplars/map_empty.rb +1 -0
  76. data/spec/exemplars/map_nested.edn +1 -0
  77. data/spec/exemplars/map_nested.rb +1 -0
  78. data/spec/exemplars/map_one_element.edn +1 -0
  79. data/spec/exemplars/map_one_element.rb +1 -0
  80. data/spec/exemplars/map_two_entry.edn +1 -0
  81. data/spec/exemplars/map_two_entry.rb +1 -0
  82. data/spec/exemplars/mmv +4 -0
  83. data/spec/exemplars/nil.edn +1 -0
  84. data/spec/exemplars/nil.rb +1 -0
  85. data/spec/exemplars/set_empty.edn +1 -0
  86. data/spec/exemplars/set_empty.rb +1 -0
  87. data/spec/exemplars/set_nested.edn +1 -0
  88. data/spec/exemplars/set_nested.rb +1 -0
  89. data/spec/exemplars/set_one_element.edn +1 -0
  90. data/spec/exemplars/set_one_element.rb +1 -0
  91. data/spec/exemplars/set_two_elements.edn +1 -0
  92. data/spec/exemplars/set_two_elements.rb +1 -0
  93. data/spec/exemplars/simple_skip.edn +1 -0
  94. data/spec/exemplars/simple_skip.rb +1 -0
  95. data/spec/exemplars/skip_more_space.edn +1 -0
  96. data/spec/exemplars/skip_more_space.rb +1 -0
  97. data/spec/exemplars/skip_more_vector_elements.edn +1 -0
  98. data/spec/exemplars/skip_more_vector_elements.rb +1 -0
  99. data/spec/exemplars/skip_some_vector_elements.edn +1 -0
  100. data/spec/exemplars/skip_some_vector_elements.rb +1 -0
  101. data/spec/exemplars/skip_two_vector_elements.edn +1 -0
  102. data/spec/exemplars/skip_two_vector_elements.rb +1 -0
  103. data/spec/exemplars/skip_vector_element.edn +1 -0
  104. data/spec/exemplars/skip_vector_element.rb +1 -0
  105. data/spec/exemplars/skip_with_spaces.edn +1 -0
  106. data/spec/exemplars/skip_with_spaces.rb +1 -0
  107. data/spec/exemplars/skip_yet_more_space.edn +1 -0
  108. data/spec/exemplars/skip_yet_more_space.rb +1 -0
  109. data/spec/exemplars/special_symbol.edn +1 -0
  110. data/spec/exemplars/special_symbol.rb +1 -0
  111. data/spec/exemplars/string_with_newline.edn +1 -0
  112. data/spec/exemplars/string_with_newline.rb +1 -0
  113. data/spec/exemplars/symbol.edn +1 -0
  114. data/spec/exemplars/symbol.rb +1 -0
  115. data/spec/exemplars/symbol_begins_with_false.edn +1 -0
  116. data/spec/exemplars/symbol_begins_with_false.rb +1 -0
  117. data/spec/exemplars/symbol_begins_with_nil.edn +1 -0
  118. data/spec/exemplars/symbol_begins_with_nil.rb +1 -0
  119. data/spec/exemplars/symbol_with_dash.edn +1 -0
  120. data/spec/exemplars/symbol_with_dash.rb +1 -0
  121. data/spec/exemplars/symbol_with_namespace.edn +1 -0
  122. data/spec/exemplars/symbol_with_namespace.rb +1 -0
  123. data/spec/exemplars/tagged_instant.edn +1 -0
  124. data/spec/exemplars/tagged_instant.rb +1 -0
  125. data/spec/exemplars/tagged_uuid.edn +1 -0
  126. data/spec/exemplars/tagged_uuid.rb +1 -0
  127. data/spec/exemplars/true.edn +1 -0
  128. data/spec/exemplars/true.rb +1 -0
  129. data/spec/exemplars/utf8.edn +1 -0
  130. data/spec/exemplars/utf8.rb +1 -0
  131. data/spec/exemplars/vector_empty.edn +1 -0
  132. data/spec/exemplars/vector_empty.rb +1 -0
  133. data/spec/exemplars/vector_mixed.edn +1 -0
  134. data/spec/exemplars/vector_mixed.rb +1 -0
  135. data/spec/exemplars/vector_nested.edn +1 -0
  136. data/spec/exemplars/vector_nested.rb +1 -0
  137. data/spec/exemplars/vector_one_element.edn +1 -0
  138. data/spec/exemplars/vector_one_element.rb +1 -0
  139. data/spec/exemplars/whole_number_with_exp.edn +1 -0
  140. data/spec/exemplars/whole_number_with_exp.rb +1 -0
  141. data/spec/spec_helper.rb +164 -0
  142. metadata +357 -0
@@ -0,0 +1,162 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'edn_parser' do
4
+ include RantlyHelpers
5
+
6
+ let(:parser) { EDN.new_parser }
7
+
8
+ it "can contain comments" do
9
+ edn = ";; This is some sample data\n[1 2 ;; the first two values\n3]"
10
+ EDN.read(edn).should == [1, 2, 3]
11
+ end
12
+
13
+ it "can discard using the discard reader macro" do
14
+ edn = "[1 2 #_3 {:foo #_bar :baz}]"
15
+ EDN.read(edn).should == [1, 2, {:foo => :baz}]
16
+ end
17
+
18
+ context "element" do
19
+ it "should consume metadata with the element" do
20
+ x = EDN.read('^{:doc "test"} [1 2]')
21
+ x.should == [1, 2]
22
+ x.metadata.should == {doc: "test"}
23
+ end
24
+ end
25
+
26
+ context "integer" do
27
+ it "should consume integers" do
28
+ rant(RantlyHelpers::INTEGER).each do |int|
29
+ (EDN.read int.to_s).should == int.to_i
30
+ end
31
+ end
32
+
33
+ it "should consume integers prefixed with a +" do
34
+ rant(RantlyHelpers::INTEGER).each do |int|
35
+ (EDN.read "+#{int.to_i.abs.to_s}").should == int.to_i.abs
36
+ end
37
+ end
38
+ end
39
+
40
+ context "float" do
41
+ it "should consume simple floats" do
42
+ rant(RantlyHelpers::FLOAT).each do |float|
43
+ EDN.read(float.to_s).should == float.to_f
44
+ end
45
+ end
46
+
47
+ it "should consume floats with exponents" do
48
+ rant(RantlyHelpers::FLOAT_WITH_EXP).each do |float|
49
+ EDN.read(float.to_s).should == float.to_f
50
+ end
51
+ end
52
+
53
+ it "should consume floats prefixed with a +" do
54
+ rant(RantlyHelpers::FLOAT).each do |float|
55
+ EDN.read("+#{float.to_f.abs.to_s}").should == float.to_f.abs
56
+ end
57
+ end
58
+ end
59
+
60
+ context "symbol" do
61
+ context "special cases" do
62
+ it "should consume '/'" do
63
+ EDN.read('/').should == EDN::Type::Symbol.new(:"/")
64
+ end
65
+
66
+ it "should consume '.'" do
67
+ EDN.read('.').should == EDN::Type::Symbol.new(:".")
68
+ end
69
+
70
+ it "should consume '-'" do
71
+ EDN.read('-').should == EDN::Type::Symbol.new(:"-")
72
+ end
73
+ end
74
+ end
75
+
76
+ context "keyword" do
77
+ it "should consume any keywords" do
78
+ rant(RantlyHelpers::SYMBOL).each do |symbol|
79
+ EDN.read(":#{symbol}").should == symbol.to_sym
80
+ end
81
+ end
82
+ end
83
+
84
+ context "string" do
85
+ it "should consume any string" do
86
+ rant(RantlyHelpers::RUBY_STRING).each do |string|
87
+ EDN.read(string.to_edn).should == string
88
+ end
89
+ end
90
+ end
91
+
92
+ context "character" do
93
+ it "should consume any character" do
94
+ rant(RantlyHelpers::RUBY_CHAR).each do |char|
95
+ EDN.read(char.to_edn).should == char
96
+ end
97
+ end
98
+ end
99
+
100
+ context "vector" do
101
+ it "should consume an empty vector" do
102
+ EDN.read('[]').should == []
103
+ EDN.read('[ ]').should == []
104
+ end
105
+
106
+ it "should consume vectors of mixed elements" do
107
+ rant(RantlyHelpers::VECTOR).each do |vector|
108
+ expect { EDN.read(vector) }.to_not raise_error
109
+ end
110
+ end
111
+ end
112
+
113
+ context "list" do
114
+ it "should consume an empty list" do
115
+ EDN.read('()').should == []
116
+ EDN.read('( )').should == []
117
+ end
118
+
119
+ it "should consume lists of mixed elements" do
120
+ rant(RantlyHelpers::LIST).each do |list|
121
+ expect { EDN.read(list) }.to_not raise_error
122
+ end
123
+ end
124
+ end
125
+
126
+ context "set" do
127
+ it "should consume an empty set" do
128
+ EDN.read('#{}').should == Set.new
129
+ EDN.read('#{ }').should == Set.new
130
+ end
131
+
132
+ it "should consume sets of mixed elements" do
133
+ rant(RantlyHelpers::SET).each do |set|
134
+ EDN.read(set)
135
+ end
136
+ end
137
+ end
138
+
139
+ context "map" do
140
+ it "should consume maps of mixed elements" do
141
+ rant(RantlyHelpers::MAP).each do |map|
142
+ expect { EDN.read(map) }.not_to raise_error
143
+ end
144
+ end
145
+ end
146
+
147
+ context "tagged element" do
148
+ context "#inst" do
149
+ it "should consume #inst" do
150
+ rant(RantlyHelpers::INST).each do |element|
151
+ expect { EDN.read(element) }.not_to raise_error
152
+ end
153
+ end
154
+ end
155
+
156
+ it "should consume tagged elements" do
157
+ rant(RantlyHelpers::TAGGED_ELEMENT).each do |element|
158
+ expect { EDN.read(element) }.not_to raise_error
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe EDN::Reader do
4
+ let(:reader) { EDN::Reader.new("[1 2] 3 :a {:b c} ") }
5
+
6
+ it "should read each value" do
7
+ reader.read.should == [1, 2]
8
+ reader.read.should == 3
9
+ reader.read.should == :a
10
+ reader.read.should == {:b => ~"c"}
11
+ end
12
+
13
+ it "should respond to each" do
14
+ reader.each do |element|
15
+ element.should_not be_nil
16
+ end
17
+ end
18
+
19
+ it "returns a special end of file value if asked" do
20
+ 4.times { reader.read(:the_end).should_not == :the_end }
21
+ reader.read(:no_more).should == :no_more
22
+ end
23
+ end
data/spec/edn_spec.rb ADDED
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+ require 'stringio'
3
+
4
+ describe EDN do
5
+ include RantlyHelpers
6
+
7
+ ExemplarPattern = "#{File.dirname(__FILE__)}/exemplars/*.edn"
8
+
9
+ context 'Exemplar' do
10
+ edn_files = Dir[ExemplarPattern]
11
+ edn_files.each do |edn_file|
12
+ rb_file = edn_file.sub(/\.edn$/, '.rb')
13
+ it "reads file #{File.basename(edn_file)} correctly" do
14
+ expected = eval(File.read(rb_file))
15
+ actual = EDN.read(File.read(edn_file))
16
+ actual.should == expected
17
+ end
18
+
19
+ it "round trips the value in #{File.basename(edn_file)} correctly" do
20
+ expected = eval(File.read(rb_file))
21
+ actual = EDN.read(File.read(edn_file))
22
+ round_trip = EDN.read(actual.to_edn)
23
+ round_trip.should == expected
24
+ end
25
+ end
26
+ end
27
+
28
+
29
+ context "#read" do
30
+ #it "reads from a stream" do
31
+ # io = StringIO.new("123")
32
+ # EDN.read(io).should == 123
33
+ #end
34
+
35
+ #it "reads mutiple values from a stream" do
36
+ # io = StringIO.new("123 456 789")
37
+ # EDN.read(io).should == 123
38
+ # EDN.read(io).should == 456
39
+ # EDN.read(io).should == 789
40
+ #end
41
+
42
+ it "raises an exception on eof by default" do
43
+ expect { EDN.read('') }.to raise_error
44
+ end
45
+
46
+ #it "allows you to specify an eof value" do
47
+ # io = StringIO.new("123 456")
48
+ # EDN.read(io, :my_eof).should == 123
49
+ # EDN.read(io, :my_eof).should == 456
50
+ # EDN.read(io, :my_eof).should == :my_eof
51
+ #end
52
+
53
+ it "allows you to specify nil as an eof value" do
54
+ EDN.read("", nil).should == nil
55
+ end
56
+ end
57
+
58
+ context "reading data" do
59
+ it "treats carriage returns like whitespace" do
60
+ EDN.read("\r\n[\r\n]\r\n").should == []
61
+ EDN.read("\r[\r]\r\r").should == []
62
+ end
63
+
64
+ it "reads any valid element" do
65
+ elements = rant(RantlyHelpers::ELEMENT)
66
+ elements.each do |element|
67
+ begin
68
+ if element == "nil"
69
+ EDN.read(element).should be_nil
70
+ else
71
+ EDN.read(element).should_not be_nil
72
+ end
73
+ rescue Exception => ex
74
+ puts "Bad element: #{element}"
75
+ raise ex
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ context "#register" do
82
+ it "uses the identity function when no handler is given" do
83
+ EDN.register "some/tag"
84
+ EDN.read("#some/tag {}").class.should == Hash
85
+ end
86
+ end
87
+
88
+ context "writing" do
89
+ it "writes any valid element" do
90
+ elements = rant(RantlyHelpers::ELEMENT)
91
+ elements.each do |element|
92
+ expect {
93
+ begin
94
+ EDN.read(element).to_edn
95
+ rescue Exception => ex
96
+ puts "Bad element: #{element}"
97
+ raise ex
98
+ end
99
+ }.to_not raise_error
100
+ end
101
+ end
102
+
103
+ it "writes equivalent edn to what it reads" do
104
+ elements = rant(RantlyHelpers::ELEMENT)
105
+ elements.each do |element|
106
+ ruby_element = EDN.read(element)
107
+ ruby_element.should == EDN.read(ruby_element.to_edn)
108
+ if ruby_element.respond_to?(:metadata)
109
+ ruby_element.metadata.should == EDN.read(ruby_element.to_edn).metadata
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1 @@
1
+ 123412341231212121241234M
@@ -0,0 +1 @@
1
+ 123412341231212121241234
@@ -0,0 +1 @@
1
+ 123412341231212121241234
@@ -0,0 +1 @@
1
+ 123412341231212121241234
@@ -0,0 +1 @@
1
+ \c
@@ -0,0 +1 @@
1
+ "c"
@@ -0,0 +1 @@
1
+ ""
@@ -0,0 +1 @@
1
+ ""
@@ -0,0 +1 @@
1
+ false
@@ -0,0 +1 @@
1
+ false
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1 @@
1
+ 3e-10
@@ -0,0 +1 @@
1
+ 3.0e-10
@@ -0,0 +1 @@
1
+ 3.0e-10
@@ -0,0 +1 @@
1
+ 3.0e-10
@@ -0,0 +1 @@
1
+ 3.e+10
@@ -0,0 +1 @@
1
+ 3.0e10
@@ -0,0 +1 @@
1
+ 3.e-10
@@ -0,0 +1 @@
1
+ 3.0e-10
@@ -0,0 +1 @@
1
+ 3e+10
@@ -0,0 +1 @@
1
+ 3.0e10
@@ -0,0 +1 @@
1
+ 3.0e+10
@@ -0,0 +1 @@
1
+ 3.0e10
@@ -0,0 +1 @@
1
+ 3.0e10
@@ -0,0 +1 @@
1
+ 3.0e10
@@ -0,0 +1 @@
1
+ 3.e10
@@ -0,0 +1 @@
1
+ 3.0e10
@@ -0,0 +1 @@
1
+ >
@@ -0,0 +1 @@
1
+ EDN::Type::Symbol.new('>')
@@ -0,0 +1 @@
1
+ 1
@@ -0,0 +1 @@
1
+ 1
@@ -0,0 +1 @@
1
+ :hello
@@ -0,0 +1 @@
1
+ :hello
@@ -0,0 +1 @@
1
+ :hello/world
@@ -0,0 +1 @@
1
+ :"hello/world"
@@ -0,0 +1 @@
1
+ ()
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1 @@
1
+ ("hello" 1 2)
@@ -0,0 +1 @@
1
+ ['hello', 1, 2]
@@ -0,0 +1 @@
1
+ ((1 (:hi)))
@@ -0,0 +1 @@
1
+ [[1, [:hi]]]
@@ -0,0 +1 @@
1
+ (1)
@@ -0,0 +1 @@
1
+ [1]