erlectricity 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/Manifest.txt +41 -0
  2. data/README.txt +3 -0
  3. data/Rakefile +68 -0
  4. data/examples/gruff/gruff.erl +62 -0
  5. data/examples/gruff/gruff_provider.rb +38 -0
  6. data/examples/gruff/gruff_run.erl +17 -0
  7. data/examples/gruff/stat_run.erl +18 -0
  8. data/examples/gruff/stat_writer.erl +40 -0
  9. data/examples/tinderl/tinderl.erl +41 -0
  10. data/examples/tinderl/tinderl.rb +23 -0
  11. data/lib/erlectricity/condition.rb +48 -0
  12. data/lib/erlectricity/conditions/hash.rb +15 -0
  13. data/lib/erlectricity/conditions/static.rb +17 -0
  14. data/lib/erlectricity/conditions/type.rb +19 -0
  15. data/lib/erlectricity/constants.rb +37 -0
  16. data/lib/erlectricity/decoder.rb +202 -0
  17. data/lib/erlectricity/encoder.rb +127 -0
  18. data/lib/erlectricity/errors/decode_error.rb +3 -0
  19. data/lib/erlectricity/errors/encode_error.rb +3 -0
  20. data/lib/erlectricity/errors/erlectricity_error.rb +3 -0
  21. data/lib/erlectricity/match_context.rb +20 -0
  22. data/lib/erlectricity/matcher.rb +60 -0
  23. data/lib/erlectricity/port.rb +46 -0
  24. data/lib/erlectricity/receiver.rb +74 -0
  25. data/lib/erlectricity/types/function.rb +3 -0
  26. data/lib/erlectricity/types/new_function.rb +3 -0
  27. data/lib/erlectricity/types/new_reference.rb +3 -0
  28. data/lib/erlectricity/types/pid.rb +3 -0
  29. data/lib/erlectricity/types/reference.rb +3 -0
  30. data/lib/erlectricity/version.rb +9 -0
  31. data/lib/erlectricity.rb +23 -0
  32. data/setup.rb +1585 -0
  33. data/test/condition_spec.rb +78 -0
  34. data/test/decode_spec.rb +133 -0
  35. data/test/encode_spec.rb +125 -0
  36. data/test/matcher_spec.rb +73 -0
  37. data/test/port_spec.rb +35 -0
  38. data/test/receiver_spec.rb +105 -0
  39. data/test/spec_suite.rb +2 -0
  40. data/test/test_erlectricity.rb +2 -0
  41. data/test/test_helper.rb +36 -0
  42. 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
@@ -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
@@ -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
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ Dir[File.dirname(__FILE__) + '/*_spec.rb'].each{ |f| require f}
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
@@ -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
+