frappuccino 0.2.0 → 0.3.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 +4 -4
- data/.travis.yml +10 -4
- data/README.md +15 -10
- data/lib/frappuccino.rb +16 -0
- data/lib/frappuccino/property.rb +32 -4
- data/lib/frappuccino/property/map_property.rb +12 -0
- data/lib/frappuccino/property/toggle_property.rb +16 -0
- data/lib/frappuccino/property/until_property.rb +17 -0
- data/lib/frappuccino/stream.rb +4 -0
- data/lib/frappuccino/version.rb +1 -1
- data/test/lift_test.rb +12 -0
- data/test/map_test.rb +2 -2
- data/test/merge_test.rb +31 -3
- data/test/mvp_test.rb +4 -3
- data/test/property_test.rb +39 -0
- data/test/test_helper.rb +4 -0
- data/test/toggle_test.rb +22 -0
- data/test/until_test.rb +23 -0
- data/test/zip_test.rb +2 -2
- metadata +20 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b25e50a7580dd5fd3e7e286b1ad5b5fd3b22f6f
|
4
|
+
data.tar.gz: e13f31447678e30538171e18a469c3df4a312a9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f24114bd056dee3e4948746618e3d7ef73717ba1b9338ef507899dfbd8ef8208a8971006067373911003b484d7e9e1e970b7907fe79e728f19012244b3424a3
|
7
|
+
data.tar.gz: 9dc5faa55739df468f2ee0bc67e7bdb0d6bf40a566347d55b679ed2ba7f5333978d8fedeef156afef1ca199301f499686bd0e7b4ffbf11c27d0d8c1f3223040a
|
data/.travis.yml
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
-
|
3
|
+
- 1.9.2
|
4
4
|
- 1.9.3
|
5
|
-
-
|
5
|
+
- 2.0.0
|
6
|
+
- 2.1.0
|
6
7
|
- jruby-19mode
|
7
|
-
|
8
|
-
-
|
8
|
+
- rbx-2
|
9
|
+
- ruby-head
|
10
|
+
- jruby-head
|
11
|
+
matrix:
|
12
|
+
allow_failures:
|
13
|
+
- rvm: ruby-head
|
14
|
+
- rvm: jruby-head
|
data/README.md
CHANGED
@@ -9,22 +9,23 @@ Functional Reactive Programming for Ruby.
|
|
9
9
|
Add this line to your application's Gemfile:
|
10
10
|
|
11
11
|
```ruby
|
12
|
-
gem 'frappuccino'
|
12
|
+
gem 'frappuccino'
|
13
13
|
```
|
14
14
|
|
15
|
-
(I'm hoping that @yoka will give me the gem name, until then, you
|
16
|
-
must install from GitHub.)
|
17
|
-
|
18
15
|
And then execute:
|
19
16
|
|
20
|
-
|
17
|
+
``` sh
|
18
|
+
$ bundle
|
19
|
+
```
|
21
20
|
|
22
21
|
Or install it yourself as:
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
``` sh
|
24
|
+
$ git clone https://github.com/steveklabnik/frappuccino
|
25
|
+
$ cd frappuccino
|
26
|
+
$ bundle
|
27
|
+
$ rake install
|
28
|
+
```
|
28
29
|
|
29
30
|
## Usage
|
30
31
|
|
@@ -77,7 +78,11 @@ end
|
|
77
78
|
You can combine two streams together:
|
78
79
|
|
79
80
|
```ruby
|
80
|
-
merged_stream =
|
81
|
+
merged_stream = stream_one.merge(stream_two)
|
82
|
+
|
83
|
+
# or
|
84
|
+
|
85
|
+
merged_stream = Frappuccino::Stream.merge(one_stream , other_stream)
|
81
86
|
|
82
87
|
# or
|
83
88
|
|
data/lib/frappuccino.rb
CHANGED
@@ -1,3 +1,19 @@
|
|
1
1
|
require "frappuccino/version"
|
2
2
|
require "frappuccino/stream"
|
3
3
|
require "frappuccino/property"
|
4
|
+
|
5
|
+
module Frappuccino
|
6
|
+
def self.lift(value)
|
7
|
+
Property.new(value)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Object
|
12
|
+
def method_missing(method, *args, &block)
|
13
|
+
if Frappuccino::Property.method_defined?(method)
|
14
|
+
Frappuccino.lift(self).public_send(method, *args, &block)
|
15
|
+
else
|
16
|
+
super(method, *args, &block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/frappuccino/property.rb
CHANGED
@@ -1,16 +1,44 @@
|
|
1
1
|
module Frappuccino
|
2
2
|
class Property
|
3
|
-
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'frappuccino/property/map_property'
|
7
|
+
require 'frappuccino/property/until_property'
|
8
|
+
require 'frappuccino/property/toggle_property'
|
9
|
+
|
10
|
+
module Frappuccino
|
11
|
+
class Property
|
12
|
+
def initialize(zero, stream = nil)
|
4
13
|
@value = zero
|
5
|
-
|
14
|
+
|
15
|
+
if stream
|
16
|
+
stream.on_value do |value|
|
17
|
+
@value = value
|
18
|
+
end
|
19
|
+
end
|
6
20
|
end
|
7
21
|
|
8
22
|
def now
|
9
23
|
@value
|
10
24
|
end
|
11
25
|
|
12
|
-
def
|
13
|
-
|
26
|
+
def sample(stream)
|
27
|
+
stream.map do
|
28
|
+
self.now
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def until(stream, property)
|
33
|
+
UntilProperty.new(self, stream, property)
|
34
|
+
end
|
35
|
+
|
36
|
+
def toggle(stream, property)
|
37
|
+
ToggleProperty.new(self, stream, property)
|
38
|
+
end
|
39
|
+
|
40
|
+
def map(&blk)
|
41
|
+
MapProperty.new(self, &blk)
|
14
42
|
end
|
15
43
|
end
|
16
44
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Frappuccino
|
2
|
+
class ToggleProperty < Property
|
3
|
+
def initialize(first, switcher, second)
|
4
|
+
@properties = [first, second]
|
5
|
+
@current_index = 0
|
6
|
+
|
7
|
+
switcher.on_value do
|
8
|
+
@current_index = (@current_index + 1) % 2
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def now
|
13
|
+
@properties[@current_index].now
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Frappuccino
|
2
|
+
class UntilProperty < Property
|
3
|
+
def initialize(first, switcher, second)
|
4
|
+
@first = first
|
5
|
+
@second = second
|
6
|
+
@current_prop = @first
|
7
|
+
|
8
|
+
switcher.on_value do |value|
|
9
|
+
@current_prop = @second
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def now
|
14
|
+
@current_prop.now
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/frappuccino/stream.rb
CHANGED
data/lib/frappuccino/version.rb
CHANGED
data/test/lift_test.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe "lift" do
|
4
|
+
it "returns a Property of the value" do
|
5
|
+
prop = Frappuccino.lift("Property")
|
6
|
+
assert_equal("Property", prop.now)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "is automatically applied to any Object" do
|
10
|
+
assert_equal("Property", "Property".now)
|
11
|
+
end
|
12
|
+
end
|
data/test/map_test.rb
CHANGED
@@ -29,7 +29,7 @@ describe "map" do
|
|
29
29
|
stream_one = Frappuccino::Stream.new(plus_button)
|
30
30
|
stream_two = Frappuccino::Stream.new(minus_button)
|
31
31
|
|
32
|
-
merged_stream =
|
32
|
+
merged_stream = stream_one.merge(stream_two)
|
33
33
|
mapped_stream = to_array(merged_stream.map(:+ => 1, :- => -1, :default => 0))
|
34
34
|
|
35
35
|
assert_equal [], mapped_stream
|
@@ -48,7 +48,7 @@ describe "map" do
|
|
48
48
|
stream_one = Frappuccino::Stream.new(plus_button)
|
49
49
|
stream_two = Frappuccino::Stream.new(minus_button)
|
50
50
|
|
51
|
-
merged_stream =
|
51
|
+
merged_stream = stream_one.merge(stream_two)
|
52
52
|
mapped_stream = to_array(merged_stream.map(:default => 1))
|
53
53
|
|
54
54
|
assert_equal [], mapped_stream
|
data/test/merge_test.rb
CHANGED
@@ -7,7 +7,7 @@ describe "merging steams" do
|
|
7
7
|
|
8
8
|
stream_one = Frappuccino::Stream.new(button_one)
|
9
9
|
stream_two = Frappuccino::Stream.new(button_two)
|
10
|
-
merged_stream = to_array(
|
10
|
+
merged_stream = to_array(stream_one.merge(stream_two))
|
11
11
|
|
12
12
|
button_one.push
|
13
13
|
button_two.push
|
@@ -21,8 +21,7 @@ describe "merging steams" do
|
|
21
21
|
|
22
22
|
stream_one = Frappuccino::Stream.new(plus_button)
|
23
23
|
stream_two = Frappuccino::Stream.new(minus_button)
|
24
|
-
|
25
|
-
merged_stream = Frappuccino::Stream.merge(stream_one, stream_two)
|
24
|
+
merged_stream = stream_one.merge(stream_two)
|
26
25
|
counter = merged_stream
|
27
26
|
.map do |event|
|
28
27
|
case event
|
@@ -50,4 +49,33 @@ describe "merging steams" do
|
|
50
49
|
4.times { plus_button.push }
|
51
50
|
assert_equal 2, counter.now
|
52
51
|
end
|
52
|
+
|
53
|
+
it "works if the callee has a different constructor from Stream" do
|
54
|
+
button_one = Button.new
|
55
|
+
button_two = Button.new
|
56
|
+
|
57
|
+
stream_one = Frappuccino::Stream.new(button_one).map { 0 }
|
58
|
+
stream_two = Frappuccino::Stream.new(button_two)
|
59
|
+
|
60
|
+
# This would explode if the merge was calling
|
61
|
+
# self.class.new rather than Stream.new
|
62
|
+
stream_one.merge(stream_two)
|
63
|
+
end
|
53
64
|
end
|
65
|
+
|
66
|
+
|
67
|
+
describe "merging stream with Frappuccino::Stream#merge" do
|
68
|
+
it "produces one stream with both sets of events" do
|
69
|
+
button_one = Button.new
|
70
|
+
button_two = Button.new
|
71
|
+
|
72
|
+
stream_one = Frappuccino::Stream.new(button_one)
|
73
|
+
stream_two = Frappuccino::Stream.new(button_two)
|
74
|
+
merged_stream = to_array(Frappuccino::Stream.merge(stream_one, stream_two))
|
75
|
+
|
76
|
+
button_one.push
|
77
|
+
button_two.push
|
78
|
+
|
79
|
+
assert_equal 2, merged_stream.length
|
80
|
+
end
|
81
|
+
end
|
data/test/mvp_test.rb
CHANGED
@@ -10,13 +10,14 @@ describe "MVP interaction" do
|
|
10
10
|
counter = stream
|
11
11
|
.map {|event| event == :pushed ? 1 : 0 }
|
12
12
|
.inject(0) {|sum, n| sum + n }
|
13
|
+
.map { |val| val.to_s }
|
13
14
|
|
14
|
-
assert_equal 0, counter.now
|
15
|
+
assert_equal "0", counter.now
|
15
16
|
|
16
17
|
3.times { button.push }
|
17
|
-
assert_equal 3, counter.now
|
18
|
+
assert_equal "3", counter.now
|
18
19
|
|
19
20
|
button.push
|
20
|
-
assert_equal 4, counter.now
|
21
|
+
assert_equal "4", counter.now
|
21
22
|
end
|
22
23
|
end
|
data/test/property_test.rb
CHANGED
@@ -19,4 +19,43 @@ describe "Property" do
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
describe "#sample" do
|
24
|
+
before do
|
25
|
+
@counter = CounterButton.new(1)
|
26
|
+
stream = Frappuccino::Stream.new(@counter)
|
27
|
+
prop = Frappuccino::Property.new(0, stream)
|
28
|
+
|
29
|
+
@sampler = Button.new
|
30
|
+
@samples = to_array(prop.sample(Frappuccino::Stream.new(@sampler)))
|
31
|
+
end
|
32
|
+
|
33
|
+
it "has no occurrences initally" do
|
34
|
+
assert_equal @samples, []
|
35
|
+
end
|
36
|
+
|
37
|
+
it "samples the Property when the passed Stream occurs" do
|
38
|
+
@sampler.push
|
39
|
+
assert_equal @samples, [0]
|
40
|
+
|
41
|
+
@counter.push
|
42
|
+
@sampler.push
|
43
|
+
assert_equal @samples, [0, 1]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#map" do
|
48
|
+
it "creates a Property with a mapped value of the original" do
|
49
|
+
button = CounterButton.new(1)
|
50
|
+
stream = Frappuccino::Stream.new(button)
|
51
|
+
prop = Frappuccino::Property.new("0", stream).map do |v|
|
52
|
+
v.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
5.times do |i|
|
56
|
+
assert_equal i.to_s, prop.now
|
57
|
+
button.push
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
22
61
|
end
|
data/test/test_helper.rb
CHANGED
data/test/toggle_test.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe "toggle" do
|
4
|
+
it "toggles between two Properties on stream occurrences" do
|
5
|
+
switch_button = Button.new
|
6
|
+
plus_button = PlusOneButton.new
|
7
|
+
minus_button = MinusOneButton.new
|
8
|
+
|
9
|
+
switch = Frappuccino::Stream.new(switch_button)
|
10
|
+
plus = to_prop(:+, Frappuccino::Stream.new(plus_button))
|
11
|
+
minus = to_prop(:-, Frappuccino::Stream.new(minus_button))
|
12
|
+
|
13
|
+
prop = plus.toggle(switch, minus)
|
14
|
+
assert_equal(:+, prop.now)
|
15
|
+
|
16
|
+
switch_button.push
|
17
|
+
assert_equal(:-, prop.now)
|
18
|
+
|
19
|
+
switch_button.push
|
20
|
+
assert_equal(:+, prop.now)
|
21
|
+
end
|
22
|
+
end
|
data/test/until_test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe "until" do
|
4
|
+
it "switches the Property on the Stream occurring" do
|
5
|
+
switch_button = Button.new
|
6
|
+
plus_button = PlusOneButton.new
|
7
|
+
minus_button = MinusOneButton.new
|
8
|
+
|
9
|
+
switch = Frappuccino::Stream.new(switch_button)
|
10
|
+
plus = to_prop(:notplus, Frappuccino::Stream.new(plus_button))
|
11
|
+
minus = to_prop(:notminus, Frappuccino::Stream.new(minus_button))
|
12
|
+
|
13
|
+
prop = plus.until(switch, minus)
|
14
|
+
assert_equal(:notplus, prop.now)
|
15
|
+
|
16
|
+
plus_button.push
|
17
|
+
assert_equal(:+, prop.now)
|
18
|
+
|
19
|
+
minus_button.push
|
20
|
+
switch_button.push
|
21
|
+
assert_equal(:-, prop.now)
|
22
|
+
end
|
23
|
+
end
|
data/test/zip_test.rb
CHANGED
@@ -27,7 +27,7 @@ describe "zip" do
|
|
27
27
|
|
28
28
|
zipped_stream = to_array(stream1.zip(stream2))
|
29
29
|
|
30
|
-
2.times do
|
30
|
+
2.times do
|
31
31
|
button1.push
|
32
32
|
assert_equal [], zipped_stream, "zipped stream occurred too early"
|
33
33
|
end
|
@@ -49,7 +49,7 @@ describe "zip" do
|
|
49
49
|
|
50
50
|
zipped_stream = to_array(stream1.zip(stream2))
|
51
51
|
|
52
|
-
2.times do
|
52
|
+
2.times do
|
53
53
|
button2.push
|
54
54
|
assert_equal [], zipped_stream, "zipped stream occurred too early"
|
55
55
|
end
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: frappuccino
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Klabnik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
description: A library to do Functional Reactive Programming in Ruby.
|
@@ -45,8 +45,8 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
-
- .gitignore
|
49
|
-
- .travis.yml
|
48
|
+
- ".gitignore"
|
49
|
+
- ".travis.yml"
|
50
50
|
- Gemfile
|
51
51
|
- LICENSE.txt
|
52
52
|
- README.md
|
@@ -54,6 +54,9 @@ files:
|
|
54
54
|
- frappuccino.gemspec
|
55
55
|
- lib/frappuccino.rb
|
56
56
|
- lib/frappuccino/property.rb
|
57
|
+
- lib/frappuccino/property/map_property.rb
|
58
|
+
- lib/frappuccino/property/toggle_property.rb
|
59
|
+
- lib/frappuccino/property/until_property.rb
|
57
60
|
- lib/frappuccino/source.rb
|
58
61
|
- lib/frappuccino/stream.rb
|
59
62
|
- lib/frappuccino/stream/drop.rb
|
@@ -64,6 +67,7 @@ files:
|
|
64
67
|
- lib/frappuccino/stream/zip.rb
|
65
68
|
- lib/frappuccino/version.rb
|
66
69
|
- test/drop_test.rb
|
70
|
+
- test/lift_test.rb
|
67
71
|
- test/map_test.rb
|
68
72
|
- test/merge_test.rb
|
69
73
|
- test/mvp_test.rb
|
@@ -76,6 +80,8 @@ files:
|
|
76
80
|
- test/stream_test.rb
|
77
81
|
- test/take_test.rb
|
78
82
|
- test/test_helper.rb
|
83
|
+
- test/toggle_test.rb
|
84
|
+
- test/until_test.rb
|
79
85
|
- test/zip_test.rb
|
80
86
|
homepage: https://github.com/steveklabnik/frappuccino
|
81
87
|
licenses:
|
@@ -87,22 +93,23 @@ require_paths:
|
|
87
93
|
- lib
|
88
94
|
required_ruby_version: !ruby/object:Gem::Requirement
|
89
95
|
requirements:
|
90
|
-
- -
|
96
|
+
- - ">="
|
91
97
|
- !ruby/object:Gem::Version
|
92
98
|
version: '0'
|
93
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
100
|
requirements:
|
95
|
-
- -
|
101
|
+
- - ">="
|
96
102
|
- !ruby/object:Gem::Version
|
97
103
|
version: '0'
|
98
104
|
requirements: []
|
99
105
|
rubyforge_project:
|
100
|
-
rubygems_version: 2.
|
106
|
+
rubygems_version: 2.2.2
|
101
107
|
signing_key:
|
102
108
|
specification_version: 4
|
103
109
|
summary: Functional Reactive Programming in Ruby.
|
104
110
|
test_files:
|
105
111
|
- test/drop_test.rb
|
112
|
+
- test/lift_test.rb
|
106
113
|
- test/map_test.rb
|
107
114
|
- test/merge_test.rb
|
108
115
|
- test/mvp_test.rb
|
@@ -115,5 +122,6 @@ test_files:
|
|
115
122
|
- test/stream_test.rb
|
116
123
|
- test/take_test.rb
|
117
124
|
- test/test_helper.rb
|
125
|
+
- test/toggle_test.rb
|
126
|
+
- test/until_test.rb
|
118
127
|
- test/zip_test.rb
|
119
|
-
has_rdoc:
|