frappuccino 0.0.1 → 0.2.0
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.
- 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
|