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.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.travis.yml +14 -0
  4. data/.yardopts +7 -0
  5. data/Gemfile +4 -0
  6. data/Guardfile +5 -0
  7. data/LICENSE.txt +202 -0
  8. data/README.md +106 -0
  9. data/Rakefile +9 -0
  10. data/examples/enum.rb +30 -0
  11. data/examples/struct.rb +24 -0
  12. data/examples/union.rb +36 -0
  13. data/lib/xdr.rb +73 -0
  14. data/lib/xdr/array.rb +28 -0
  15. data/lib/xdr/bool.rb +24 -0
  16. data/lib/xdr/concerns/array_converter.rb +5 -0
  17. data/lib/xdr/concerns/converts_to_xdr.rb +67 -0
  18. data/lib/xdr/concerns/float_converter.rb +5 -0
  19. data/lib/xdr/concerns/integer_converter.rb +5 -0
  20. data/lib/xdr/concerns/reads_bytes.rb +8 -0
  21. data/lib/xdr/concerns/string_converter.rb +5 -0
  22. data/lib/xdr/double.rb +14 -0
  23. data/lib/xdr/dsl.rb +7 -0
  24. data/lib/xdr/dsl/enum.rb +24 -0
  25. data/lib/xdr/dsl/struct.rb +13 -0
  26. data/lib/xdr/dsl/union.rb +32 -0
  27. data/lib/xdr/enum.rb +48 -0
  28. data/lib/xdr/float.rb +14 -0
  29. data/lib/xdr/hyper.rb +14 -0
  30. data/lib/xdr/int.rb +14 -0
  31. data/lib/xdr/namespace.rb +26 -0
  32. data/lib/xdr/opaque.rb +28 -0
  33. data/lib/xdr/option.rb +30 -0
  34. data/lib/xdr/quadruple.rb +5 -0
  35. data/lib/xdr/rpc.rb +6 -0
  36. data/lib/xdr/rpc/record.rb +7 -0
  37. data/lib/xdr/rpc/record_reader.rb +16 -0
  38. data/lib/xdr/string.rb +36 -0
  39. data/lib/xdr/struct.rb +51 -0
  40. data/lib/xdr/struct_validator.rb +6 -0
  41. data/lib/xdr/union.rb +101 -0
  42. data/lib/xdr/union_validator.rb +7 -0
  43. data/lib/xdr/unsigned_hyper.rb +14 -0
  44. data/lib/xdr/unsigned_int.rb +14 -0
  45. data/lib/xdr/var_array.rb +38 -0
  46. data/lib/xdr/var_opaque.rb +36 -0
  47. data/lib/xdr/version.rb +3 -0
  48. data/lib/xdr/void.rb +14 -0
  49. data/payshares-xdr.gemspec +29 -0
  50. data/spec/lib/xdr/array_spec.rb +73 -0
  51. data/spec/lib/xdr/bool_spec.rb +43 -0
  52. data/spec/lib/xdr/concerns/converts_to_xdr_spec.rb +55 -0
  53. data/spec/lib/xdr/concerns/reads_bytes_spec.rb +31 -0
  54. data/spec/lib/xdr/double_spec.rb +38 -0
  55. data/spec/lib/xdr/dsl/enum_spec.rb +44 -0
  56. data/spec/lib/xdr/dsl/struct_spec.rb +29 -0
  57. data/spec/lib/xdr/dsl/union_spec.rb +22 -0
  58. data/spec/lib/xdr/enum_spec.rb +70 -0
  59. data/spec/lib/xdr/float_spec.rb +37 -0
  60. data/spec/lib/xdr/hyper_spec.rb +40 -0
  61. data/spec/lib/xdr/int_spec.rb +40 -0
  62. data/spec/lib/xdr/opaque_spec.rb +36 -0
  63. data/spec/lib/xdr/option_spec.rb +36 -0
  64. data/spec/lib/xdr/quadruple_spec.rb +14 -0
  65. data/spec/lib/xdr/rpc/record_reader_spec.rb +27 -0
  66. data/spec/lib/xdr/string_spec.rb +41 -0
  67. data/spec/lib/xdr/struct_spec.rb +101 -0
  68. data/spec/lib/xdr/union_spec.rb +248 -0
  69. data/spec/lib/xdr/unsigned_hyper_spec.rb +36 -0
  70. data/spec/lib/xdr/unsigned_int_spec.rb +36 -0
  71. data/spec/lib/xdr/var_array_spec.rb +71 -0
  72. data/spec/lib/xdr/var_opaque_spec.rb +43 -0
  73. data/spec/lib/xdr/void_spec.rb +46 -0
  74. data/spec/spec_helper.rb +15 -0
  75. data/spec/support/matchers/eq_bytes.rb +6 -0
  76. metadata +257 -0
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe XDR::Array, "#read" do
4
+ let(:empty) { XDR::Array[XDR::Int, 0] }
5
+ let(:one) { XDR::Array[XDR::Int, 1] }
6
+ let(:many) { XDR::Array[XDR::Int, 2] }
7
+
8
+ it "decodes values correctly" do
9
+ expect( read empty, "" ).to eq([])
10
+ expect( read empty, "\x00\x00\x00\x00" ).to eq([])
11
+ expect( read one, "\x00\x00\x00\x00" ).to eq([0])
12
+ expect( read one, "\x00\x00\x00\x01" ).to eq([1])
13
+ expect( read many, "\x00\x00\x00\x00\x00\x00\x00\x01" ).to eq([0, 1])
14
+ expect( read many, "\x00\x00\x00\x01\x00\x00\x00\x01" ).to eq([1, 1])
15
+ end
16
+
17
+ it "raises EOFError the byte stream isn't large enough" do
18
+ expect{ read many, "\x00\x00\x00\x00" }.to raise_error(EOFError)
19
+ end
20
+
21
+ def read(reader, str)
22
+ io = StringIO.new(str)
23
+ reader.read(io)
24
+ end
25
+ end
26
+
27
+ describe XDR::Array, "#write" do
28
+ subject{ XDR::Array[XDR::Int, 2] }
29
+
30
+ it "encodes values correctly" do
31
+ expect(write [1,2]).to eq("\x00\x00\x00\x01\x00\x00\x00\x02")
32
+ expect(write [1,4]).to eq("\x00\x00\x00\x01\x00\x00\x00\x04")
33
+ end
34
+
35
+ it "raises a WriteError if the value is not the correct length" do
36
+ expect{ write nil }.to raise_error(XDR::WriteError)
37
+ expect{ write [] }.to raise_error(XDR::WriteError)
38
+ expect{ write [1] }.to raise_error(XDR::WriteError)
39
+ expect{ write [1,2,3] }.to raise_error(XDR::WriteError)
40
+ end
41
+
42
+ it "raises a WriteError if a child element is of the wrong type" do
43
+ expect{ write [nil] }.to raise_error(XDR::WriteError)
44
+ expect{ write ["hi"] }.to raise_error(XDR::WriteError)
45
+ expect{ write [1,2,"hi"] }.to raise_error(XDR::WriteError)
46
+ end
47
+
48
+ def write(val)
49
+ io = StringIO.new()
50
+ subject.write(val, io)
51
+ io.string
52
+ end
53
+ end
54
+
55
+ describe XDR::Array, "#valid?" do
56
+ subject{ XDR::Array[XDR::Int, 2] }
57
+
58
+ it "rejects an empty array" do
59
+ expect(subject.valid?([])).to be_falsey
60
+ end
61
+
62
+ it "accepts a filled array provided each element passes the child_type validator" do
63
+ expect(subject.valid?([1,2])).to be_truthy
64
+ expect(subject.valid?([2,3])).to be_truthy
65
+ end
66
+
67
+ it "rejects a filled array if any element is rejected by the child_type validator" do
68
+ expect(subject.valid?(["hello", "hello"])).to be_falsey
69
+ expect(subject.valid?([1, "hello"])).to be_falsey
70
+ expect(subject.valid?([1, nil])).to be_falsey
71
+ expect(subject.valid?([nil])).to be_falsey
72
+ end
73
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe XDR::Bool, ".read" do
4
+ subject{ XDR::Bool }
5
+
6
+ let(:false_s) { "\x00\x00\x00\x00" }
7
+ let(:true_s) { "\x00\x00\x00\x01" }
8
+ let(:two) { "\x00\x00\x00\x02" }
9
+
10
+ it "decodes values correctly" do
11
+ expect(read(false_s)).to eq(false)
12
+ expect(read(true_s)).to eq(true)
13
+ end
14
+
15
+ it "raises ReadError if the decoded value is not 0 or 1" do
16
+ expect{ read two }.to raise_error XDR::ReadError
17
+ end
18
+
19
+ def read(str)
20
+ io = StringIO.new(str)
21
+ subject.read(io)
22
+ end
23
+ end
24
+
25
+ describe XDR::Bool, ".write" do
26
+ subject{ XDR::Bool }
27
+
28
+ it "encodes values correctly" do
29
+ expect(write false).to eq("\x00\x00\x00\x00")
30
+ expect(write true).to eq("\x00\x00\x00\x01")
31
+ end
32
+
33
+ it "raises WriteError if the value is boolean" do
34
+ expect{ write 1 }.to raise_error XDR::WriteError
35
+ expect{ write "hello" }.to raise_error XDR::WriteError
36
+ end
37
+
38
+ def write(val)
39
+ io = StringIO.new()
40
+ subject.write(val, io)
41
+ io.string
42
+ end
43
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe XDR::Concerns::ConvertsToXDR do
4
+ subject{ UnimplementedConvertible.new }
5
+
6
+ it "requires an implementation of #read" do
7
+ expect{ subject.read(StringIO.new) }.to raise_error(NotImplementedError)
8
+ end
9
+
10
+ it "requires an implementation of #write" do
11
+ expect{ subject.write(3, StringIO.new) }.to raise_error(NotImplementedError)
12
+ end
13
+
14
+ it "requires an implementation of #valid?" do
15
+ expect{ subject.valid?(3) }.to raise_error(NotImplementedError)
16
+ end
17
+ end
18
+
19
+ describe XDR::Concerns::ConvertsToXDR, "#to_xdr" do
20
+ subject{ ImplementedConvertible.new }
21
+
22
+ it "calls through to write" do
23
+ expect(subject).to receive(:write).with("hiya", kind_of(StringIO))
24
+ subject.to_xdr("hiya")
25
+ end
26
+ end
27
+
28
+ describe XDR::Concerns::ConvertsToXDR, "#from_xdr" do
29
+ subject{ ImplementedConvertible.new }
30
+
31
+ it "calls through to write" do
32
+ expect(subject).to receive(:read).with(kind_of(StringIO))
33
+ subject.from_xdr("hiya")
34
+ end
35
+ end
36
+
37
+ class UnimplementedConvertible
38
+ include XDR::Concerns::ConvertsToXDR
39
+ end
40
+
41
+ class ImplementedConvertible
42
+ include XDR::Concerns::ConvertsToXDR
43
+
44
+ def read(io)
45
+ read_bytes(4)
46
+ end
47
+
48
+ def write(val, io)
49
+ io.write(val)
50
+ end
51
+
52
+ def valid?(val)
53
+ true
54
+ end
55
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ class TestReader
4
+ include XDR::Concerns::ReadsBytes
5
+ public :read_bytes
6
+ end
7
+
8
+
9
+ describe XDR::Concerns::ReadsBytes, "#read_bytes" do
10
+ subject{ TestReader.new }
11
+
12
+ it "raises EOFError when the requested length goes beyond the length of the stream" do
13
+ expect{ read("", 1) }.to raise_error(EOFError)
14
+ expect{ read("", 2) }.to raise_error(EOFError)
15
+ expect{ read("", 10) }.to raise_error(EOFError)
16
+ expect{ read("\x00\x01\x02", 4) }.to raise_error(EOFError)
17
+ expect{ read("\x00\x01\x02", 10) }.to raise_error(EOFError)
18
+ end
19
+
20
+ it "returns the read data" do
21
+ expect(read("", 0)).to eq("")
22
+ expect(read("\x00", 1)).to eq("\x00")
23
+ expect(read("\x01", 1)).to eq("\x01")
24
+ expect(read("\x00\x01\x02", 3)).to eq("\x00\x01\x02")
25
+ end
26
+
27
+ def read(str, length)
28
+ io = StringIO.new(str)
29
+ subject.read_bytes(io, length)
30
+ end
31
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe XDR::Double, ".read" do
5
+
6
+ it "decodes values correctly" do
7
+ expect(read("\x00\x00\x00\x00\x00\x00\x00\x00")).to eq(0.0)
8
+ expect(read("\x80\x00\x00\x00\x00\x00\x00\x00")).to eq(-0.0)
9
+ expect(read("\x3F\xF0\x00\x00\x00\x00\x00\x00")).to eq(1.0)
10
+ expect(read("\xBF\xF0\x00\x00\x00\x00\x00\x00")).to eq(-1.0)
11
+ end
12
+
13
+ def read(str)
14
+ io = StringIO.new(str)
15
+ subject.read(io)
16
+ end
17
+ end
18
+
19
+ describe XDR::Double, ".write" do
20
+ it "encodes values correctly" do
21
+ expect(write 0.0).to eq_bytes("\x00\x00\x00\x00\x00\x00\x00\x00")
22
+ expect(write -0.0).to eq_bytes("\x80\x00\x00\x00\x00\x00\x00\x00")
23
+ expect(write 1.0).to eq_bytes("\x3F\xF0\x00\x00\x00\x00\x00\x00")
24
+ expect(write -1.0).to eq_bytes("\xBF\xF0\x00\x00\x00\x00\x00\x00")
25
+ end
26
+
27
+ it "raises a WriteError when the value is not Float" do
28
+ expect{ write 3 }.to raise_error(XDR::WriteError)
29
+ expect{ write "hi" }.to raise_error(XDR::WriteError)
30
+ expect{ write "1.0" }.to raise_error(XDR::WriteError)
31
+ end
32
+
33
+ def write(val)
34
+ io = StringIO.new()
35
+ subject.write(val, io)
36
+ io.string
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe XDR::DSL::Enum, "#member" do
5
+ subject do
6
+ Class.new(XDR::Enum) do
7
+ member :one, 1
8
+ member :two, 2
9
+ end
10
+ end
11
+
12
+ it "adds to the members collection of the class" do
13
+ expect(subject.members.length).to eq(2)
14
+ expect(subject.members[:one]).to eq(subject.one)
15
+ expect(subject.members[:two]).to eq(subject.two)
16
+ end
17
+
18
+ it "raises ArgumentError if a non-fixnum value is used" do
19
+ expect {
20
+ Class.new(XDR::Enum) do
21
+ member :one, "hi!"
22
+ end
23
+ }.to raise_error(ArgumentError)
24
+ end
25
+ end
26
+
27
+ describe XDR::DSL::Enum, "#seal" do
28
+ subject do
29
+ Class.new(XDR::Enum) do
30
+ member :one, 1
31
+ member :two, 2
32
+ seal
33
+ end
34
+ end
35
+
36
+ it "marks the class as sealed" do
37
+ expect(subject.sealed).to eq(true)
38
+ end
39
+
40
+ it "prevents you from adding members after being sealed" do
41
+ expect{ subject.member :three, 3 }.to raise_error(ArgumentError)
42
+ end
43
+
44
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe XDR::DSL::Struct, "#attribute" do
5
+ subject do
6
+ Class.new(XDR::Struct) do
7
+ attribute :attr1, XDR::Int
8
+ attribute :attr2, XDR::String[]
9
+ end
10
+ end
11
+
12
+
13
+ it "adds to the fields collection of the class" do
14
+ expect(subject.fields.length).to eq(2)
15
+ expect(subject.fields[:attr1]).to eq(XDR::Int)
16
+ expect(subject.fields[:attr2]).to be_a(XDR::String)
17
+ end
18
+
19
+
20
+
21
+ it "raises ArgumentError if a non-convertible type is used" do
22
+ expect do
23
+ Class.new(XDR::Struct) do
24
+ attribute :attr1, String
25
+ end
26
+ end.to raise_error(ArgumentError)
27
+ end
28
+
29
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe XDR::DSL::Union, "#switch" do
5
+
6
+ it "allows symbols in switch declarations" do
7
+ expect do
8
+ klass = Class.new(XDR::Union) do
9
+ switch_on ResultType, :type
10
+ switch :ok
11
+ end
12
+
13
+ klass.new(:ok)
14
+ end.to_not raise_error
15
+ end
16
+
17
+ class ResultType < XDR::Enum
18
+ member :ok, 0
19
+ member :error, 1
20
+ seal
21
+ end
22
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ class TestColor < XDR::Enum
4
+ member :red, 0
5
+ member :green, 1
6
+ member :even_more_green, 3
7
+
8
+ seal
9
+ end
10
+
11
+ describe XDR::Enum, ".read" do
12
+ let(:zero) { "\x00\x00\x00\x00" }
13
+ let(:one) { "\x00\x00\x00\x01" }
14
+ let(:two) { "\x00\x00\x00\x02" }
15
+
16
+ subject{ TestColor }
17
+
18
+ it "decodes values correctly" do
19
+ expect( read zero ).to eq(TestColor.red)
20
+ expect( read one ).to eq(TestColor.green)
21
+ end
22
+
23
+ it "raises EnumValueError if the decoded value is not in the defined constants" do
24
+ expect{ read two }.to raise_error XDR::EnumValueError
25
+ end
26
+
27
+ def read(str)
28
+ io = StringIO.new(str)
29
+ subject.read(io)
30
+ end
31
+ end
32
+
33
+ describe XDR::Enum, ".write" do
34
+ subject{ TestColor }
35
+
36
+ it "encodes values correctly" do
37
+ expect( write TestColor.red ).to eq("\x00\x00\x00\x00")
38
+ expect( write TestColor.green ).to eq("\x00\x00\x00\x01")
39
+ end
40
+
41
+ it "raises WriteError if value isn't a member" do
42
+ expect{ write 0 }.to raise_error XDR::WriteError
43
+ expect{ write 1 }.to raise_error XDR::WriteError
44
+ end
45
+
46
+ def write(val)
47
+ io = StringIO.new()
48
+ subject.write(val, io)
49
+ io.string
50
+ end
51
+ end
52
+
53
+ describe XDR::Enum, ".from_name" do
54
+ subject{ TestColor }
55
+
56
+ it "returns the correct value" do
57
+ expect(subject.from_name("red")).to eq(TestColor.red)
58
+ end
59
+
60
+ it "allows various casings, strings or symbols" do
61
+ expect(subject.from_name("even_more_green")).to eq(TestColor.even_more_green)
62
+ expect(subject.from_name("EVEN_MORE_GREEN")).to eq(TestColor.even_more_green)
63
+ expect(subject.from_name(:even_more_green)).to eq(TestColor.even_more_green)
64
+ expect(subject.from_name(:EVEN_MORE_GREEN)).to eq(TestColor.even_more_green)
65
+ end
66
+
67
+ it "raises EnumNameError when the name is not a member" do
68
+ expect{ subject.from_name("chartreuse")}.to raise_error(XDR::EnumNameError)
69
+ end
70
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe XDR::Float, ".read" do
5
+ it "decodes values correctly" do
6
+ expect(read("\x00\x00\x00\x00")).to eq(0.0)
7
+ expect(read("\x80\x00\x00\x00")).to eq(-0.0)
8
+ expect(read("\x3F\x80\x00\x00")).to eq(1.0)
9
+ expect(read("\xBF\x80\x00\x00")).to eq(-1.0)
10
+ end
11
+
12
+ def read(str)
13
+ io = StringIO.new(str)
14
+ subject.read(io)
15
+ end
16
+ end
17
+
18
+ describe XDR::Float, ".write" do
19
+ it "encodes values correctly" do
20
+ expect(write(0.0)).to eq_bytes("\x00\x00\x00\x00")
21
+ expect(write(-0.0)).to eq_bytes("\x80\x00\x00\x00")
22
+ expect(write(1.0)).to eq_bytes("\x3F\x80\x00\x00")
23
+ expect(write(-1.0)).to eq_bytes("\xBF\x80\x00\x00")
24
+ end
25
+
26
+ it "raises a WriteError when the value is not Float" do
27
+ expect{ write 3 }.to raise_error(XDR::WriteError)
28
+ expect{ write "hello" }.to raise_error(XDR::WriteError)
29
+ expect{ write "1.0" }.to raise_error(XDR::WriteError)
30
+ end
31
+
32
+ def write(val)
33
+ io = StringIO.new()
34
+ subject.write(val, io)
35
+ io.string
36
+ end
37
+ end