payshares-xdr 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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +14 -0
- data/.yardopts +7 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +202 -0
- data/README.md +106 -0
- data/Rakefile +9 -0
- data/examples/enum.rb +30 -0
- data/examples/struct.rb +24 -0
- data/examples/union.rb +36 -0
- data/lib/xdr.rb +73 -0
- data/lib/xdr/array.rb +28 -0
- data/lib/xdr/bool.rb +24 -0
- data/lib/xdr/concerns/array_converter.rb +5 -0
- data/lib/xdr/concerns/converts_to_xdr.rb +67 -0
- data/lib/xdr/concerns/float_converter.rb +5 -0
- data/lib/xdr/concerns/integer_converter.rb +5 -0
- data/lib/xdr/concerns/reads_bytes.rb +8 -0
- data/lib/xdr/concerns/string_converter.rb +5 -0
- data/lib/xdr/double.rb +14 -0
- data/lib/xdr/dsl.rb +7 -0
- data/lib/xdr/dsl/enum.rb +24 -0
- data/lib/xdr/dsl/struct.rb +13 -0
- data/lib/xdr/dsl/union.rb +32 -0
- data/lib/xdr/enum.rb +48 -0
- data/lib/xdr/float.rb +14 -0
- data/lib/xdr/hyper.rb +14 -0
- data/lib/xdr/int.rb +14 -0
- data/lib/xdr/namespace.rb +26 -0
- data/lib/xdr/opaque.rb +28 -0
- data/lib/xdr/option.rb +30 -0
- data/lib/xdr/quadruple.rb +5 -0
- data/lib/xdr/rpc.rb +6 -0
- data/lib/xdr/rpc/record.rb +7 -0
- data/lib/xdr/rpc/record_reader.rb +16 -0
- data/lib/xdr/string.rb +36 -0
- data/lib/xdr/struct.rb +51 -0
- data/lib/xdr/struct_validator.rb +6 -0
- data/lib/xdr/union.rb +101 -0
- data/lib/xdr/union_validator.rb +7 -0
- data/lib/xdr/unsigned_hyper.rb +14 -0
- data/lib/xdr/unsigned_int.rb +14 -0
- data/lib/xdr/var_array.rb +38 -0
- data/lib/xdr/var_opaque.rb +36 -0
- data/lib/xdr/version.rb +3 -0
- data/lib/xdr/void.rb +14 -0
- data/payshares-xdr.gemspec +29 -0
- data/spec/lib/xdr/array_spec.rb +73 -0
- data/spec/lib/xdr/bool_spec.rb +43 -0
- data/spec/lib/xdr/concerns/converts_to_xdr_spec.rb +55 -0
- data/spec/lib/xdr/concerns/reads_bytes_spec.rb +31 -0
- data/spec/lib/xdr/double_spec.rb +38 -0
- data/spec/lib/xdr/dsl/enum_spec.rb +44 -0
- data/spec/lib/xdr/dsl/struct_spec.rb +29 -0
- data/spec/lib/xdr/dsl/union_spec.rb +22 -0
- data/spec/lib/xdr/enum_spec.rb +70 -0
- data/spec/lib/xdr/float_spec.rb +37 -0
- data/spec/lib/xdr/hyper_spec.rb +40 -0
- data/spec/lib/xdr/int_spec.rb +40 -0
- data/spec/lib/xdr/opaque_spec.rb +36 -0
- data/spec/lib/xdr/option_spec.rb +36 -0
- data/spec/lib/xdr/quadruple_spec.rb +14 -0
- data/spec/lib/xdr/rpc/record_reader_spec.rb +27 -0
- data/spec/lib/xdr/string_spec.rb +41 -0
- data/spec/lib/xdr/struct_spec.rb +101 -0
- data/spec/lib/xdr/union_spec.rb +248 -0
- data/spec/lib/xdr/unsigned_hyper_spec.rb +36 -0
- data/spec/lib/xdr/unsigned_int_spec.rb +36 -0
- data/spec/lib/xdr/var_array_spec.rb +71 -0
- data/spec/lib/xdr/var_opaque_spec.rb +43 -0
- data/spec/lib/xdr/void_spec.rb +46 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/matchers/eq_bytes.rb +6 -0
- metadata +257 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe XDR::Hyper, ".read" do
|
5
|
+
|
6
|
+
it "decodes values correctly" do
|
7
|
+
expect(read("\x00\x00\x00\x00\x00\x00\x00\x00")).to eq(0)
|
8
|
+
expect(read("\x00\x00\x00\x00\x00\x00\x00\x01")).to eq(1)
|
9
|
+
expect(read("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF")).to eq(-1)
|
10
|
+
expect(read("\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF")).to eq(2**63 - 1)
|
11
|
+
expect(read("\x80\x00\x00\x00\x00\x00\x00\x00")).to eq(-(2**63))
|
12
|
+
end
|
13
|
+
|
14
|
+
def read(str)
|
15
|
+
io = StringIO.new(str)
|
16
|
+
subject.read(io)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe XDR::Hyper, ".write" do
|
21
|
+
|
22
|
+
it "decodes values correctly" do
|
23
|
+
expect(write 0).to eq_bytes("\x00\x00\x00\x00\x00\x00\x00\x00")
|
24
|
+
expect(write 1).to eq_bytes("\x00\x00\x00\x00\x00\x00\x00\x01")
|
25
|
+
expect(write -1).to eq_bytes("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF")
|
26
|
+
expect(write 2**63 - 1).to eq_bytes("\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF")
|
27
|
+
expect(write -(2**63)).to eq_bytes("\x80\x00\x00\x00\x00\x00\x00\x00")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raises WriteError when an Integer isn't passed" do
|
31
|
+
expect{ write 1.0 }.to raise_error(XDR::WriteError)
|
32
|
+
expect{ write "hi" }.to raise_error(XDR::WriteError)
|
33
|
+
end
|
34
|
+
|
35
|
+
def write(val)
|
36
|
+
io = StringIO.new()
|
37
|
+
subject.write(val, io)
|
38
|
+
io.string
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe XDR::Int, ".read" do
|
5
|
+
|
6
|
+
it "decodes values correctly" do
|
7
|
+
expect(read("\x00\x00\x00\x00")).to eq(0)
|
8
|
+
expect(read("\x00\x00\x00\x01")).to eq(1)
|
9
|
+
expect(read("\xFF\xFF\xFF\xFF")).to eq(-1)
|
10
|
+
expect(read("\x7F\xFF\xFF\xFF")).to eq(2**31 - 1)
|
11
|
+
expect(read("\x80\x00\x00\x00")).to eq(-(2**31))
|
12
|
+
end
|
13
|
+
|
14
|
+
def read(str)
|
15
|
+
io = StringIO.new(str)
|
16
|
+
subject.read(io)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe XDR::Int, ".write" do
|
21
|
+
|
22
|
+
it "decodes values correctly" do
|
23
|
+
expect(write 0).to eq_bytes("\x00\x00\x00\x00")
|
24
|
+
expect(write 1).to eq_bytes("\x00\x00\x00\x01")
|
25
|
+
expect(write -1).to eq_bytes("\xFF\xFF\xFF\xFF")
|
26
|
+
expect(write 2**31 - 1).to eq_bytes("\x7F\xFF\xFF\xFF")
|
27
|
+
expect(write -(2**31)).to eq_bytes("\x80\x00\x00\x00")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raises WriteError when an Integer isn't passed" do
|
31
|
+
expect{ write 1.0 }.to raise_error(XDR::WriteError)
|
32
|
+
expect{ write "hi" }.to raise_error(XDR::WriteError)
|
33
|
+
end
|
34
|
+
|
35
|
+
def write(val)
|
36
|
+
io = StringIO.new()
|
37
|
+
subject.write(val, io)
|
38
|
+
io.string
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe XDR::Opaque, "#read" do
|
5
|
+
subject{ XDR::Opaque.new(3) }
|
6
|
+
|
7
|
+
it "decodes values correctly" do
|
8
|
+
expect(read("\x00\x00\x00\x00")).to eq("\x00\x00\x00")
|
9
|
+
expect(read("\x00\x01\x00\x00")).to eq("\x00\x01\x00")
|
10
|
+
end
|
11
|
+
|
12
|
+
def read(str)
|
13
|
+
io = StringIO.new(str)
|
14
|
+
subject.read(io)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe XDR::Opaque, "#write" do
|
19
|
+
subject{ XDR::Opaque.new(3) }
|
20
|
+
|
21
|
+
it "encodes values correctly" do
|
22
|
+
expect(write("123")).to eq("123\x00")
|
23
|
+
expect(write("124")).to eq("124\x00")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "raises a WriteError if the value is not the correct length" do
|
27
|
+
expect{ write("1234") }.to raise_error(XDR::WriteError)
|
28
|
+
expect{ write("12") }.to raise_error(XDR::WriteError)
|
29
|
+
end
|
30
|
+
|
31
|
+
def write(val)
|
32
|
+
io = StringIO.new()
|
33
|
+
subject.write(val, io)
|
34
|
+
io.string
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe XDR::Option, ".read" do
|
5
|
+
subject{ XDR::Option[XDR::Int] }
|
6
|
+
|
7
|
+
it "decodes values correctly" do
|
8
|
+
expect(read "\x00\x00\x00\x01\x00\x00\x00\x00" ).to eq(0)
|
9
|
+
expect(read "\x00\x00\x00\x00" ).to eq(nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
def read(str)
|
13
|
+
io = StringIO.new(str)
|
14
|
+
subject.read(io)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe XDR::Option, ".write" do
|
19
|
+
subject{ XDR::Option[XDR::Int] }
|
20
|
+
|
21
|
+
it "decodes values correctly" do
|
22
|
+
expect(write 0).to eq_bytes("\x00\x00\x00\x01\x00\x00\x00\x00")
|
23
|
+
expect(write nil).to eq_bytes("\x00\x00\x00\x00")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "raises WriteError when the provided value is non-nil bust invalid for the child type" do
|
27
|
+
expect{ write 1.0 }.to raise_error(XDR::WriteError)
|
28
|
+
expect{ write "hi" }.to raise_error(XDR::WriteError)
|
29
|
+
end
|
30
|
+
|
31
|
+
def write(val)
|
32
|
+
io = StringIO.new()
|
33
|
+
subject.write(val, io)
|
34
|
+
io.string
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe XDR::Quadruple, ".read" do
|
5
|
+
let(:zero){ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
|
6
|
+
it "cannot decode values yet" do
|
7
|
+
expect{ read zero }.to raise_error(NotImplementedError)
|
8
|
+
end
|
9
|
+
|
10
|
+
def read(str)
|
11
|
+
io = StringIO.new(str)
|
12
|
+
subject.read(io)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe XDR::RPC::RecordReader, "#read" do
|
4
|
+
|
5
|
+
it "decodes values correctly" do
|
6
|
+
empty_record = read "\x00\x00\x00\x00"
|
7
|
+
last_record = read "\x80\x00\x00\x02\x00\x00"
|
8
|
+
|
9
|
+
expect(empty_record).to_not be_last
|
10
|
+
expect(empty_record.length).to eq(0)
|
11
|
+
expect(empty_record.content.string).to eq("")
|
12
|
+
|
13
|
+
expect(last_record).to be_last
|
14
|
+
expect(last_record.length).to eq(2)
|
15
|
+
expect(last_record.content.string).to eq("\x00\x00")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "raises EOFError the byte stream isn't large enough" do
|
19
|
+
expect{ read "\x00\x00\x00\x01" }.to raise_error(EOFError)
|
20
|
+
expect{ read "\x00\x00\x00\x08\x00\x00\x00\x01" }.to raise_error(EOFError)
|
21
|
+
end
|
22
|
+
|
23
|
+
def read(str)
|
24
|
+
io = StringIO.new(str)
|
25
|
+
subject.read(io)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe XDR::String, "#read" do
|
5
|
+
subject{ XDR::String.new(3) }
|
6
|
+
|
7
|
+
it "decodes values correctly" do
|
8
|
+
expect(read("\x00\x00\x00\x00")).to eq("")
|
9
|
+
expect(read("\x00\x00\x00\x01h\x00\x00\x00")).to eq("h")
|
10
|
+
expect(read("\x00\x00\x00\x02hi\x00\x00")).to eq("hi")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "raises a ReadError when the encoded length is greater than the allowed max" do
|
14
|
+
expect{ read "\x00\x00\x00\x04hiya" }.to raise_error(XDR::ReadError)
|
15
|
+
end
|
16
|
+
|
17
|
+
def read(str)
|
18
|
+
io = StringIO.new(str)
|
19
|
+
subject.read(io)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe XDR::String, "#write" do
|
24
|
+
subject{ XDR::String[2] }
|
25
|
+
|
26
|
+
it "encodes values correctly" do
|
27
|
+
expect(write("")).to eq("\x00\x00\x00\x00")
|
28
|
+
expect(write("h")).to eq("\x00\x00\x00\x01h\x00\x00\x00")
|
29
|
+
expect(write("hi")).to eq("\x00\x00\x00\x02hi\x00\x00")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "raises a WriteError when the provided string is too long" do
|
33
|
+
expect{ write "123" }.to raise_error(XDR::WriteError)
|
34
|
+
end
|
35
|
+
|
36
|
+
def write(val)
|
37
|
+
io = StringIO.new()
|
38
|
+
subject.write(val, io)
|
39
|
+
io.string
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module StructSpec
|
4
|
+
class SampleError < XDR::Struct
|
5
|
+
attribute :code, XDR::Int
|
6
|
+
attribute :msg, XDR::String[100]
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
# class SampleEnvelope < XDR::Struct
|
11
|
+
# attribute :body, XDR::VarOpaque[]
|
12
|
+
# attribute :sigs, XDR::VarArray[XDR::Opaque[32]]
|
13
|
+
# end
|
14
|
+
|
15
|
+
# class SampleOptions < XDR::Struct
|
16
|
+
# attribute :limit, XDR::Option[XDR::Int]
|
17
|
+
# attribute :subscribed, XDR::Option[XDR::Bool]
|
18
|
+
# end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
describe XDR::Struct, "creation" do
|
23
|
+
let(:args){ {} }
|
24
|
+
subject{ StructSpec::SampleError.new(args) }
|
25
|
+
|
26
|
+
context "with no args" do
|
27
|
+
it "creates an instance" do
|
28
|
+
expect(subject).to be_a(StructSpec::SampleError)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "with valid args" do
|
33
|
+
let(:args){{code: 3, msg: "It broke!"}}
|
34
|
+
|
35
|
+
it "assigns values correctly" do
|
36
|
+
expect(subject.code).to eq(3)
|
37
|
+
expect(subject.msg).to eq("It broke!")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe XDR::Struct, "attribute assignment" do
|
43
|
+
subject{ StructSpec::SampleError.new }
|
44
|
+
|
45
|
+
it "roundtrips correctly" do
|
46
|
+
expect(subject.code).to be_nil
|
47
|
+
expect(subject.msg).to be_nil
|
48
|
+
|
49
|
+
subject.code = 10
|
50
|
+
subject.msg = "busted"
|
51
|
+
|
52
|
+
expect(subject.code).to eq(10)
|
53
|
+
expect(subject.msg).to eq("busted")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
describe XDR::Struct, "valid?"
|
59
|
+
describe XDR::Struct, "optional members"
|
60
|
+
|
61
|
+
describe XDR::Struct, "#to_xdr" do
|
62
|
+
subject{ StructSpec::SampleError.new({code: 3, msg: "It broke!"}) }
|
63
|
+
let(:result){ subject.to_xdr }
|
64
|
+
|
65
|
+
it "serialized each field in order" do
|
66
|
+
expect(result[0...4]).to eq("\x00\x00\x00\x03")
|
67
|
+
expect(result[4...8]).to eq([9].pack("l>"))
|
68
|
+
expect(result[8..-1]).to eq("It broke!\x00\x00\x00")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "raises an exception if the struct is not valid" do
|
72
|
+
subject.code = nil
|
73
|
+
expect{ result }.to raise_error(XDR::WriteError)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "produces hex" do
|
77
|
+
result = subject.to_xdr(:hex)
|
78
|
+
expect(result).to eq("000000030000000949742062726f6b6521000000")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "produces base64" do
|
82
|
+
result = subject.to_xdr(:base64)
|
83
|
+
expect(result).to eq("AAAAAwAAAAlJdCBicm9rZSEAAAA=")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
describe XDR::Struct, ".read" do
|
89
|
+
subject{ StructSpec::SampleError }
|
90
|
+
let(:result){ read "\x00\x00\x00\x01\x00\x00\x00\x0812345678" }
|
91
|
+
it "decodes values correctly" do
|
92
|
+
expect( result ).to be_a(subject)
|
93
|
+
expect( result.code ).to eq(1)
|
94
|
+
expect( result.msg ).to eq("12345678")
|
95
|
+
end
|
96
|
+
|
97
|
+
def read(str)
|
98
|
+
io = StringIO.new(str)
|
99
|
+
subject.read(io)
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe XDR::Union, ".read" do
|
4
|
+
|
5
|
+
subject{ UnionSpec::Result }
|
6
|
+
let(:result){ subject.read(bytes) }
|
7
|
+
|
8
|
+
context "with a void arm encoded" do
|
9
|
+
let(:bytes){ StringIO.new "\x00\x00\x00\x00" }
|
10
|
+
|
11
|
+
it "decodes correctly" do
|
12
|
+
expect(result).to be_a(UnionSpec::Result)
|
13
|
+
expect(result.switch).to eq(UnionSpec::ResultType.ok)
|
14
|
+
expect(result.arm).to be_nil
|
15
|
+
expect(result.get).to be_nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with a non-void arm encoded" do
|
20
|
+
let(:bytes){ StringIO.new "\x00\x00\x00\x01\x00\x00\x00\x0812345678" }
|
21
|
+
|
22
|
+
it "decodes correctly" do
|
23
|
+
expect(result).to be_a(UnionSpec::Result)
|
24
|
+
expect(result.switch).to eq(UnionSpec::ResultType.error)
|
25
|
+
expect(result.arm).to eq(:message)
|
26
|
+
expect(result.get).to eq("12345678")
|
27
|
+
expect(result.message!).to eq("12345678")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with a default arm encoded" do
|
32
|
+
let(:bytes){ StringIO.new "\x00\x00\x00\x02" }
|
33
|
+
|
34
|
+
it "decodes correctly" do
|
35
|
+
expect(result).to be_a(UnionSpec::Result)
|
36
|
+
expect(result.switch).to eq(UnionSpec::ResultType.nonsense)
|
37
|
+
expect(result.arm).to be_nil
|
38
|
+
expect(result.get).to be_nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with a switch that is not a member of the switch_type" do
|
43
|
+
let(:bytes){ StringIO.new "\x00\x00\x00\x10" }
|
44
|
+
|
45
|
+
it "raises EnumValueError" do
|
46
|
+
expect{ result }.to raise_error XDR::EnumValueError
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with a invalid arm encoded" do
|
51
|
+
let(:bytes){ StringIO.new "\x00\x00\x00\x02" }
|
52
|
+
subject{ UnionSpec::UnforfivingResult }
|
53
|
+
|
54
|
+
it "raises InvalidSwitchError" do
|
55
|
+
expect{ result }.to raise_error XDR::InvalidSwitchError
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe XDR::Union, "#attribute!" do
|
62
|
+
subject{ UnionSpec::Result.new(:ok) }
|
63
|
+
|
64
|
+
it "raises an ArmNotSetError when the attribute requested has not been populated" do
|
65
|
+
expect{ subject.message! }.to raise_error XDR::ArmNotSetError
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns the underyling value when the arm is populated" do
|
69
|
+
subject.set(:error, "it all went bad")
|
70
|
+
expect(subject.message!).to eq("it all went bad")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe XDR::Union, "#set" do
|
75
|
+
subject{ UnionSpec::ManyTypes.new }
|
76
|
+
|
77
|
+
it "sets the underlying member variables correctly" do
|
78
|
+
subject.set(:fixnum, 3)
|
79
|
+
expect(subject.switch).to eq(UnionSpec::Types.fixnum)
|
80
|
+
expect(subject.arm).to eq(:fixnum)
|
81
|
+
expect(subject.value).to eq(3)
|
82
|
+
|
83
|
+
subject.set(:float, 1.0)
|
84
|
+
expect(subject.switch).to eq(UnionSpec::Types.float)
|
85
|
+
expect(subject.arm).to eq(:float)
|
86
|
+
expect(subject.value).to eq(1.0)
|
87
|
+
|
88
|
+
subject.set(:array, [1,2])
|
89
|
+
expect(subject.switch).to eq(UnionSpec::Types.array)
|
90
|
+
expect(subject.arm).to eq(:array)
|
91
|
+
expect(subject.value).to eq([1,2])
|
92
|
+
|
93
|
+
subject.set(:bool, true)
|
94
|
+
expect(subject.switch).to eq(UnionSpec::Types.bool)
|
95
|
+
expect(subject.arm).to eq(:bool)
|
96
|
+
expect(subject.value).to eq(true)
|
97
|
+
|
98
|
+
subject.set(:optional, nil)
|
99
|
+
expect(subject.switch).to eq(UnionSpec::Types.optional)
|
100
|
+
expect(subject.arm).to eq(:optional)
|
101
|
+
expect(subject.value).to eq(nil)
|
102
|
+
|
103
|
+
subject.set(:optional, 3)
|
104
|
+
expect(subject.switch).to eq(UnionSpec::Types.optional)
|
105
|
+
expect(subject.arm).to eq(:optional)
|
106
|
+
expect(subject.value).to eq(3)
|
107
|
+
|
108
|
+
subject.set(:complex, UnionSpec::Result.new(:ok))
|
109
|
+
expect(subject.switch).to eq(UnionSpec::Types.complex)
|
110
|
+
expect(subject.arm).to eq(:complex)
|
111
|
+
expect(subject.value).to be_a(UnionSpec::Result)
|
112
|
+
|
113
|
+
subject.set(:void)
|
114
|
+
expect(subject.switch).to eq(UnionSpec::Types.void)
|
115
|
+
expect(subject.arm).to eq(nil)
|
116
|
+
expect(subject.value).to eq(nil)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "raises InvalidValueError if the value provided is not compatible with the selected arm" do
|
120
|
+
expect{ subject.set(:fixnum, 3.0) }.to raise_error(XDR::InvalidValueError)
|
121
|
+
expect{ subject.set(:fixnum, "hi") }.to raise_error(XDR::InvalidValueError)
|
122
|
+
expect{ subject.set(:fixnum, []) }.to raise_error(XDR::InvalidValueError)
|
123
|
+
expect{ subject.set(:fixnum, true) }.to raise_error(XDR::InvalidValueError)
|
124
|
+
|
125
|
+
expect{ subject.set(:float, 3) }.to raise_error(XDR::InvalidValueError)
|
126
|
+
expect{ subject.set(:float, "hi") }.to raise_error(XDR::InvalidValueError)
|
127
|
+
expect{ subject.set(:float, []) }.to raise_error(XDR::InvalidValueError)
|
128
|
+
expect{ subject.set(:float, true) }.to raise_error(XDR::InvalidValueError)
|
129
|
+
|
130
|
+
expect{ subject.set(:array, 3) }.to raise_error(XDR::InvalidValueError)
|
131
|
+
expect{ subject.set(:array, "hi") }.to raise_error(XDR::InvalidValueError)
|
132
|
+
expect{ subject.set(:array, 3.0) }.to raise_error(XDR::InvalidValueError)
|
133
|
+
expect{ subject.set(:array, true) }.to raise_error(XDR::InvalidValueError)
|
134
|
+
|
135
|
+
expect{ subject.set(:bool, 3) }.to raise_error(XDR::InvalidValueError)
|
136
|
+
expect{ subject.set(:bool, "hi") }.to raise_error(XDR::InvalidValueError)
|
137
|
+
expect{ subject.set(:bool, 3.0) }.to raise_error(XDR::InvalidValueError)
|
138
|
+
expect{ subject.set(:bool, []) }.to raise_error(XDR::InvalidValueError)
|
139
|
+
|
140
|
+
expect{ subject.set(:optional, "hi") }.to raise_error(XDR::InvalidValueError)
|
141
|
+
expect{ subject.set(:optional, 3.0) }.to raise_error(XDR::InvalidValueError)
|
142
|
+
expect{ subject.set(:optional, []) }.to raise_error(XDR::InvalidValueError)
|
143
|
+
expect{ subject.set(:optional, true) }.to raise_error(XDR::InvalidValueError)
|
144
|
+
|
145
|
+
expect{ subject.set(:complex, 3) }.to raise_error(XDR::InvalidValueError)
|
146
|
+
expect{ subject.set(:complex, "hi") }.to raise_error(XDR::InvalidValueError)
|
147
|
+
expect{ subject.set(:complex, 3.0) }.to raise_error(XDR::InvalidValueError)
|
148
|
+
expect{ subject.set(:complex, []) }.to raise_error(XDR::InvalidValueError)
|
149
|
+
expect{ subject.set(:complex, true) }.to raise_error(XDR::InvalidValueError)
|
150
|
+
|
151
|
+
expect{ subject.set(:void, 3) }.to raise_error(XDR::InvalidValueError)
|
152
|
+
expect{ subject.set(:void, "hi") }.to raise_error(XDR::InvalidValueError)
|
153
|
+
expect{ subject.set(:void, 3.0) }.to raise_error(XDR::InvalidValueError)
|
154
|
+
expect{ subject.set(:void, []) }.to raise_error(XDR::InvalidValueError)
|
155
|
+
expect{ subject.set(:void, true) }.to raise_error(XDR::InvalidValueError)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "raises InvalidSwitchError if the provided switch is not compatible with the switch_type" do
|
159
|
+
expect{ subject.set 4 }.to raise_error(XDR::InvalidSwitchError)
|
160
|
+
expect{ subject.set "hi" }.to raise_error(XDR::InvalidSwitchError)
|
161
|
+
expect{ subject.set UnionSpec::ResultType.ok }.to raise_error(XDR::InvalidSwitchError)
|
162
|
+
end
|
163
|
+
|
164
|
+
context "when the union does not have a default switch" do
|
165
|
+
subject{ UnionSpec::UnforfivingResult.new }
|
166
|
+
|
167
|
+
#TODO
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe XDR::Union, "#switch" do
|
172
|
+
subject{ UnionSpec::Result.new }
|
173
|
+
|
174
|
+
it "reflects the set switch" do
|
175
|
+
subject.set :ok
|
176
|
+
expect( subject.switch ).to eq(UnionSpec::ResultType.ok)
|
177
|
+
subject.set :error, "broke"
|
178
|
+
expect( subject.switch ).to eq(UnionSpec::ResultType.error)
|
179
|
+
subject.set :nonsense
|
180
|
+
expect( subject.switch ).to eq(UnionSpec::ResultType.nonsense)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "is aliased to the union's switch_name" do
|
184
|
+
subject.set :ok
|
185
|
+
expect( subject.type ).to eq(subject.switch)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
module UnionSpec
|
190
|
+
class ResultType < XDR::Enum
|
191
|
+
member :ok, 0
|
192
|
+
member :error, 1
|
193
|
+
member :nonsense, 2
|
194
|
+
|
195
|
+
seal
|
196
|
+
end
|
197
|
+
|
198
|
+
class Types < XDR::Enum
|
199
|
+
member :fixnum, 0
|
200
|
+
member :float, 1
|
201
|
+
member :array, 2
|
202
|
+
member :bool, 3
|
203
|
+
member :optional, 4
|
204
|
+
member :complex, 5
|
205
|
+
member :void, 6
|
206
|
+
|
207
|
+
seal
|
208
|
+
end
|
209
|
+
|
210
|
+
class Result < XDR::Union
|
211
|
+
switch_on ResultType, :type
|
212
|
+
|
213
|
+
switch ResultType.ok
|
214
|
+
switch ResultType.error, :message
|
215
|
+
switch :default
|
216
|
+
|
217
|
+
attribute :message, XDR::String[]
|
218
|
+
end
|
219
|
+
|
220
|
+
class UnforfivingResult < XDR::Union
|
221
|
+
switch_on ResultType, :type
|
222
|
+
|
223
|
+
switch :ok
|
224
|
+
switch :error, :message
|
225
|
+
|
226
|
+
attribute :message, XDR::String[]
|
227
|
+
end
|
228
|
+
|
229
|
+
class ManyTypes < XDR::Union
|
230
|
+
switch_on Types, :type
|
231
|
+
|
232
|
+
switch Types.fixnum, :fixnum
|
233
|
+
switch Types.float, :float
|
234
|
+
switch Types.array, :array
|
235
|
+
switch Types.bool, :bool
|
236
|
+
switch Types.optional, :optional
|
237
|
+
switch Types.complex, :complex
|
238
|
+
switch Types.void
|
239
|
+
|
240
|
+
|
241
|
+
attribute :fixnum, XDR::Hyper
|
242
|
+
attribute :float, XDR::Double
|
243
|
+
attribute :array, XDR::Array[XDR::Int, 2]
|
244
|
+
attribute :bool, XDR::Bool
|
245
|
+
attribute :optional, XDR::Option[XDR::Int]
|
246
|
+
attribute :complex, Result
|
247
|
+
end
|
248
|
+
end
|