xnlogic-transit-ruby 0.8.572-java

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.
@@ -0,0 +1,68 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Transit
16
+ # Transit::Writer marshals Ruby objects as transit values to an output stream.
17
+ # @see https://github.com/cognitect/transit-format
18
+ class Writer
19
+
20
+ # @param [Symbol] format required :json, :json_verbose, or :msgpack
21
+ # @param [IO] io required
22
+ # @param [Hash] opts optional
23
+ #
24
+ # Creates a new Writer configured to write to <tt>io</tt> in
25
+ # <tt>format</tt> (<tt>:json</tt>, <tt>:json_verbose</tt>,
26
+ # <tt>:msgpack</tt>).
27
+ #
28
+ # Use opts to register custom write handlers, associating each one
29
+ # with its type.
30
+ #
31
+ # @example
32
+ # json_writer = Transit::Writer.new(:json, io)
33
+ # json_verbose_writer = Transit::Writer.new(:json_verbose, io)
34
+ # msgpack_writer = Transit::Writer.new(:msgpack, io)
35
+ # writer_with_custom_handlers = Transit::Writer.new(:json, io,
36
+ # :handlers => {Point => PointWriteHandler})
37
+ #
38
+ # @see Transit::WriteHandlers
39
+ def initialize(format, io, opts={})
40
+ @marshaler = case format
41
+ when :json
42
+ Marshaler::Json.new(io, {:handlers => {},
43
+ :oj_opts => {:indent => -1}}.merge(opts))
44
+ when :json_verbose
45
+ Marshaler::VerboseJson.new(io, {:handlers => {}}.merge(opts))
46
+ else
47
+ Marshaler::MessagePack.new(io, {:handlers => {}}.merge(opts))
48
+ end
49
+ end
50
+
51
+ # Converts a Ruby object to a transit value and writes it to this
52
+ # Writer's output stream.
53
+ #
54
+ # @param obj the value to write
55
+ # @example
56
+ # writer = Transit::Writer.new(:json, io)
57
+ # writer.write(Date.new(2014,7,22))
58
+ if Transit::jruby?
59
+ def write(obj)
60
+ @marshaler.write(obj)
61
+ end
62
+ else
63
+ def write(obj)
64
+ @marshaler.marshal_top(obj)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,85 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ unless File.exist?('../transit-format/examples/0.8/simple')
16
+ puts <<-MSG
17
+ Before you can run the rspec examples, you need to install the
18
+ the https://github.com/cognitect/transit-format repo in a sibling
19
+ directory, e.g.
20
+
21
+ cd ..
22
+ git clone https://github.com/cognitect/transit-format
23
+
24
+ That repo contains exemplars used by transit-ruby's rspec examples
25
+ (in ../transit-format/examples/0.8/simple), so then you can:
26
+
27
+ cd transit-ruby
28
+ rspec
29
+
30
+ MSG
31
+ exit
32
+ end
33
+
34
+ require 'json'
35
+ require 'rspec'
36
+ require 'wrong/adapters/rspec'
37
+ require 'transit'
38
+ require 'spec_helper-local' if File.exist?(File.expand_path('../spec_helper-local.rb', __FILE__))
39
+
40
+ RSpec.configure do |c|
41
+ c.alias_example_to :fit, :focus => true
42
+ c.filter_run_including :focus => true, :focused => true
43
+ c.run_all_when_everything_filtered = true
44
+ c.mock_with :nothing
45
+ end
46
+
47
+ ALPHA_NUM = 'abcdefghijklmnopqrstuvwxyzABCDESFHIJKLMNOPQRSTUVWXYZ_0123456789'
48
+
49
+ def random_alphanum
50
+ ALPHA_NUM[rand(ALPHA_NUM.size)]
51
+ end
52
+
53
+ def random_string(max_length=10)
54
+ l = rand(max_length) + 1
55
+ (Array.new(l).map {|x| random_alphanum}).join
56
+ end
57
+
58
+ def random_strings(max_length=10, n=100)
59
+ Array.new(n).map {random_string(max_length)}
60
+ end
61
+
62
+ def random_symbol(max_length=10)
63
+ random_string(max_length).to_sym
64
+ end
65
+
66
+ def ints_centered_on(m, n=5)
67
+ ((m-n)..(m+n)).to_a
68
+ end
69
+
70
+ def array_of_symbols(m, n=m)
71
+ seeds = (0...m).map {|i| ("key%04d" % i).to_sym}
72
+ seeds.cycle.take(n)
73
+ end
74
+
75
+ def hash_of_size(n)
76
+ Hash[array_of_symbols(n).zip((0..n).to_a)]
77
+ end
78
+
79
+ Person = Struct.new("Person", :first_name, :last_name, :birthdate)
80
+
81
+ class PersonHandler
82
+ def tag(_) "person"; end
83
+ def rep(p) {:first_name => p.first_name, :last_name => p.last_name, :birthdate => p.birthdate} end
84
+ def string_rep(p) nil end
85
+ end
@@ -0,0 +1,65 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ module Transit
18
+ describe DateTimeUtil do
19
+ describe "[to|from]_millis" do
20
+ it "round trips properly" do
21
+ 100.times do
22
+ n = DateTime.now
23
+ a = Transit::DateTimeUtil.to_millis(n)
24
+ b = Transit::DateTimeUtil.from_millis(a)
25
+ c = Transit::DateTimeUtil.to_millis(b)
26
+ d = Transit::DateTimeUtil.from_millis(c)
27
+ assert { a == c }
28
+ assert { b == d }
29
+ sleep(0.0001)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "to_millis" do
35
+ let(:time) { Time.at(1388631845) + 0.678 }
36
+
37
+ it "supports DateTime" do
38
+ assert { Transit::DateTimeUtil.to_millis(time.to_datetime) == 1388631845678 }
39
+ end
40
+
41
+ it "supports Time" do
42
+ assert { Transit::DateTimeUtil.to_millis(time) == 1388631845678 }
43
+ end
44
+
45
+ it "supports Date" do
46
+ assert { Transit::DateTimeUtil.to_millis(Date.new(2014,1,2)) == 1388620800000 }
47
+ end
48
+ end
49
+
50
+ describe "from_millis" do
51
+ it "converts to utc" do
52
+ t = DateTime.now
53
+ m = Transit::DateTimeUtil.to_millis(t)
54
+ f = Transit::DateTimeUtil.from_millis(m)
55
+ assert { f.zone == '+00:00' }
56
+ end
57
+
58
+ it "handles millis properly" do
59
+ assert { Transit::DateTimeUtil.from_millis(1388631845674) == DateTime.new(2014,1,2,3,4,5.674).new_offset(0) }
60
+ assert { Transit::DateTimeUtil.from_millis(1388631845675) == DateTime.new(2014,1,2,3,4,5.675).new_offset(0) }
61
+ assert { Transit::DateTimeUtil.from_millis(1388631845676) == DateTime.new(2014,1,2,3,4,5.676).new_offset(0) }
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,60 @@
1
+ # Copyright 2014 Cognitect. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS-IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ module Transit
18
+ describe Decoder do
19
+ def decode(o)
20
+ Decoder.new.decode(o)
21
+ end
22
+
23
+ describe "caching" do
24
+ it "decodes cacheable map keys" do
25
+ assert { decode([{"this" => "a"},{"^0" => "b"}]) == [{"this" => "a"},{"this" => "b"}] }
26
+ end
27
+
28
+ it "does not cache non-map-keys" do
29
+ assert { decode([{"a" => "~^!"},{"b" => "~^?"}]) == [{"a" => "^!"},{"b" => "^?"}] }
30
+ end
31
+ end
32
+
33
+ describe "formats" do
34
+ describe "JSON_M" do
35
+ it "converts an array starting with '^ ' to a map" do
36
+ assert { decode(["^ ", :a, :b, :c, :d]) == {:a => :b, :c => :d} }
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "unrecognized input" do
42
+ it "decodes an unrecognized string to a TaggedValue" do
43
+ assert { decode("~Unrecognized") == TaggedValue.new("U", "nrecognized") }
44
+ end
45
+ end
46
+
47
+ describe "ints" do
48
+ it "decodes n as an Integer" do
49
+ 1.upto(64).each do |pow|
50
+ assert { decode("~n#{2**pow}").kind_of? Integer }
51
+ end
52
+ end
53
+ it "decodes i as an Integer" do
54
+ 1.upto(63).each do |pow|
55
+ assert { decode("~i#{2**pow - 1}").kind_of? Integer }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,150 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright 2014 Cognitect. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS-IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # -*- coding: utf-8 -*-
17
+ require 'spec_helper'
18
+
19
+ # Assumes that the examples are in the simple_examples dir at the top.
20
+
21
+ TOP_DIR=File.dirname(File.dirname(File.dirname(__FILE__)))
22
+
23
+ ARRAY_SIMPLE = [1, 2, 3]
24
+ ARRAY_MIXED = [0, 1, 2.0, true, false, 'five', :six, Transit::Symbol.new(:seven), '~eight', nil]
25
+ ARRAY_NESTED = [ARRAY_SIMPLE, ARRAY_MIXED]
26
+ SMALL_STRINGS = ["","a","ab","abc","abcd","abcde","abcdef"]
27
+ POWERS_OF_TWO = (0..65).map {|x| 2**x}
28
+ INTERESTING_INTS = (POWERS_OF_TWO.map {|x| ints_centered_on(x, 2)}).flatten
29
+
30
+ UUIDS = [
31
+ Transit::UUID.new('5a2cbea3-e8c6-428b-b525-21239370dd55'),
32
+ Transit::UUID.new('d1dc64fa-da79-444b-9fa4-d4412f427289'),
33
+ Transit::UUID.new('501a978e-3a3e-4060-b3be-1cf2bd4b1a38'),
34
+ Transit::UUID.new('b3ba141a-a776-48e4-9fae-a28ea8571f58')]
35
+
36
+ URIS = [
37
+ Addressable::URI.parse('http://example.com'),
38
+ Addressable::URI.parse('ftp://example.com'),
39
+ Addressable::URI.parse('file:///path/to/file.txt'),
40
+ Addressable::URI.parse('http://www.詹姆斯.com/')]
41
+
42
+ DATES = [-6106017600000, 0, 946728000000, 1396909037000].map {|x| Transit::DateTimeUtil.from_millis(x)}
43
+
44
+ SYMBOLS = [:a, :ab ,:abc ,:abcd, :abcde, :a1, :b2, :c3, :a_b]
45
+ TRANSIT_SYMBOLS = SYMBOLS.map {|x| Transit::Symbol.new(x)}
46
+
47
+ SET_SIMPLE = Set.new(ARRAY_SIMPLE)
48
+ SET_MIXED = Set.new(ARRAY_MIXED)
49
+ SET_NESTED= Set.new([SET_SIMPLE, SET_MIXED])
50
+
51
+ MAP_SIMPLE = {a: 1, b: 2, c: 3}
52
+ MAP_MIXED = {:a=>1, :b=>"a string", :c=>true}
53
+ MAP_NESTED = {simple: MAP_SIMPLE, mixed: MAP_MIXED}
54
+
55
+ Exemplar = Struct.new(:name, :expected_value)
56
+
57
+ EXEMPLARS = [
58
+ Exemplar.new('nil', nil),
59
+ Exemplar.new('true', true),
60
+ Exemplar.new('false', false),
61
+ Exemplar.new('zero', 0),
62
+ Exemplar.new('one', 1),
63
+ Exemplar.new('one_string', 'hello'),
64
+ Exemplar.new('one_keyword', :hello),
65
+ Exemplar.new('one_symbol', Transit::Symbol.new('hello')),
66
+ Exemplar.new('one_date', DateTime.new(2000,1,1,12)), # Transit::DateTimeUtil.from_millis(946728000000)),
67
+ Exemplar.new("vector_simple", ARRAY_SIMPLE),
68
+ Exemplar.new("vector_empty", []),
69
+ Exemplar.new("vector_mixed", ARRAY_MIXED),
70
+ Exemplar.new("vector_nested", ARRAY_NESTED),
71
+ Exemplar.new("small_strings", SMALL_STRINGS ),
72
+ Exemplar.new("strings_tilde", SMALL_STRINGS.map{|s| "~#{s}"}),
73
+ Exemplar.new("strings_hash", SMALL_STRINGS.map{|s| "##{s}"}),
74
+ Exemplar.new("strings_hat", SMALL_STRINGS.map{|s| "^#{s}"}),
75
+ Exemplar.new("small_ints", ints_centered_on(0)),
76
+ Exemplar.new("ints", (0...128).to_a),
77
+ Exemplar.new("ints_interesting", INTERESTING_INTS),
78
+ Exemplar.new("ints_interesting_neg", INTERESTING_INTS.map {|x| -1 * x}),
79
+ Exemplar.new("doubles_small", ints_centered_on(0).map {|x| Float(x)}),
80
+ Exemplar.new("doubles_interesting", [-3.14159, 3.14159, 4E11, 2.998E8, 6.626E-34]),
81
+ Exemplar.new('one_uuid', UUIDS.first),
82
+ Exemplar.new('uuids', UUIDS),
83
+ Exemplar.new('one_uri', URIS.first),
84
+ Exemplar.new('uris', URIS),
85
+ Exemplar.new('dates_interesting', DATES),
86
+ Exemplar.new('symbols', TRANSIT_SYMBOLS),
87
+ Exemplar.new('keywords', SYMBOLS),
88
+ Exemplar.new('list_simple', ARRAY_SIMPLE),
89
+ Exemplar.new('list_empty', []),
90
+ Exemplar.new('list_mixed', ARRAY_MIXED),
91
+ Exemplar.new('list_nested', [ARRAY_SIMPLE, ARRAY_MIXED]),
92
+ Exemplar.new('set_simple', SET_SIMPLE),
93
+ Exemplar.new("set_empty", Set.new),
94
+ Exemplar.new("set_mixed", SET_MIXED),
95
+ Exemplar.new("set_nested", SET_NESTED),
96
+ Exemplar.new('map_simple', MAP_SIMPLE),
97
+ Exemplar.new('map_mixed', MAP_MIXED),
98
+ Exemplar.new('map_nested', MAP_NESTED),
99
+ Exemplar.new('map_string_keys', {"first"=>1, "second"=>2, "third"=>3}),
100
+ Exemplar.new('map_numeric_keys', {1=>"one", 2=>"two"}),
101
+ Exemplar.new('map_vector_keys', {[1,1] => 'one', [2, 2] => 'two'}),
102
+ Exemplar.new('map_10_items', hash_of_size(10)),
103
+ Exemplar.new("maps_two_char_sym_keys", [{:aa=>1, :bb=>2}, {:aa=>3, :bb=>4}, {:aa=>5, :bb=>6}]),
104
+ Exemplar.new("maps_three_char_sym_keys", [{:aaa=>1, :bbb=>2}, {:aaa=>3, :bbb=>4}, {:aaa=>5, :bbb=>6}]),
105
+ Exemplar.new("maps_four_char_sym_keys", [{:aaaa=>1, :bbbb=>2}, {:aaaa=>3, :bbbb=>4}, {:aaaa=>5, :bbbb=>6}]),
106
+ Exemplar.new("maps_two_char_string_keys", [{'aa'=>1, 'bb'=>2}, {'aa'=>3, 'bb'=>4}, {'aa'=>5, 'bb'=>6}]),
107
+ Exemplar.new("maps_three_char_string_keys", [{'aaa'=>1, 'bbb'=>2}, {'aaa'=>3, 'bbb'=>4}, {'aaa'=>5, 'bbb'=>6}]),
108
+ Exemplar.new("maps_four_char_string_keys", [{'aaaa'=>1, 'bbbb'=>2}, {'aaaa'=>3, 'bbbb'=>4}, {'aaaa'=>5, 'bbbb'=>6}]),
109
+ Exemplar.new("maps_unrecognized_keys",
110
+ [Transit::TaggedValue.new("abcde", :anything), Transit::TaggedValue.new("fghij", :"anything-else")]),
111
+ Exemplar.new("map_unrecognized_vals", {key: "~Unrecognized"}),
112
+ Exemplar.new("vector_unrecognized_vals", ["~Unrecognized"]),
113
+ Exemplar.new("vector_1935_keywords_repeated_twice", array_of_symbols(1935, 3870)),
114
+ Exemplar.new("vector_1936_keywords_repeated_twice", array_of_symbols(1936, 3872)),
115
+ Exemplar.new("vector_1937_keywords_repeated_twice", array_of_symbols(1937, 3874)),
116
+ Exemplar.new("vector_special_numbers", [Float::NAN, Float::INFINITY, -Float::INFINITY])
117
+ ]
118
+
119
+ [10, 1935, 1936, 1937].each do |i|
120
+ EXEMPLARS << Exemplar.new( "map_#{i}_nested", {f: hash_of_size(i), s: hash_of_size(i)})
121
+ end
122
+
123
+ def verify_exemplar(exemplar, type, suffix)
124
+ path = "../transit-format/examples/0.8/simple/#{exemplar.name}#{suffix}"
125
+ it "reads what we expect from #{path}" do
126
+ raise "Can't open #{path}" unless File.exist?(path)
127
+ File.open(path) do |io|
128
+ actual_value = Transit::Reader.new(type, io).read
129
+ assert { exemplar.expected_value == actual_value }
130
+ end
131
+ end
132
+ end
133
+
134
+ module Transit
135
+ shared_examples "exemplars" do |type, suffix|
136
+ EXEMPLARS.each {|ex| verify_exemplar(ex, type, suffix)}
137
+ end
138
+
139
+ describe "JSON exemplars" do
140
+ include_examples "exemplars", :json, '.json'
141
+ end
142
+
143
+ describe "JSON-VERBOSE exemplars" do
144
+ include_examples "exemplars", :json_verbose, '.verbose.json'
145
+ end
146
+
147
+ describe "MessagePack exemplars" do
148
+ include_examples "exemplars", :msgpack, '.mp'
149
+ end
150
+ end
@@ -0,0 +1,30 @@
1
+ module Transit
2
+ describe Marshaler do
3
+ it "caches non-verbose handlers" do
4
+ io = StringIO.new
5
+ first = Transit::Marshaler::Json.new(io,{}).instance_variable_get("@handlers")
6
+ second = Transit::Marshaler::Json.new(io,{}).instance_variable_get("@handlers")
7
+ third = Transit::Marshaler::MessagePack.new(io,{}).instance_variable_get("@handlers")
8
+ assert { first }
9
+ assert { first.equal?(second) }
10
+ assert { second.equal?(third) }
11
+ end
12
+
13
+ it "caches verbose handlers" do
14
+ io = StringIO.new
15
+ first = Transit::Marshaler::VerboseJson.new(io,{}).instance_variable_get("@handlers")
16
+ second = Transit::Marshaler::VerboseJson.new(io,{}).instance_variable_get("@handlers")
17
+ assert { first }
18
+ assert { first.equal?(second) }
19
+ end
20
+
21
+ it "caches verbose and non-verbose handlers separately" do
22
+ io = StringIO.new
23
+ first = Transit::Marshaler::Json.new(io,{}).instance_variable_get("@handlers")
24
+ second = Transit::Marshaler::VerboseJson.new(io,{}).instance_variable_get("@handlers")
25
+ assert { first }
26
+ assert { second }
27
+ assert { !first.equal?(second) }
28
+ end
29
+ end
30
+ end