tmm1-erlectricity 0.2.1
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/CONTRIBUTORS +2 -0
- data/History.txt +1 -0
- data/Manifest.txt +45 -0
- data/README.txt +51 -0
- data/Rakefile +71 -0
- data/examples/gruff/gruff.erl +62 -0
- data/examples/gruff/gruff_provider.rb +36 -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 +45 -0
- data/examples/tinderl/tinderl.rb +27 -0
- data/ext/decoder.c +391 -0
- data/ext/extconf.rb +11 -0
- data/lib/erlectricity.rb +37 -0
- data/lib/erlectricity/condition.rb +51 -0
- data/lib/erlectricity/conditions/hash.rb +14 -0
- data/lib/erlectricity/conditions/static.rb +13 -0
- data/lib/erlectricity/conditions/type.rb +17 -0
- data/lib/erlectricity/constants.rb +37 -0
- data/lib/erlectricity/decoder.rb +204 -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/matcher.rb +38 -0
- data/lib/erlectricity/port.rb +46 -0
- data/lib/erlectricity/receiver.rb +78 -0
- data/lib/erlectricity/types/function.rb +3 -0
- data/lib/erlectricity/types/list.rb +1 -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/setup.rb +1585 -0
- data/test/condition_spec.rb +73 -0
- data/test/decode_spec.rb +129 -0
- data/test/encode_spec.rb +132 -0
- data/test/matcher_spec.rb +69 -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 +42 -0
- metadata +102 -0
@@ -0,0 +1,73 @@
|
|
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 different 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" do
|
18
|
+
s = Erlectricity::StaticCondition.new(:foo)
|
19
|
+
s.binding_for(:foo).should == nil
|
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 with no transormations" do
|
46
|
+
s = Erlectricity::TypeCondition.new(Symbol)
|
47
|
+
s.binding_for(:foo).should == :foo
|
48
|
+
s.binding_for(:bar).should == :bar
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
context "Erlectricity::HashConditions" do
|
54
|
+
specify "should satisfy an args of the form [[key, value], [key, value]]" do
|
55
|
+
Erlectricity::HashCondition.new.satisfies?([[:foo, 3], [:bar, Object.new]]).should == true
|
56
|
+
Erlectricity::HashCondition.new.satisfies?([[:foo, 3]]).should == true
|
57
|
+
end
|
58
|
+
|
59
|
+
specify "should satisfy on empty arrays" do
|
60
|
+
Erlectricity::HashCondition.new.satisfies?([]).should == true
|
61
|
+
end
|
62
|
+
|
63
|
+
specify "should nat satisfy other args" do
|
64
|
+
Erlectricity::HashCondition.new.satisfies?(:foo).should == false
|
65
|
+
Erlectricity::HashCondition.new.satisfies?("foo").should == false
|
66
|
+
Erlectricity::HashCondition.new.satisfies?(3.0).should == false
|
67
|
+
end
|
68
|
+
|
69
|
+
specify "should bind to a Hash" do
|
70
|
+
s = Erlectricity::HashCondition.new()
|
71
|
+
s.binding_for([[:foo, 3], [:bar, [3,4,5]]]).should == {:foo => 3, :bar => [3,4,5] }
|
72
|
+
end
|
73
|
+
end
|
data/test/decode_spec.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
context "When unpacking from a binary stream" do
|
4
|
+
setup do
|
5
|
+
end
|
6
|
+
|
7
|
+
specify "an erlang atom should decode to a ruby symbol" do
|
8
|
+
get("haha").should == :haha
|
9
|
+
end
|
10
|
+
|
11
|
+
specify "an erlang number encoded as a small_int (< 255) should decode to a fixnum" do
|
12
|
+
get("0").should == 0
|
13
|
+
get("255").should == 255
|
14
|
+
end
|
15
|
+
|
16
|
+
specify "an erlang number encoded as a int (signed 27-bit number) should decode to a fixnum" do
|
17
|
+
get("256").should == 256
|
18
|
+
get("#{(1 << 27) -1}").should == (1 << 27) -1
|
19
|
+
get("-1").should == -1
|
20
|
+
get("#{-(1 << 27)}").should == -(1 << 27)
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
specify "an erlang number encoded as a small bignum (1 byte length) should decode to fixnum if it can" do
|
25
|
+
get("#{(1 << 27)}").should == (1 << 27)
|
26
|
+
get("#{-(1 << 27) - 1}").should == -(1 << 27) - 1
|
27
|
+
get("#{(1 << word_length) - 1}").should == (1 << word_length) - 1
|
28
|
+
get("#{-(1 << word_length)}").should == -(1 << word_length)
|
29
|
+
end
|
30
|
+
|
31
|
+
specify "an erlang number encoded as a small bignum (1 byte length) should decode to bignum if it can't be a fixnum" do
|
32
|
+
get("#{(1 << word_length)}").should == (1 << word_length)
|
33
|
+
get("#{-(1 << word_length) - 1}").should == -(1 << word_length) - 1
|
34
|
+
get("#{(1 << (255 * 8)) - 1}").should == (1 << (255 * 8)) - 1
|
35
|
+
get("#{-((1 << (255 * 8)) - 1)}").should == -((1 << (255 * 8)) - 1)
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
specify "an erlang number encoded as a big bignum (4 byte length) should decode to bignum" do
|
40
|
+
get("#{(1 << (255 * 8)) }").should == (1 << (255 * 8))
|
41
|
+
get("#{-(1 << (255 * 8))}").should == -(1 << (255 * 8))
|
42
|
+
get("#{(1 << (512 * 8)) }").should == (1 << (512 * 8))
|
43
|
+
get("#{-(1 << (512 * 8))}").should == -(1 << (512 * 8))
|
44
|
+
end
|
45
|
+
|
46
|
+
specify "an erlang float should decode to a Float" do
|
47
|
+
get("#{1.0}").should == 1.0
|
48
|
+
get("#{-1.0}").should == -1.0
|
49
|
+
get("#{123.456}").should == 123.456
|
50
|
+
get("#{123.456789012345}").should == 123.456789012345
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
specify "an erlang reference should decode to a Reference object" do
|
55
|
+
ref = get("make_ref()")
|
56
|
+
ref.should.be.instance_of Erlectricity::NewReference
|
57
|
+
ref.node.should.be.instance_of Symbol
|
58
|
+
end
|
59
|
+
|
60
|
+
specify "an erlang pid should decode to a Pid object" do
|
61
|
+
pid = get("spawn(fun() -> 3 end)")
|
62
|
+
pid.should.be.instance_of Erlectricity::Pid
|
63
|
+
pid.node.should.be.instance_of Symbol
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
specify "an erlang tuple encoded as a small tuple (1-byte length) should decode to an array" do
|
68
|
+
ref = get("{3}")
|
69
|
+
ref.length.should == 1
|
70
|
+
ref.first.should == 3
|
71
|
+
|
72
|
+
ref = get("{3, a, make_ref()}")
|
73
|
+
ref.length.should == 3
|
74
|
+
ref[0].should == 3
|
75
|
+
ref[1].should == :a
|
76
|
+
ref[2].class.should == Erlectricity::NewReference
|
77
|
+
|
78
|
+
tuple_meat = (['3'] * 255).join(', ')
|
79
|
+
ref = get("{#{tuple_meat}}")
|
80
|
+
ref.length.should == 255
|
81
|
+
ref.each{|r| r.should == 3}
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
specify "an erlang tuple encoded as a large tuple (4-byte length) should decode to an array" do
|
86
|
+
tuple_meat = (['3'] * 256).join(', ')
|
87
|
+
ref = get("{#{tuple_meat}}")
|
88
|
+
ref.length.should == 256
|
89
|
+
ref.each{|r| r.should == 3}
|
90
|
+
|
91
|
+
tuple_meat = (['3'] * 512).join(', ')
|
92
|
+
ref = get("{#{tuple_meat}}")
|
93
|
+
ref.length.should == 512
|
94
|
+
ref.each{|r| r.should == 3}
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
specify "an empty erlang list encoded as a nil should decode to an array" do
|
99
|
+
get("[]").should == []
|
100
|
+
end
|
101
|
+
|
102
|
+
specify "an erlang list encoded as a string should decode to an array of bytes (less than ideal, but consistent)" do
|
103
|
+
get("\"asdasd\"").should == "asdasd".split('').map{|c| c[0]}
|
104
|
+
get("\"#{'a' * 65534}\"").should == ['a'[0]] * 65534
|
105
|
+
end
|
106
|
+
|
107
|
+
specify "an erlang list encoded as a list should decode to a array" do
|
108
|
+
get("[3,4,256]").should == [3,4,256]
|
109
|
+
get("\"#{'a' * 65535 }\"").should == [97] * 65535
|
110
|
+
get("[3,4, foo, {3,4,5,bar}, 256]").should == [3,4, :foo, [3,4,5,:bar], 256]
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
specify "an erlang binary should decode to a string" do
|
115
|
+
get("<< 3,4,255 >>").should == "\003\004\377"
|
116
|
+
get("<< \"whatup\" >>").should == "whatup"
|
117
|
+
end
|
118
|
+
|
119
|
+
specify "a good thing should be awesome" do
|
120
|
+
get(%Q-[{options,{struct,[{test,<<"I'm chargin' mah lazer">>}]}},{passage,<<"Why doesn't this work?">>}]-).should ==
|
121
|
+
[[:options, [:struct, [[:test, "I'm chargin' mah lazer"]]]], [:passage, "Why doesn't this work?"]]
|
122
|
+
end
|
123
|
+
|
124
|
+
def get(str)
|
125
|
+
x = "term_to_binary(#{str.gsub(/"/, '\\\"')})"
|
126
|
+
bin = run_erl(x)
|
127
|
+
Erlectricity::Decoder.read_any_from(bin)
|
128
|
+
end
|
129
|
+
end
|
data/test/encode_spec.rb
ADDED
@@ -0,0 +1,132 @@
|
|
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 Erlectricity::List should by default be written as a list" do
|
92
|
+
write_any(Erl::List.new([1,2,300])).should == get_erl_with_magic("[1,2,300]")
|
93
|
+
write_any(Erl::List.new([300] * 255)).should == get_erl_with_magic("[#{([300] * 255).join(',')}]")
|
94
|
+
write_any(Erl::List.new([300] * 256)).should == get_erl_with_magic("[#{([300] * 256).join(',')}]")
|
95
|
+
write_any(Erl::List.new([300] * 512)).should == get_erl_with_magic("[#{([300] * 512).join(',')}]")
|
96
|
+
end
|
97
|
+
|
98
|
+
specify "An array written with write_list should encode as erlang would a list" do
|
99
|
+
get{@encoder.write_list [1,2,300]}.should == get_erl("[1,2,300]")
|
100
|
+
get{@encoder.write_list [300] * 255}.should == get_erl("[#{([300] * 255).join(',')}]")
|
101
|
+
get{@encoder.write_list [300] * 256}.should == get_erl("[#{([300] * 256).join(',')}]")
|
102
|
+
get{@encoder.write_list [300] * 512}.should == get_erl("[#{([300] * 512).join(',')}]")
|
103
|
+
end
|
104
|
+
|
105
|
+
specify "a string should be encoded as a erlang binary would be" do
|
106
|
+
get{@encoder.write_binary "hey who"}.should == get_erl("<< \"hey who\" >>")
|
107
|
+
get{@encoder.write_binary ""}.should == get_erl("<< \"\" >>")
|
108
|
+
|
109
|
+
write_any("hey who").should == get_erl_with_magic("<< \"hey who\" >>")
|
110
|
+
write_any("").should == get_erl_with_magic("<< \"\" >>")
|
111
|
+
end
|
112
|
+
|
113
|
+
def get
|
114
|
+
@encoder.out = StringIO.new('', 'w')
|
115
|
+
yield
|
116
|
+
@encoder.out.string
|
117
|
+
end
|
118
|
+
|
119
|
+
def write_any(term)
|
120
|
+
@encoder.out = StringIO.new('', 'w')
|
121
|
+
@encoder.write_any term
|
122
|
+
@encoder.out.string
|
123
|
+
end
|
124
|
+
|
125
|
+
def get_erl(str)
|
126
|
+
get_erl_with_magic(str)[1..-1] #[1..-1] to chop off the magic number
|
127
|
+
end
|
128
|
+
|
129
|
+
def get_erl_with_magic(str)
|
130
|
+
run_erl("term_to_binary(#{str.gsub(/"/, '\\\"')})")
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,69 @@
|
|
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
|
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 |f|
|
9
|
+
f.when Erl.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 |f|
|
21
|
+
f.when(:foo, :foo) do
|
22
|
+
:first
|
23
|
+
end
|
24
|
+
|
25
|
+
f.when(:foo, Erl.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 |f|
|
45
|
+
f.when(:bar) { }
|
46
|
+
f.when(Erl.any) { f.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 |f|
|
56
|
+
f.when(:foo) do
|
57
|
+
f.receive do |g|
|
58
|
+
g.when(:bar){ :ok }
|
59
|
+
end
|
60
|
+
f.receive_loop
|
61
|
+
end
|
62
|
+
|
63
|
+
f.when(: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 |f|
|
75
|
+
f.when(:foo) do
|
76
|
+
f.receive do |g|
|
77
|
+
g.when(:bar){ :ok }
|
78
|
+
end
|
79
|
+
f.receive_loop
|
80
|
+
end
|
81
|
+
|
82
|
+
f.when(: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 |f|
|
95
|
+
f.when(Erl.atom) do |bindinated|
|
96
|
+
results << bindinated
|
97
|
+
f.receive_loop
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
@receiver.run.should == nil
|
102
|
+
results.should == [:foo, :bar, :baz]
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|