erlectricity 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|