frappuccino 0.0.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +8 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +104 -0
- data/Rakefile +12 -0
- data/frappuccino.gemspec +23 -0
- data/lib/frappuccino.rb +3 -140
- data/lib/frappuccino/property.rb +16 -0
- data/lib/frappuccino/source.rb +14 -0
- data/lib/frappuccino/stream.rb +112 -0
- data/lib/frappuccino/stream/drop.rb +18 -0
- data/lib/frappuccino/stream/map.rb +12 -0
- data/lib/frappuccino/stream/scan.rb +15 -0
- data/lib/frappuccino/stream/select.rb +14 -0
- data/lib/frappuccino/stream/take.rb +16 -0
- data/lib/frappuccino/stream/zip.rb +26 -0
- data/lib/frappuccino/version.rb +3 -0
- data/test/drop_test.rb +13 -0
- data/test/map_test.rb +80 -0
- data/test/merge_test.rb +53 -0
- data/test/mvp_test.rb +22 -0
- data/test/not_implemented_test.rb +18 -0
- data/test/on_value_test.rb +75 -0
- data/test/property_test.rb +22 -0
- data/test/scan_test.rb +14 -0
- data/test/select_test.rb +40 -0
- data/test/source_test.rb +14 -0
- data/test/stream_test.rb +44 -0
- data/test/take_test.rb +13 -0
- data/test/test_helper.rb +66 -0
- data/test/zip_test.rb +64 -0
- metadata +106 -46
- data/bin/frappuccino +0 -8
- data/template/bg.png +0 -0
- data/template/index.erb +0 -191
@@ -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
|
data/test/drop_test.rb
ADDED
@@ -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
|
data/test/map_test.rb
ADDED
@@ -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
|
data/test/merge_test.rb
ADDED
@@ -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
|
data/test/mvp_test.rb
ADDED
@@ -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
|
data/test/scan_test.rb
ADDED
@@ -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
|
data/test/select_test.rb
ADDED
@@ -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
|