erlectricity 0.1.0
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.
- data/Manifest.txt +41 -0
- data/README.txt +3 -0
- data/Rakefile +68 -0
- data/examples/gruff/gruff.erl +62 -0
- data/examples/gruff/gruff_provider.rb +38 -0
- data/examples/gruff/gruff_run.erl +17 -0
- data/examples/gruff/stat_run.erl +18 -0
- data/examples/gruff/stat_writer.erl +40 -0
- data/examples/tinderl/tinderl.erl +41 -0
- data/examples/tinderl/tinderl.rb +23 -0
- data/lib/erlectricity/condition.rb +48 -0
- data/lib/erlectricity/conditions/hash.rb +15 -0
- data/lib/erlectricity/conditions/static.rb +17 -0
- data/lib/erlectricity/conditions/type.rb +19 -0
- data/lib/erlectricity/constants.rb +37 -0
- data/lib/erlectricity/decoder.rb +202 -0
- data/lib/erlectricity/encoder.rb +127 -0
- data/lib/erlectricity/errors/decode_error.rb +3 -0
- data/lib/erlectricity/errors/encode_error.rb +3 -0
- data/lib/erlectricity/errors/erlectricity_error.rb +3 -0
- data/lib/erlectricity/match_context.rb +20 -0
- data/lib/erlectricity/matcher.rb +60 -0
- data/lib/erlectricity/port.rb +46 -0
- data/lib/erlectricity/receiver.rb +74 -0
- data/lib/erlectricity/types/function.rb +3 -0
- data/lib/erlectricity/types/new_function.rb +3 -0
- data/lib/erlectricity/types/new_reference.rb +3 -0
- data/lib/erlectricity/types/pid.rb +3 -0
- data/lib/erlectricity/types/reference.rb +3 -0
- data/lib/erlectricity/version.rb +9 -0
- data/lib/erlectricity.rb +23 -0
- data/setup.rb +1585 -0
- data/test/condition_spec.rb +78 -0
- data/test/decode_spec.rb +133 -0
- data/test/encode_spec.rb +125 -0
- data/test/matcher_spec.rb +73 -0
- data/test/port_spec.rb +35 -0
- data/test/receiver_spec.rb +105 -0
- data/test/spec_suite.rb +2 -0
- data/test/test_erlectricity.rb +2 -0
- data/test/test_helper.rb +36 -0
- metadata +87 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
context "Erlectricity::StaticConditions" do
|
4
|
+
specify "should satisfy on the same value" do
|
5
|
+
Erlectricity::StaticCondition.new(:foo).satisfies?(:foo).should == true
|
6
|
+
Erlectricity::StaticCondition.new([:foo]).satisfies?([:foo]).should == true
|
7
|
+
Erlectricity::StaticCondition.new(3).satisfies?(3).should == true
|
8
|
+
end
|
9
|
+
|
10
|
+
specify "should not satisfy on diffeent values" do
|
11
|
+
Erlectricity::StaticCondition.new(:foo).satisfies?("foo").should == false
|
12
|
+
Erlectricity::StaticCondition.new([:foo]).satisfies?(:foo).should == false
|
13
|
+
Erlectricity::StaticCondition.new(Object.new).satisfies?(Object.new).should == false
|
14
|
+
Erlectricity::StaticCondition.new(3).satisfies?(3.0).should == false
|
15
|
+
end
|
16
|
+
|
17
|
+
specify "should not produce any bindings, even if a name is supplied" do
|
18
|
+
s = Erlectricity::StaticCondition.new(:foo, :bound_name)
|
19
|
+
s.bindings_for(:foo).should == {}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "Erlectricity::TypeConditions" do
|
24
|
+
specify "should be satisfied when the arg has the same class" do
|
25
|
+
Erlectricity::TypeCondition.new(Symbol).satisfies?(:foo).should == true
|
26
|
+
Erlectricity::TypeCondition.new(Symbol).satisfies?(:bar).should == true
|
27
|
+
Erlectricity::TypeCondition.new(String).satisfies?("foo").should == true
|
28
|
+
Erlectricity::TypeCondition.new(String).satisfies?("bar").should == true
|
29
|
+
Erlectricity::TypeCondition.new(Array).satisfies?([]).should == true
|
30
|
+
Erlectricity::TypeCondition.new(Fixnum).satisfies?(3).should == true
|
31
|
+
end
|
32
|
+
|
33
|
+
specify "should be satisfied when the arg is of a descendent class" do
|
34
|
+
Erlectricity::TypeCondition.new(Object).satisfies?(:foo).should == true
|
35
|
+
Erlectricity::TypeCondition.new(Object).satisfies?("foo").should == true
|
36
|
+
Erlectricity::TypeCondition.new(Object).satisfies?(3).should == true
|
37
|
+
end
|
38
|
+
|
39
|
+
specify "should not be satisfied when the arg is of a different class" do
|
40
|
+
Erlectricity::TypeCondition.new(String).satisfies?(:foo).should == false
|
41
|
+
Erlectricity::TypeCondition.new(Symbol).satisfies?("foo").should == false
|
42
|
+
Erlectricity::TypeCondition.new(Fixnum).satisfies?(3.0).should == false
|
43
|
+
end
|
44
|
+
|
45
|
+
specify "should bind the arg to the name specified with no transormations" do
|
46
|
+
s = Erlectricity::TypeCondition.new(Symbol, :bound_name)
|
47
|
+
s.bindings_for(:foo).should == {:bound_name => :foo}
|
48
|
+
s.bindings_for(:bar).should == {:bound_name => :bar}
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "should not bind anything if no binding name is specified" do
|
52
|
+
|
53
|
+
s = Erlectricity::TypeCondition.new(Symbol)
|
54
|
+
s.bindings_for(:foo).should == {}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "Erlectricity::HashConditions" do
|
59
|
+
specify "should satisfy an args of the form [[key, value], [key, value]]" do
|
60
|
+
Erlectricity::HashCondition.new.satisfies?([[:foo, 3], [:bar, Object.new]]).should == true
|
61
|
+
Erlectricity::HashCondition.new.satisfies?([[:foo, 3]]).should == true
|
62
|
+
end
|
63
|
+
|
64
|
+
specify "should satisfy on empty arrays" do
|
65
|
+
Erlectricity::HashCondition.new.satisfies?([]).should == true
|
66
|
+
end
|
67
|
+
|
68
|
+
specify "should nat satisfy other args" do
|
69
|
+
Erlectricity::HashCondition.new.satisfies?(:foo).should == false
|
70
|
+
Erlectricity::HashCondition.new.satisfies?("foo").should == false
|
71
|
+
Erlectricity::HashCondition.new.satisfies?(3.0).should == false
|
72
|
+
end
|
73
|
+
|
74
|
+
specify "should product a binder" do
|
75
|
+
s = Erlectricity::HashCondition.new(:bound_name)
|
76
|
+
s.bindings_for([[:foo, 3], [:bar, [3,4,5]]]).should == {:bound_name => {:foo => 3, :bar => [3,4,5] }}
|
77
|
+
end
|
78
|
+
end
|
data/test/decode_spec.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
context "The byte reader attached to decoder" do
|
4
|
+
specify "should not advance the stream when peeking unless there arent enough bytes available" do
|
5
|
+
@decoder = Erlectricity::Decoder.new(StringIO.new('abcdefghijklmnopqrstuvwxyz'))
|
6
|
+
100.times{ @decoder.peek_1.should == 'a'[0] }
|
7
|
+
100.times{ @decoder.peek_2.should == 'ab'.unpack("n").first }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "When unpacking from a binary stream" do
|
12
|
+
setup do
|
13
|
+
@decoder = Erlectricity::Decoder.new(nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
specify "an erlang atom should decode to a ruby symbol" do
|
17
|
+
get("haha").should == :haha
|
18
|
+
end
|
19
|
+
|
20
|
+
specify "an erlang number encoded as a small_int (< 255) should decode to a fixnum" do
|
21
|
+
get("0").should == 0
|
22
|
+
get("255").should == 255
|
23
|
+
end
|
24
|
+
|
25
|
+
specify "an erlang number encoded as a int (signed 27-bit number) should decode to a fixnum" do
|
26
|
+
get("256").should == 256
|
27
|
+
get("#{(1 << 27) -1}").should == (1 << 27) -1
|
28
|
+
get("-1").should == -1
|
29
|
+
get("#{-(1 << 27)}").should == -(1 << 27)
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
specify "an erlang number encoded as a small bignum (1 byte length) should decode to fixnum if it can" do
|
34
|
+
get("#{(1 << 27)}").should == (1 << 27)
|
35
|
+
get("#{-(1 << 27) - 1}").should == -(1 << 27) - 1
|
36
|
+
get("#{(1 << word_length) - 1}").should == (1 << word_length) - 1
|
37
|
+
get("#{-(1 << word_length)}").should == -(1 << word_length)
|
38
|
+
end
|
39
|
+
|
40
|
+
specify "an erlang number encoded as a small bignum (1 byte length) should decode to bignum if it can't be a fixnum" do
|
41
|
+
get("#{(1 << word_length)}").should == (1 << word_length)
|
42
|
+
get("#{-(1 << word_length) - 1}").should == -(1 << word_length) - 1
|
43
|
+
get("#{(1 << (255 * 8)) - 1}").should == (1 << (255 * 8)) - 1
|
44
|
+
get("#{-((1 << (255 * 8)) - 1)}").should == -((1 << (255 * 8)) - 1)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
specify "an erlang number encoded as a big bignum (4 byte length) should decode to bignum" do
|
49
|
+
get("#{(1 << (255 * 8)) }").should == (1 << (255 * 8))
|
50
|
+
get("#{-(1 << (255 * 8))}").should == -(1 << (255 * 8))
|
51
|
+
get("#{(1 << (512 * 8)) }").should == (1 << (512 * 8))
|
52
|
+
get("#{-(1 << (512 * 8))}").should == -(1 << (512 * 8))
|
53
|
+
end
|
54
|
+
|
55
|
+
specify "an erlang float should decode to a Float" do
|
56
|
+
get("#{1.0}").should == 1.0
|
57
|
+
get("#{-1.0}").should == -1.0
|
58
|
+
get("#{123.456}").should == 123.456
|
59
|
+
get("#{123.456789012345}").should == 123.456789012345
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
specify "an erlang reference should decode to a Reference object" do
|
64
|
+
ref = get("make_ref()")
|
65
|
+
ref.should.be.instance_of Erlectricity::NewReference
|
66
|
+
ref.node.should.be.instance_of Symbol
|
67
|
+
end
|
68
|
+
|
69
|
+
specify "an erlang pid should decode to a Pid object" do
|
70
|
+
pid = get("spawn(fun() -> 3 end)")
|
71
|
+
pid.should.be.instance_of Erlectricity::Pid
|
72
|
+
pid.node.should.be.instance_of Symbol
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
specify "an erlang tuple encoded as a small tuple (1-byte length) should decode to an array" do
|
77
|
+
ref = get("{3}")
|
78
|
+
ref.length.should == 1
|
79
|
+
ref.first.should == 3
|
80
|
+
|
81
|
+
ref = get("{3, a, make_ref()}")
|
82
|
+
ref.length.should == 3
|
83
|
+
ref[0].should == 3
|
84
|
+
ref[1].should == :a
|
85
|
+
ref[2].class.should == Erlectricity::NewReference
|
86
|
+
|
87
|
+
tuple_meat = (['3'] * 255).join(', ')
|
88
|
+
ref = get("{#{tuple_meat}}")
|
89
|
+
ref.length.should == 255
|
90
|
+
ref.each{|r| r.should == 3}
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
specify "an erlang tuple encoded as a large tuple (4-byte length) should decode to an array" do
|
95
|
+
tuple_meat = (['3'] * 256).join(', ')
|
96
|
+
ref = get("{#{tuple_meat}}")
|
97
|
+
ref.length.should == 256
|
98
|
+
ref.each{|r| r.should == 3}
|
99
|
+
|
100
|
+
tuple_meat = (['3'] * 512).join(', ')
|
101
|
+
ref = get("{#{tuple_meat}}")
|
102
|
+
ref.length.should == 512
|
103
|
+
ref.each{|r| r.should == 3}
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
specify "an empty erlang list encoded as a nil should decode to an array" do
|
108
|
+
get("[]").should == []
|
109
|
+
end
|
110
|
+
|
111
|
+
specify "an erlang list encoded as a string should decode to an array of bytes (less than ideal, but consistent)" do
|
112
|
+
get("\"asdasd\"").should == "asdasd".split('').map{|c| c[0]}
|
113
|
+
get("\"#{'a' * 65534}\"").should == ['a'[0]] * 65534
|
114
|
+
end
|
115
|
+
|
116
|
+
specify "an erlang list encoded as a list should decode to a array" do
|
117
|
+
get("[3,4,256]").should == [3,4,256]
|
118
|
+
get("\"#{'a' * 65535 }\"").should == [97] * 65535
|
119
|
+
get("[3,4, foo, {3,4,5,bar}, 256]").should == [3,4, :foo, [3,4,5,:bar], 256]
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
specify "an erlang binary should decode to a string" do
|
124
|
+
get("<< 3,4,255 >>").should == "\003\004\377"
|
125
|
+
get("<< \"whatup\" >>").should == "whatup"
|
126
|
+
end
|
127
|
+
|
128
|
+
def get(str)
|
129
|
+
bin = run_erl("term_to_binary(#{str})")
|
130
|
+
@decoder.in = StringIO.new(bin)
|
131
|
+
@decoder.read_any
|
132
|
+
end
|
133
|
+
end
|
data/test/encode_spec.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
context "When packing to a binary stream" do
|
4
|
+
setup do
|
5
|
+
@out = StringIO.new('', 'w')
|
6
|
+
@encoder = Erlectricity::Encoder.new(@out)
|
7
|
+
end
|
8
|
+
specify "A symbol should be encoded to an erlang atom" do
|
9
|
+
get{@encoder.write_symbol :haha}.should == get_erl("haha")
|
10
|
+
write_any(:haha).should == get_erl_with_magic("haha")
|
11
|
+
end
|
12
|
+
|
13
|
+
specify "A number should be encoded as an erlang number would be" do
|
14
|
+
|
15
|
+
#SMALL_INTS
|
16
|
+
get{@encoder.write_fixnum 0}.should == get_erl("0")
|
17
|
+
get{@encoder.write_fixnum 255}.should == get_erl("255")
|
18
|
+
write_any(0).should == get_erl_with_magic("0")
|
19
|
+
write_any(255).should == get_erl_with_magic("255")
|
20
|
+
|
21
|
+
#INTS
|
22
|
+
get{@encoder.write_fixnum 256}.should == get_erl("256")
|
23
|
+
get{@encoder.write_fixnum((1 << 27) - 1)}.should == get_erl("#{(1 << 27) - 1}")
|
24
|
+
get{@encoder.write_fixnum(-1)}.should == get_erl("-1")
|
25
|
+
get{@encoder.write_fixnum(-(1 << 27))}.should == get_erl("#{-(1 << 27)}")
|
26
|
+
write_any(256).should == get_erl_with_magic("256")
|
27
|
+
write_any((1 << 27) - 1).should == get_erl_with_magic("#{(1 << 27) - 1}")
|
28
|
+
write_any(-1).should == get_erl_with_magic("-1")
|
29
|
+
write_any(-(1 << 27)).should == get_erl_with_magic("#{-(1 << 27)}")
|
30
|
+
|
31
|
+
# #SMALL_BIGNUMS
|
32
|
+
# get{@encoder.write_fixnum((1 << word_length))}.should == get_erl("#{(1 << word_length)}")
|
33
|
+
# get{@encoder.write_fixnum(-(1 << word_length) - 1)}.should == get_erl("#{-(1 << word_length) - 1}")
|
34
|
+
# get{@encoder.write_fixnum((1 << (255 * 8)) - 1)}.should == get_erl("#{(1 << (255 * 8)) - 1}")
|
35
|
+
# get{@encoder.write_fixnum(-((1 << (255 * 8)) - 1))}.should == get_erl("#{-((1 << (255 * 8)) - 1)}")
|
36
|
+
#
|
37
|
+
# write_any((1 << word_length)).should == get_erl_with_magic("#{(1 << word_length)}")
|
38
|
+
# write_any(-(1 << word_length) - 1).should == get_erl_with_magic("#{-(1 << word_length) - 1}")
|
39
|
+
# write_any((1 << (255 * 8)) - 1).should == get_erl_with_magic("#{(1 << (255 * 8)) - 1}")
|
40
|
+
# write_any(-((1 << (255 * 8)) - 1)).should == get_erl_with_magic("#{-((1 << (255 * 8)) - 1)}")
|
41
|
+
#
|
42
|
+
# #LARG_BIGNUMS
|
43
|
+
# get{@encoder.write_fixnum((1 << (255 * 8)))}.should == get_erl("#{(1 << (255 * 8))}")
|
44
|
+
# get{@encoder.write_fixnum(-(1 << (255 * 8))}.should == get_erl("#{-(1 << (255 * 8)}")
|
45
|
+
# get{@encoder.write_fixnum((1 << (512 * 8))}.should == get_erl("#{(1 << (512 * 8))}")
|
46
|
+
# get{@encoder.write_fixnum(-((1 << (512 * 8)) - 1))}.should == get_erl("#{-((1 << (512 * 8)) - 1)}")
|
47
|
+
#
|
48
|
+
# write_any((1 << (255 * 8))).should == get_erl_with_magic("#{(1 << (255 * 8))}")
|
49
|
+
# write_any(-(1 << (255 * 8)).should == get_erl_with_magic("#{-(1 << (255 * 8)}")
|
50
|
+
# write_any((1 << (512 * 8))).should == get_erl_with_magic("#{(1 << (512 * 8))}")
|
51
|
+
# write_any(-((1 << (512 * 8)) - 1)).should == get_erl_with_magic("#{-((1 << (512 * 8)) - 1)}")
|
52
|
+
end
|
53
|
+
|
54
|
+
# specify "A float (that is within the truncated precision of ruby compared to erlang) should encode as erlang does" do
|
55
|
+
# get{@encoder.write_float 1.0}.should == get_erl("1.0")
|
56
|
+
# get{@encoder.write_float -1.0}.should == get_erl("-1.0")
|
57
|
+
# get{@encoder.write_float 123.456}.should == get_erl("123.456")
|
58
|
+
# get{@encoder.write_float 123.456789012345}.should == get_erl("123.456789012345")
|
59
|
+
# end
|
60
|
+
|
61
|
+
specify "An Erlectiricity::NewReference should encode back to its original form" do
|
62
|
+
ref_bin = run_erl("term_to_binary(make_ref())")
|
63
|
+
ruby_ref = Erlectricity::Decoder.read_any_from(ref_bin)
|
64
|
+
|
65
|
+
get{@encoder.write_new_reference(ruby_ref)}.should == ref_bin[1..-1]
|
66
|
+
write_any(ruby_ref).should == ref_bin
|
67
|
+
end
|
68
|
+
|
69
|
+
specify "An Erlectiricity::Pid should encode back to its original form" do
|
70
|
+
pid_bin = run_erl("term_to_binary(spawn(fun() -> 3 end))")
|
71
|
+
ruby_pid = Erlectricity::Decoder.read_any_from(pid_bin)
|
72
|
+
|
73
|
+
get{@encoder.write_pid(ruby_pid)}.should == pid_bin[1..-1]
|
74
|
+
write_any(ruby_pid).should == pid_bin
|
75
|
+
end
|
76
|
+
|
77
|
+
specify "An array written with write_tuple should encode as erlang would a tuple" do
|
78
|
+
get{@encoder.write_tuple [1,2,3]}.should == get_erl("{1,2,3}")
|
79
|
+
get{@encoder.write_tuple [3] * 255}.should == get_erl("{#{([3] * 255).join(',')}}")
|
80
|
+
get{@encoder.write_tuple [3] * 256}.should == get_erl("{#{([3] * 256).join(',')}}")
|
81
|
+
get{@encoder.write_tuple [3] * 512}.should == get_erl("{#{([3] * 512).join(',')}}")
|
82
|
+
end
|
83
|
+
|
84
|
+
specify "An array should by default be written as a tuple" do
|
85
|
+
write_any([1,2,3]).should == get_erl_with_magic("{1,2,3}")
|
86
|
+
write_any([3] * 255).should == get_erl_with_magic("{#{([3] * 255).join(',')}}")
|
87
|
+
write_any([3] * 256).should == get_erl_with_magic("{#{([3] * 256).join(',')}}")
|
88
|
+
write_any([3] * 512).should == get_erl_with_magic("{#{([3] * 512).join(',')}}")
|
89
|
+
end
|
90
|
+
|
91
|
+
specify "An array written with write_list should encode as erlang would a list" do
|
92
|
+
get{@encoder.write_list [1,2,300]}.should == get_erl("[1,2,300]")
|
93
|
+
get{@encoder.write_list [300] * 255}.should == get_erl("[#{([300] * 255).join(',')}]")
|
94
|
+
get{@encoder.write_list [300] * 256}.should == get_erl("[#{([300] * 256).join(',')}]")
|
95
|
+
get{@encoder.write_list [300] * 512}.should == get_erl("[#{([300] * 512).join(',')}]")
|
96
|
+
end
|
97
|
+
|
98
|
+
specify "a string should be encoded as a erlang binary would be" do
|
99
|
+
get{@encoder.write_binary "hey who"}.should == get_erl("<< \"hey who\" >>")
|
100
|
+
get{@encoder.write_binary ""}.should == get_erl("<< \"\" >>")
|
101
|
+
|
102
|
+
write_any("hey who").should == get_erl_with_magic("<< \"hey who\" >>")
|
103
|
+
write_any("").should == get_erl_with_magic("<< \"\" >>")
|
104
|
+
end
|
105
|
+
|
106
|
+
def get
|
107
|
+
@encoder.out = StringIO.new('', 'w')
|
108
|
+
yield
|
109
|
+
@encoder.out.string
|
110
|
+
end
|
111
|
+
|
112
|
+
def write_any(term)
|
113
|
+
@encoder.out = StringIO.new('', 'w')
|
114
|
+
@encoder.write_any term
|
115
|
+
@encoder.out.string
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_erl(str)
|
119
|
+
get_erl_with_magic(str)[1..-1] #[1..-1] to chop off the magic number
|
120
|
+
end
|
121
|
+
|
122
|
+
def get_erl_with_magic(str)
|
123
|
+
run_erl("term_to_binary(#{str})")
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
def false_match(matcher, arg)
|
4
|
+
matcher.matches?(arg).should == false
|
5
|
+
end
|
6
|
+
|
7
|
+
context "A matcher whose condition is Symbol (the class object)" do
|
8
|
+
setup do
|
9
|
+
@matcher = Erlectricity::Matcher.new(nil, Erlectricity::TypeCondition.new(Symbol), nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
specify "should match any symbol" do
|
13
|
+
@matcher.matches?(:foo).should == true
|
14
|
+
@matcher.matches?(:bar).should == true
|
15
|
+
@matcher.matches?(:baz).should == true
|
16
|
+
end
|
17
|
+
|
18
|
+
specify "should not match strings" do
|
19
|
+
@matcher.matches?("foo").should == false
|
20
|
+
@matcher.matches?("bar").should == false
|
21
|
+
@matcher.matches?("baz").should == false
|
22
|
+
end
|
23
|
+
|
24
|
+
specify "should not match a arrays" do
|
25
|
+
@matcher.matches?([:foo]).should == false
|
26
|
+
@matcher.matches?([:foo, :bar]).should == false
|
27
|
+
@matcher.matches?([:foo, :bar, :baz]).should == false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "a matcher whose condition is a symbol" do
|
32
|
+
setup do
|
33
|
+
@matcher = Erlectricity::Matcher.new(nil, Erlectricity::StaticCondition.new(:foo), nil)
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "should match that symbol" do
|
37
|
+
@matcher.matches?(:foo).should == true
|
38
|
+
end
|
39
|
+
|
40
|
+
specify "should not match any other symbol" do
|
41
|
+
@matcher.matches?(:bar).should == false
|
42
|
+
@matcher.matches?(:baz).should == false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "a matcher whose matcher is an array" do
|
47
|
+
setup do
|
48
|
+
end
|
49
|
+
|
50
|
+
specify "should match if all of its children match" do
|
51
|
+
Erlectricity::Matcher.new(nil, [Erlectricity::StaticCondition.new(:speak), Erlectricity::TypeCondition.new(Object)], nil).matches?([:paste, "haha"]).should == false
|
52
|
+
|
53
|
+
matcher = Erlectricity::Matcher.new(nil, [Erlectricity::StaticCondition.new(:foo), Erlectricity::StaticCondition.new(:bar)], nil)
|
54
|
+
matcher.matches?([:foo, :bar]).should == true
|
55
|
+
end
|
56
|
+
|
57
|
+
specify "should not match any of its children dont match" do
|
58
|
+
matcher = Erlectricity::Matcher.new(nil, [Erlectricity::StaticCondition.new(:foo), Erlectricity::StaticCondition.new(:bar)], nil)
|
59
|
+
matcher.matches?([:foo]).should == false
|
60
|
+
matcher.matches?([:foo, :bar, :baz]).should == false
|
61
|
+
matcher.matches?([:fooo, :barr]).should == false
|
62
|
+
matcher.matches?([3, :bar]).should == false
|
63
|
+
end
|
64
|
+
|
65
|
+
specify "should not match if arg isn't an array" do
|
66
|
+
matcher = Erlectricity::Matcher.new(nil, [Erlectricity::StaticCondition.new(:foo), Erlectricity::StaticCondition.new(:bar)], nil)
|
67
|
+
matcher.matches?(:foo).should == false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "a matcher" do
|
72
|
+
|
73
|
+
end
|
data/test/port_spec.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
context "A port" do
|
4
|
+
specify "should return terms from the queue if it is not empty" do
|
5
|
+
port = FakePort.new()
|
6
|
+
port.queue.clear
|
7
|
+
port.queue << :foo << :bar
|
8
|
+
port.receive.should == :foo
|
9
|
+
port.receive.should == :bar
|
10
|
+
port.receive.should == nil
|
11
|
+
end
|
12
|
+
|
13
|
+
specify "should read_from_input if the queue gets empty" do
|
14
|
+
port = FakePort.new(:bar)
|
15
|
+
port.queue.clear
|
16
|
+
port.queue << :foo
|
17
|
+
port.receive.should == :foo
|
18
|
+
port.receive.should == :bar
|
19
|
+
port.receive.should == nil
|
20
|
+
end
|
21
|
+
|
22
|
+
specify "should put the terms in skipped at the front of queue when restore_skipped is called" do
|
23
|
+
port = FakePort.new(:baz)
|
24
|
+
port.queue.clear
|
25
|
+
port.queue << :bar
|
26
|
+
port.skipped << :foo
|
27
|
+
port.restore_skipped
|
28
|
+
|
29
|
+
port.receive.should == :foo
|
30
|
+
port.receive.should == :bar
|
31
|
+
port.receive.should == :baz
|
32
|
+
port.receive.should == nil
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
def simple_receiver_and_port(*terms, &block)
|
4
|
+
port = FakePort.new(*terms)
|
5
|
+
receiver = if block
|
6
|
+
Erlectricity::Receiver.new(port, &block)
|
7
|
+
else
|
8
|
+
Erlectricity::Receiver.new(port) do
|
9
|
+
match(any) do
|
10
|
+
:matched
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
context "When a receiver is passed a message that matches two match blocks it" do
|
18
|
+
setup do
|
19
|
+
@port = FakePort.new([:foo, :foo])
|
20
|
+
@receiver = Erlectricity::Receiver.new(@port) do
|
21
|
+
match(:foo, :foo) do
|
22
|
+
:first
|
23
|
+
end
|
24
|
+
|
25
|
+
match(:foo, any) do
|
26
|
+
:second
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
specify "should run the first matching receiver's block" do
|
32
|
+
@receiver.run.should == :first
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "A receiver" do
|
37
|
+
specify "should return the result of the match block when finished" do
|
38
|
+
simple_receiver_and_port(:foo).run.should == :matched
|
39
|
+
simple_receiver_and_port(:bar).run.should == :matched
|
40
|
+
simple_receiver_and_port(:bar, :baz).run.should == :matched
|
41
|
+
end
|
42
|
+
|
43
|
+
specify "should process another message if the matched block returns the results of receive_loop" do
|
44
|
+
recv = simple_receiver_and_port(:foo, :bar, :baz) do
|
45
|
+
match(:bar) { }
|
46
|
+
match(any) { receive_loop }
|
47
|
+
end
|
48
|
+
|
49
|
+
recv.run
|
50
|
+
recv.port.terms.should == [:baz]
|
51
|
+
end
|
52
|
+
|
53
|
+
specify "should properly nest" do
|
54
|
+
@port = FakePort.new(:foo, :bar, :baz)
|
55
|
+
@receiver = Erlectricity::Receiver.new(@port) do
|
56
|
+
match(:foo) do
|
57
|
+
receive do
|
58
|
+
match(:bar){ :ok }
|
59
|
+
end
|
60
|
+
receive_loop
|
61
|
+
end
|
62
|
+
|
63
|
+
match(:baz) do
|
64
|
+
:done
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
@receiver.run.should == :done
|
69
|
+
@port.terms.should == []
|
70
|
+
end
|
71
|
+
|
72
|
+
specify "should queue up skipped results and restore them when a match happens" do
|
73
|
+
@port = FakePort.new(:foo, :baz, :bar)
|
74
|
+
@receiver = Erlectricity::Receiver.new(@port) do
|
75
|
+
match(:foo) do
|
76
|
+
receive do
|
77
|
+
match(:bar){ :ok }
|
78
|
+
end
|
79
|
+
receive_loop
|
80
|
+
end
|
81
|
+
|
82
|
+
match(:baz) do
|
83
|
+
:done
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
@receiver.run.should == :done
|
88
|
+
@port.terms.should == []
|
89
|
+
end
|
90
|
+
|
91
|
+
specify "should expose bindings to the matched block" do
|
92
|
+
@port = FakePort.new(:foo, :bar, :baz)
|
93
|
+
results = []
|
94
|
+
@receiver = Erlectricity::Receiver.new(@port) do
|
95
|
+
match(atom(:bindinated)) do
|
96
|
+
results << bindinated
|
97
|
+
receive_loop
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
@receiver.run.should == nil
|
102
|
+
results.should == [:foo, :bar, :baz]
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
data/test/spec_suite.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require 'rubygems'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'test/spec'
|
5
|
+
require 'erlectricity'
|
6
|
+
|
7
|
+
class Test::Unit::TestCase
|
8
|
+
|
9
|
+
def run_erl(code)
|
10
|
+
`erl -noshell -eval 'A = #{code.split.join(' ')}, io:put_chars(A).' -s erlang halt`
|
11
|
+
end
|
12
|
+
|
13
|
+
def word_length
|
14
|
+
(1.size * 8) - 2
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class FakePort < Erlectricity::Port
|
19
|
+
attr_reader :sent
|
20
|
+
attr_reader :terms
|
21
|
+
|
22
|
+
def initialize(*terms)
|
23
|
+
@terms = terms
|
24
|
+
@sent = []
|
25
|
+
super(StringIO.new(""), StringIO.new(""))
|
26
|
+
end
|
27
|
+
|
28
|
+
def send(term)
|
29
|
+
sent << term
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def read_from_input
|
34
|
+
@terms.shift
|
35
|
+
end
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: erlectricity
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2007-05-08 00:00:00 -07:00
|
8
|
+
summary: A library to interface erlang and ruby through the erlang port system
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: nullstyle@gmail.com
|
12
|
+
homepage: http://erlectricity.rubyforge.org
|
13
|
+
rubyforge_project: erlectricity
|
14
|
+
description: A library to interface erlang and ruby through the erlang port system
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Scott Fleckenstein
|
31
|
+
files:
|
32
|
+
- Manifest.txt
|
33
|
+
- README.txt
|
34
|
+
- Rakefile
|
35
|
+
- examples/gruff/gruff.erl
|
36
|
+
- examples/gruff/gruff_provider.rb
|
37
|
+
- examples/gruff/gruff_run.erl
|
38
|
+
- examples/gruff/stat_run.erl
|
39
|
+
- examples/gruff/stat_writer.erl
|
40
|
+
- examples/tinderl/tinderl.erl
|
41
|
+
- examples/tinderl/tinderl.rb
|
42
|
+
- lib/erlectricity.rb
|
43
|
+
- lib/erlectricity/condition.rb
|
44
|
+
- lib/erlectricity/conditions/hash.rb
|
45
|
+
- lib/erlectricity/conditions/static.rb
|
46
|
+
- lib/erlectricity/conditions/type.rb
|
47
|
+
- lib/erlectricity/constants.rb
|
48
|
+
- lib/erlectricity/decoder.rb
|
49
|
+
- lib/erlectricity/encoder.rb
|
50
|
+
- lib/erlectricity/errors/decode_error.rb
|
51
|
+
- lib/erlectricity/errors/encode_error.rb
|
52
|
+
- lib/erlectricity/errors/erlectricity_error.rb
|
53
|
+
- lib/erlectricity/match_context.rb
|
54
|
+
- lib/erlectricity/matcher.rb
|
55
|
+
- lib/erlectricity/port.rb
|
56
|
+
- lib/erlectricity/receiver.rb
|
57
|
+
- lib/erlectricity/types/function.rb
|
58
|
+
- lib/erlectricity/types/new_function.rb
|
59
|
+
- lib/erlectricity/types/new_reference.rb
|
60
|
+
- lib/erlectricity/types/pid.rb
|
61
|
+
- lib/erlectricity/types/reference.rb
|
62
|
+
- lib/erlectricity/version.rb
|
63
|
+
- setup.rb
|
64
|
+
- test/condition_spec.rb
|
65
|
+
- test/decode_spec.rb
|
66
|
+
- test/encode_spec.rb
|
67
|
+
- test/matcher_spec.rb
|
68
|
+
- test/port_spec.rb
|
69
|
+
- test/receiver_spec.rb
|
70
|
+
- test/spec_suite.rb
|
71
|
+
- test/test_erlectricity.rb
|
72
|
+
- test/test_helper.rb
|
73
|
+
test_files:
|
74
|
+
- test/test_erlectricity.rb
|
75
|
+
- test/test_helper.rb
|
76
|
+
rdoc_options: []
|
77
|
+
|
78
|
+
extra_rdoc_files: []
|
79
|
+
|
80
|
+
executables: []
|
81
|
+
|
82
|
+
extensions: []
|
83
|
+
|
84
|
+
requirements: []
|
85
|
+
|
86
|
+
dependencies: []
|
87
|
+
|