frappuccino 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ module Frappuccino
2
+ class Drop < Stream
3
+ def initialize(source, n)
4
+ source.add_observer(self)
5
+
6
+ @dropped = 0
7
+ @n = n
8
+ end
9
+
10
+ def update(event)
11
+ @dropped += 1
12
+
13
+ if @dropped > @n
14
+ occur(event)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ module Frappuccino
2
+ class Map < Stream
3
+ def initialize(source, &blk)
4
+ @block = blk
5
+ source.add_observer(self)
6
+ end
7
+
8
+ def update(event)
9
+ occur(@block.call(event))
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module Frappuccino
2
+ class Scan < Stream
3
+ def initialize(source, zero, &blk)
4
+ @last = zero
5
+ @block = blk
6
+
7
+ source.add_observer(self)
8
+ end
9
+
10
+ def update(value)
11
+ @last = @block.call(@last, value)
12
+ occur(@last)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module Frappuccino
2
+ class Select < Stream
3
+ def initialize(source, &blk)
4
+ @block = blk
5
+ source.add_observer(self)
6
+ end
7
+
8
+ def update(event)
9
+ if @block.call(event)
10
+ occur(event)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module Frappuccino
2
+ class Take < Stream
3
+ def initialize(source, n)
4
+ @n = n
5
+ @length = 0
6
+ source.add_observer(self)
7
+ end
8
+
9
+ def update(value)
10
+ if @length < @n
11
+ occur(value)
12
+ @length += 1
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ module Frappuccino
2
+ class Zip < Stream
3
+ def initialize(left, right)
4
+ @left_buffer = []
5
+ @right_buffer = []
6
+ left.add_observer(self, :left_update)
7
+ right.add_observer(self, :right_update)
8
+ end
9
+
10
+ def left_update(event)
11
+ if @right_buffer.length > 0
12
+ occur([event, @right_buffer.shift])
13
+ else
14
+ @left_buffer << event
15
+ end
16
+ end
17
+
18
+ def right_update(event)
19
+ if @left_buffer.length > 0
20
+ occur([@left_buffer.shift, event])
21
+ else
22
+ @right_buffer << event
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Frappuccino
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ describe "drop" do
4
+ it "ignores the first n events" do
5
+ button = CounterButton.new
6
+ stream = Frappuccino::Stream.new(button)
7
+ dropped_stream = to_array(stream.drop(3))
8
+
9
+ 5.times { button.push }
10
+ assert_equal 2, dropped_stream.length
11
+ assert_equal [3, 4], dropped_stream
12
+ end
13
+ end
@@ -0,0 +1,80 @@
1
+ require 'test_helper'
2
+
3
+ describe "map" do
4
+ it "can take callbacks" do
5
+ button = Button.new
6
+
7
+ stream = Frappuccino::Stream.new(button)
8
+
9
+ filtered_stream = stream
10
+ .map{|event| 1 }
11
+
12
+ count = 0
13
+
14
+ filtered_stream.on_value do |event|
15
+ count += event
16
+ end
17
+
18
+ button.push
19
+ button.push
20
+ button.push
21
+
22
+ assert_equal 3, count
23
+ end
24
+
25
+ it "maps events to values" do
26
+ plus_button = PlusOneButton.new
27
+ minus_button = MinusOneButton.new
28
+
29
+ stream_one = Frappuccino::Stream.new(plus_button)
30
+ stream_two = Frappuccino::Stream.new(minus_button)
31
+
32
+ merged_stream = Frappuccino::Stream.merge(stream_one, stream_two)
33
+ mapped_stream = to_array(merged_stream.map(:+ => 1, :- => -1, :default => 0))
34
+
35
+ assert_equal [], mapped_stream
36
+
37
+ plus_button.push
38
+ assert_equal [1], mapped_stream
39
+
40
+ minus_button.push
41
+ assert_equal [1, -1], mapped_stream
42
+ end
43
+
44
+ it "respects the default value of the hash" do
45
+ plus_button = PlusOneButton.new
46
+ minus_button = MinusOneButton.new
47
+
48
+ stream_one = Frappuccino::Stream.new(plus_button)
49
+ stream_two = Frappuccino::Stream.new(minus_button)
50
+
51
+ merged_stream = Frappuccino::Stream.merge(stream_one, stream_two)
52
+ mapped_stream = to_array(merged_stream.map(:default => 1))
53
+
54
+ assert_equal [], mapped_stream
55
+
56
+ plus_button.push
57
+ minus_button.push
58
+ assert_equal [1, 1], mapped_stream
59
+ end
60
+ end
61
+
62
+ describe "collect" do
63
+ it "is a synonym for #map" do
64
+ stream = Frappuccino::Stream.new(nil)
65
+
66
+ map = stream.collect{|event| 1 }
67
+
68
+ assert_kind_of Frappuccino::Map, map
69
+ end
70
+ end
71
+
72
+ describe "#map_stream" do
73
+ it "is a synonym for #map" do
74
+ stream = Frappuccino::Stream.new(nil)
75
+
76
+ map = stream.map_stream(:default => 1)
77
+
78
+ assert_kind_of Frappuccino::Map, map
79
+ end
80
+ end
@@ -0,0 +1,53 @@
1
+ require 'test_helper'
2
+
3
+ describe "merging steams" do
4
+ it "produces one stream with both sets of events" do
5
+ button_one = Button.new
6
+ button_two = Button.new
7
+
8
+ stream_one = Frappuccino::Stream.new(button_one)
9
+ stream_two = Frappuccino::Stream.new(button_two)
10
+ merged_stream = to_array(Frappuccino::Stream.merge(stream_one, stream_two))
11
+
12
+ button_one.push
13
+ button_two.push
14
+
15
+ assert_equal 2, merged_stream.length
16
+ end
17
+
18
+ it "+1/-1" do
19
+ plus_button = PlusOneButton.new
20
+ minus_button = MinusOneButton.new
21
+
22
+ stream_one = Frappuccino::Stream.new(plus_button)
23
+ stream_two = Frappuccino::Stream.new(minus_button)
24
+
25
+ merged_stream = Frappuccino::Stream.merge(stream_one, stream_two)
26
+ counter = merged_stream
27
+ .map do |event|
28
+ case event
29
+ when :+
30
+ 1
31
+ when :-
32
+ -1
33
+ else
34
+ 0
35
+ end
36
+ end
37
+ .inject(0) {|sum, n| sum + n }
38
+
39
+ assert_equal 0, counter.now
40
+
41
+ plus_button.push
42
+ assert_equal 1, counter.now
43
+
44
+ minus_button.push
45
+ assert_equal 0, counter.now
46
+
47
+ 2.times { minus_button.push }
48
+ assert_equal(-2, counter.now)
49
+
50
+ 4.times { plus_button.push }
51
+ assert_equal 2, counter.now
52
+ end
53
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ require 'frappuccino'
4
+
5
+ describe "MVP interaction" do
6
+ it "can subscribe to an event stream" do
7
+ button = Button.new
8
+ stream = Frappuccino::Stream.new(button)
9
+
10
+ counter = stream
11
+ .map {|event| event == :pushed ? 1 : 0 }
12
+ .inject(0) {|sum, n| sum + n }
13
+
14
+ assert_equal 0, counter.now
15
+
16
+ 3.times { button.push }
17
+ assert_equal 3, counter.now
18
+
19
+ button.push
20
+ assert_equal 4, counter.now
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ describe "not implemented methods" do
4
+ [:all?,
5
+ :any?,
6
+ :chunk,
7
+ :cycle,
8
+ :find,
9
+ :detect,
10
+ ].each do |m|
11
+ it "#{m} is not implemented because it's nonsensical" do
12
+ assert_raises(NotImplementedError) do
13
+ stream = Frappuccino::Stream.new(nil)
14
+ stream.send(m)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,75 @@
1
+ require 'test_helper'
2
+
3
+ describe "#on_value" do
4
+ it "calls the block on a value" do
5
+ button = Button.new
6
+ stream = Frappuccino::Stream.new(button)
7
+
8
+ event = false
9
+
10
+ stream.on_value do |value|
11
+ event = value
12
+ end
13
+
14
+ button.push
15
+
16
+ assert_equal :pushed, event, "#on_value did not call back."
17
+ end
18
+
19
+ it "allows for multiple callbacks per Stream" do
20
+ button = Button.new
21
+ stream = Frappuccino::Stream.new(button)
22
+
23
+ callback1 = false
24
+ callback2 = false
25
+
26
+ stream.on_value do |value|
27
+ callback1 = value
28
+ end
29
+
30
+ stream.on_value do |value|
31
+ callback2 = value
32
+ end
33
+
34
+ button.push
35
+
36
+ assert_equal :pushed, callback1, "#on_value did not call first callback"
37
+ assert_equal :pushed, callback2, "#on_value did not call second callback"
38
+ end
39
+
40
+ it "works with mapped Streams" do
41
+ button = Button.new
42
+ stream = Frappuccino::Stream.new(button)
43
+
44
+ callback = false
45
+
46
+ stream.map { |val| :true }.on_value do |val|
47
+ callback = val
48
+ end
49
+
50
+ button.push
51
+
52
+ assert_equal :true, callback, "#on_value did not call back."
53
+ end
54
+
55
+ it "works with filtered Streams" do
56
+ button = Button.new
57
+ stream = Frappuccino::Stream.new(button)
58
+
59
+ callback = false
60
+ should = true
61
+
62
+ stream.select { |val| should }.on_value do |val|
63
+ callback = val
64
+ end
65
+
66
+ button.push
67
+ assert_equal :pushed, callback, "#on_value did not call back."
68
+
69
+ should = false
70
+ callback = :didnot
71
+ button.push
72
+
73
+ assert_equal :didnot, callback, "#on_value did call back."
74
+ end
75
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ describe "Property" do
4
+ describe "#now" do
5
+ it "returns the current 'last' value of the Stream" do
6
+ button = Button.new
7
+ stream = Frappuccino::Stream.new(button)
8
+ stepper = Frappuccino::Property.new(:not_pushed, stream)
9
+
10
+ button.push
11
+ assert_equal :pushed, stepper.now
12
+ end
13
+
14
+ describe "when the input Stream is empty" do
15
+ it "returns the zero value" do
16
+ stream = Frappuccino::Stream.new(Object.new)
17
+ stepper = Frappuccino::Property.new("zero", stream)
18
+ assert_equal "zero", stepper.now
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ describe "scan" do
4
+ it "returns a stream where every element is the result of the passed block applied to the last result and the current element" do
5
+ button = Button.new
6
+ stream = Frappuccino::Stream.new(button)
7
+ count_stream = to_array(stream.scan(0) { |last, current|
8
+ last + 1
9
+ })
10
+
11
+ 5.times { button.push }
12
+ assert_equal [1,2,3,4,5], count_stream
13
+ end
14
+ end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ describe "#select" do
4
+ it "properly filters events from the stream" do
5
+ points = Points.new
6
+ button = Button.new
7
+
8
+ stream = Frappuccino::Stream.new(points, button)
9
+
10
+ filtered_stream = to_array(stream.select{|event| event == :POINTS! })
11
+
12
+ 9.times { points.POINTS! }
13
+ 9.times { button.push }
14
+
15
+ assert_equal 9, filtered_stream.length
16
+ assert_equal true, filtered_stream.all? { |event| event == :POINTS! }
17
+ end
18
+
19
+ it "has #on_value" do
20
+ points = Points.new
21
+ button = Button.new
22
+
23
+ stream = Frappuccino::Stream.new(points, button)
24
+
25
+ filtered_stream = stream
26
+ .select{|event| event == :POINTS! }
27
+
28
+ count = 0
29
+
30
+ filtered_stream.on_value do |event|
31
+ count += 1
32
+ end
33
+
34
+ points.POINTS!
35
+ points.POINTS!
36
+ button.push
37
+
38
+ assert_equal 2, count
39
+ end
40
+ end