reacto 0.0.0 → 0.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 00345a7d238aab953495d04d30b70de59a43b452
4
- data.tar.gz: bf82a8089e0b732e456c14a8100d8f8ecf260370
3
+ metadata.gz: 8c3be32892f6d090d99fad277060c0a6594eff2f
4
+ data.tar.gz: 8cf5362fb0e3a1de7d6a7ab8c30fa6afd78cba97
5
5
  SHA512:
6
- metadata.gz: 552be561f5bec4bc6ab3b75f1f814b5d326dbae95328e83334d17811fcc0a23a6259ae946905fed819700a62d2b61d7119d2f378eddc479bc2518def7308194b
7
- data.tar.gz: 972a2db20596802f0957760eadf2b58901bcd20d08211f9332ef633fd1f707833a1ca4f0bc4a07b151c0e3bc1bdf4baea8c5b1e813500c8556a01f7541497766
6
+ metadata.gz: 60e81798750a652579e0834810f80352c0c6fb3418c35f062ee82efd26f2ec44f9211e149324ec5da9b6e4547aaca700bac123aef4333725ee2a19eb3c63812e
7
+ data.tar.gz: bc7528738e9e26c73eb513075c6ebea36870eb9c0d396672391130abfdf1862ed0a44dd1b7db751e1fcf9617ad6d432a5c558fe825e996c36535cdd207ea386a
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
@@ -16,8 +16,14 @@ module Reacto
16
16
  trackable.do_track subscription.subscription!
17
17
  end
18
18
 
19
+ close = lambda do
20
+ return unless subscription.closed?
21
+
22
+ tracker.on_close
23
+ end
24
+
19
25
  Subscriptions::OperationSubscription.new(
20
- tracker, value: value
26
+ tracker, value: value, close: close
21
27
  )
22
28
  end
23
29
  end
@@ -0,0 +1,37 @@
1
+ require 'reacto/subscriptions/operation_subscription'
2
+
3
+ module Reacto
4
+ module Operations
5
+ class FlatMapLatest
6
+ def initialize(transform)
7
+ @transform = transform
8
+ @last_active = nil
9
+ end
10
+
11
+ def call(tracker)
12
+ subscription = Subscriptions::FlatMapSubscription.new(tracker)
13
+ value = lambda do |v|
14
+ trackable = @transform.call(v)
15
+
16
+ sub = subscription.subscription!
17
+
18
+ @last_active.unsubscribe if @last_active
19
+ trackable.do_track sub
20
+ @last_active = sub
21
+ end
22
+
23
+ close = lambda do
24
+ return unless subscription.closed?
25
+
26
+ tracker.on_close
27
+ end
28
+
29
+ Subscriptions::OperationSubscription.new(
30
+ tracker, value: value, close: close
31
+ )
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+
@@ -15,6 +15,7 @@ require 'reacto/operations/uniq'
15
15
  require 'reacto/operations/flatten'
16
16
  require 'reacto/operations/throttle'
17
17
  require 'reacto/operations/flat_map'
18
+ require 'reacto/operations/flat_map_latest'
18
19
 
19
20
  module Reacto
20
21
  module Operations
@@ -63,6 +63,10 @@ module Reacto
63
63
  @subscriber.on_error(e)
64
64
  end
65
65
 
66
+ def closed?
67
+ @subscriptions.all? { |s| s.closed? }
68
+ end
69
+
66
70
  def on_close
67
71
  return unless subscribed?
68
72
  return unless @subscriptions.any? { |s| !s.closed? }
@@ -1,3 +1,5 @@
1
+ require 'forwardable'
2
+
1
3
  require 'reacto/subscriptions/subscription'
2
4
 
3
5
  module Reacto
@@ -204,6 +204,10 @@ module Reacto
204
204
  lift(Operations::FlatMap.new(block_given? ? block : transform))
205
205
  end
206
206
 
207
+ def flat_map_latest(transform = nil, &block)
208
+ lift(Operations::FlatMapLatest.new(block_given? ? block : transform))
209
+ end
210
+
207
211
  def map(mapping = nil, error: nil, close: nil, &block)
208
212
  lift(Operations::Map.new(
209
213
  block_given? ? block : mapping, error: error, close: close
@@ -1,4 +1,4 @@
1
1
  module Reacto
2
- VERSION = '0.0.0'
2
+ VERSION = '0.0.1'
3
3
  end
4
4
 
@@ -1,15 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  context Reacto::Trackable do
4
-
5
- context '.never' do
6
- it 'creates a new trackable, which won\'t send any notifications' do
7
- attach_test_trackers described_class.never
8
-
9
- expect(test_data).to be_empty
10
- end
11
- end
12
-
13
4
  context '.error' do
14
5
  it 'creates a new trackable emitting only the error passed' do
15
6
  err = StandardError.new('Errrr')
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context '.never' do
5
+ it 'creates a new trackable, which won\'t send any notifications' do
6
+ attach_test_trackers described_class.never
7
+
8
+ expect(test_data).to be_empty
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context '#concat' do
5
+ it 'starts emitting the values from the concatenated after emitting the ' \
6
+ 'values from the source, then emits a `close` notification' do
7
+ trackable = source.concat(described_class.enumerable((6..10)))
8
+ trackable.on(value: test_on_value, close: test_on_close)
9
+
10
+ expect(test_data).to be == (5..10).to_a + ['|']
11
+ end
12
+
13
+ it 'can be chained' do
14
+ trackable = source
15
+ .concat(described_class.enumerable((6..8)))
16
+ .concat(described_class.enumerable((9..10)))
17
+ trackable.on(value: test_on_value, close: test_on_close)
18
+
19
+ expect(test_data).to be == (5..10).to_a + ['|']
20
+ end
21
+
22
+ it 'closes on error' do
23
+ err = StandardError.new('Hey')
24
+ trackable = source
25
+ .concat(described_class.error(err))
26
+ .concat(described_class.enumerable((9..10)))
27
+ trackable.on(
28
+ value: test_on_value, close: test_on_close, error: test_on_error
29
+ )
30
+
31
+ expect(test_data).to be == [5, err]
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context '#diff' do
5
+ it 'by default emits arrays with two values the - previous and current ' \
6
+ 'element' do
7
+ source = described_class.enumerable((1..10))
8
+ trackable = source.diff
9
+ trackable.on(value: test_on_value, error: test_on_error)
10
+
11
+ expect(test_data).to be == [
12
+ [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10
13
+ ]]
14
+ end
15
+
16
+ it 'can be passed a diff function to calculate the difference between ' \
17
+ 'the previously emitted value and the current and to emit it' do
18
+ source = described_class.enumerable((1..10))
19
+ trackable = source.diff(Reacto::NO_VALUE, -> (p, c) { c - p })
20
+ trackable.on(value: test_on_value, error: test_on_error)
21
+
22
+ expect(test_data).to be == [1] * 9
23
+ end
24
+
25
+ it 'can be passed a diff block to calculate the difference between ' \
26
+ 'the previously emitted value and the current and to emit it' do
27
+ source = described_class.enumerable((1..10))
28
+ trackable = source.diff { |p, c| c - p }
29
+ trackable.on(value: test_on_value, error: test_on_error)
30
+
31
+ expect(test_data).to be == [1] * 9
32
+ end
33
+
34
+ it 'can receive initial value to be used as seed - the first value' do
35
+ source = described_class.enumerable((1..10))
36
+ trackable = source.diff(-5) { |p, c| c - p }
37
+ trackable.on(value: test_on_value, error: test_on_error)
38
+
39
+ expect(test_data).to be == [6] + ([1] * 9)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context '#drop_errors' do
5
+ it 'drops all the errors from the source and continues' do
6
+ described_class.enumerable((1..5)).concat(
7
+ described_class.error(StandardError.new)
8
+ ).concat(described_class.enumerable(6..10)).drop_errors.on(
9
+ value: test_on_value, error: test_on_error, close: test_on_close
10
+ )
11
+
12
+ expect(test_data).to be == (1..10).to_a + ['|']
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context 'flat_map_latest' do
5
+ it 'TODO' do
6
+ trackable = described_class.interval(1).take(3).flat_map_latest do |val|
7
+ Reacto::Trackable.interval(0.3, (val..7).to_enum)
8
+ end
9
+
10
+ subscription = trackable.on(
11
+ value: test_on_value, close: test_on_close, error: test_on_error
12
+ )
13
+
14
+ trackable.await(subscription)
15
+ expect(test_data).to be == [0, 1, 2, 1, 2, 3, 2, 3, 4, 5, 6, 7, '|']
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context 'flat_map' do
5
+ it 'flattens the notification of the Trackable objects produced by ' \
6
+ 'the passed transformation function and turns them to one stream of ' \
7
+ 'notifications' do
8
+ trackable = described_class.enumerable((1..5)).flat_map do |val|
9
+ Reacto::Trackable.enumerable([val, val + 1])
10
+ end
11
+
12
+ trackable.on(
13
+ value: test_on_value, close: test_on_close, error: test_on_error
14
+ )
15
+ expect(test_data).to be == [1, 2, 2, 3, 3, 4, 4, 5, 5, 6, '|']
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context 'flatten' do
5
+ it 'sends the members of array values as values' do
6
+ trackable =
7
+ described_class.enumerable([[1, 2, 3], [4, 3], [2, 1, 5]]).flatten
8
+
9
+ trackable.on(
10
+ value: test_on_value, close: test_on_close, error: test_on_error
11
+ )
12
+ expect(test_data).to be == [1, 2, 3, 4, 3, 2, 1, 5, '|']
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context '#inject' do
5
+ let(:test_behaviour) do
6
+ lambda do |tracker_subscription|
7
+ [16, 7, 2014].each do |value|
8
+ tracker_subscription.on_value(value)
9
+ end
10
+
11
+ tracker_subscription.on_close
12
+ end
13
+ end
14
+
15
+ it 'sends the values created by applying the `inject` operation on the ' \
16
+ 'last value and current value, using for first value the initial one' do
17
+ trackable = source.inject(0) do |prev, v|
18
+ prev + v
19
+ end
20
+ trackable.on(value: test_on_value)
21
+
22
+ expect(test_data.size).to be(3)
23
+ expect(test_data).to be == [16, 23, 2037]
24
+ end
25
+
26
+ it 'sends the values created by applying the `inject` operation on the ' \
27
+ 'last value and current value, using for first value ' \
28
+ 'the first emitted by the source if no initial value provided' do
29
+ trackable = source.inject do |prev, v|
30
+ prev + v
31
+ end
32
+ trackable.on(value: test_on_value)
33
+
34
+ expect(test_data.size).to be(3)
35
+ expect(test_data).to be == [16, 23, 2037]
36
+ end
37
+
38
+ it 'sends the initial value if no value is emitted' do
39
+ source = described_class.new(-> (t) { t.on_close })
40
+ trackable = source.inject(0) do |prev, v|
41
+ prev + v
42
+ end
43
+ trackable.on(value: test_on_value)
44
+
45
+ expect(test_data.size).to be(1)
46
+ expect(test_data).to be == [0]
47
+ end
48
+
49
+ it 'sends nothing if no initial value and no value emitted' do
50
+ source = described_class.new(-> (t) { t.on_close })
51
+ trackable = source.inject do |prev, v|
52
+ prev + v
53
+ end
54
+ trackable.on(value: test_on_value)
55
+
56
+ expect(test_data.size).to be(0)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context '#merge' do
5
+ it 'merges the passed trackable\'s emitions with the source ones' do
6
+ trackable =
7
+ described_class.interval(0.2).map { |v| v.to_s + 'a'}.take(5)
8
+ to_be_merged =
9
+ described_class.interval(0.35).map { |v| v.to_s + 'b'}.take(4)
10
+ subscription = trackable.merge(to_be_merged).on(
11
+ value: test_on_value, close: test_on_close, error: test_on_error
12
+ )
13
+ trackable.await(subscription)
14
+
15
+ expect(test_data).to be ==
16
+ ["0a", "0b", "1a", "2a", "1b", "3a", "4a", "2b", "3b", "|"]
17
+ end
18
+
19
+ it 'finishes with the error if `delay_error` is true' do
20
+ err = StandardError.new('Hey')
21
+ trackable = described_class.interval(0.2).map do |v|
22
+ raise err if v == 3
23
+ v.to_s + 'a'
24
+ end.take(5)
25
+
26
+ to_be_merged =
27
+ described_class.interval(0.35).map { |v| v.to_s + 'b'}.take(4)
28
+
29
+ trackable = trackable.merge(to_be_merged, delay_error: true)
30
+ subscription = trackable.on(
31
+ value: test_on_value, close: test_on_close, error: test_on_error
32
+ )
33
+ trackable.await(subscription, 2)
34
+
35
+ expect(test_data).to be ==
36
+ ["0a", "0b", "1a", "2a", "1b", "2b", "3b", err]
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context '#drop, #take, #last, #first, #[]' do
5
+ let(:test_behaviour) do
6
+ lambda do |tracker_subscription|
7
+ (1..15).each do |value|
8
+ tracker_subscription.on_value(value)
9
+ end
10
+
11
+ tracker_subscription.on_close
12
+ end
13
+ end
14
+
15
+ context('#drop') do
16
+ it 'drops the first `n` values sent by the source' do
17
+ source.drop(6).on(value: test_on_value)
18
+
19
+ expect(test_data.size).to be(9)
20
+ expect(test_data).to be == (7..15).to_a
21
+ end
22
+ end
23
+
24
+ context('#take') do
25
+ it 'sents only the first `n` values sent by the source' do
26
+ source.take(6).on(value: test_on_value)
27
+
28
+ expect(test_data.size).to be(6)
29
+ expect(test_data).to be == (1..6).to_a
30
+ end
31
+ end
32
+
33
+ context('#last') do
34
+ it 'emits only the last value of the source and the closing ' \
35
+ 'notification' do
36
+ source.last.on(value: test_on_value, close: test_on_close)
37
+
38
+ expect(test_data).to be == [15, '|']
39
+ end
40
+
41
+ it 'only closes if no value was emitted by the source' do
42
+ described_class.close.last.on(
43
+ value: test_on_value, close: test_on_close
44
+ )
45
+
46
+ expect(test_data).to be == ['|']
47
+ end
48
+
49
+ it 'emits the last value before the error and the error when error ' \
50
+ 'notification is received from the source' do
51
+ err = StandardError.new('Hey!')
52
+ source.concat(described_class.error(err)).last.on(
53
+ value: test_on_value, close: test_on_close, error: test_on_error
54
+ )
55
+
56
+ expect(test_data).to be == [15, err]
57
+ end
58
+ end
59
+
60
+ context('#first') do
61
+ it 'emits only the first value of the source and closes' do
62
+ source.first.on(
63
+ value: test_on_value, close: test_on_close
64
+ )
65
+
66
+ expect(test_data).to be == [1, '|']
67
+ end
68
+
69
+ it 'only closes if no value was emitted by the source' do
70
+ described_class.close.first.on(
71
+ value: test_on_value, close: test_on_close
72
+ )
73
+
74
+ expect(test_data).to be == ['|']
75
+ end
76
+ end
77
+
78
+ context('#[]') do
79
+ it 'emits only the n-th value of the source and closes' do
80
+ source[4].on(
81
+ value: test_on_value, close: test_on_close
82
+ )
83
+
84
+ expect(test_data).to be == [5, '|']
85
+ end
86
+
87
+ it 'just closes if no value was emitted by the source' do
88
+ described_class.close[3].on(
89
+ value: test_on_value, close: test_on_close
90
+ )
91
+
92
+ expect(test_data).to be == ['|']
93
+ end
94
+ end
95
+ end
96
+ end
@@ -12,4 +12,3 @@ context Reacto::Trackable do
12
12
  end
13
13
  end
14
14
  end
15
-
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ context Reacto::Trackable do
4
+ context 'uniq' do
5
+ it 'sends only uniq values, dropping the repeating ones' do
6
+ trackable =
7
+ described_class.enumerable([1, 2, 3, 2, 4, 3, 2, 1, 5]).uniq
8
+
9
+ trackable.on(
10
+ value: test_on_value, close: test_on_close, error: test_on_error
11
+ )
12
+ expect(test_data).to be == [1, 2, 3, 4, 5, '|']
13
+ end
14
+ end
15
+ end
@@ -1,20 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  context Reacto::Trackable do
4
- let(:test_data) { [] }
5
- let(:test_on_value) { -> (v) { test_data << v }}
6
- let(:test_on_error) { -> (e) { test_data << e }}
7
- let(:test_on_close) { -> () { test_data << '|' }}
8
-
9
- let(:test_behaviour) do
10
- lambda do |tracker_subscription|
11
- tracker_subscription.on_value(5)
12
- tracker_subscription.on_close
13
- end
14
- end
15
-
16
- let(:source) { described_class.new(test_behaviour) }
17
-
18
4
  context '.new' do
19
5
  it 'supports behavior invoked on tracking, passed as block' do
20
6
  trackable = described_class.new do |tracker_subscription|
@@ -62,356 +48,4 @@ context Reacto::Trackable do
62
48
  expect(test_data[0]).to be(25)
63
49
  end
64
50
  end
65
-
66
- context '#map' do
67
- it 'transforms the value of the source Trackable using the passed ' \
68
- 'transformation' do
69
- trackable = source.map do |v|
70
- v * v * v
71
- end
72
-
73
- trackable.on(value: test_on_value)
74
-
75
- expect(test_data.size).to be(1)
76
- expect(test_data[0]).to be(125)
77
- end
78
-
79
- it 'transforms errors, if error transformation is passed' do
80
- source = described_class.make do |subscriber|
81
- subscriber.on_value(4)
82
- subscriber.on_error(StandardError.new('error'))
83
- end
84
- trackable = source.map(-> (v) { v }, error: -> (e) { 5 })
85
-
86
- trackable.on(value: test_on_value, error: test_on_error)
87
-
88
- expect(test_data.size).to be(2)
89
- expect(test_data).to be == [4, 5]
90
- end
91
-
92
- it 'emits what is produced by the passed `close` function before close' do
93
- trackable =
94
- described_class.enumerable((1..5)).map(close: ->() { 10 }) do |v|
95
- v
96
- end
97
-
98
- trackable.on(value: test_on_value, close: test_on_close)
99
- expect(test_data).to be == (1..5).to_a + [10, '|']
100
- end
101
- end
102
-
103
- context '#select' do
104
- it 'doesn\'t notify with values not passing the filter block' do
105
- trackable = source.select do |v|
106
- v % 2 == 0
107
- end
108
-
109
- trackable.on(value: test_on_value)
110
-
111
- expect(test_data.size).to be(0)
112
- end
113
-
114
- it 'notifies with values passing the filter block' do
115
- trackable = source.select do |v|
116
- v % 2 == 1
117
- end
118
-
119
- trackable.on(value: test_on_value)
120
-
121
- expect(test_data.size).to be(1)
122
- expect(test_data[0]).to be(5)
123
- end
124
- end
125
-
126
- context '#inject' do
127
- let(:test_behaviour) do
128
- lambda do |tracker_subscription|
129
- [16, 7, 2014].each do |value|
130
- tracker_subscription.on_value(value)
131
- end
132
-
133
- tracker_subscription.on_close
134
- end
135
- end
136
-
137
- it 'sends the values created by applying the `inject` operation on the ' \
138
- 'last value and current value, using for first value the initial one' do
139
- trackable = source.inject(0) do |prev, v|
140
- prev + v
141
- end
142
- trackable.on(value: test_on_value)
143
-
144
- expect(test_data.size).to be(3)
145
- expect(test_data).to be == [16, 23, 2037]
146
- end
147
-
148
- it 'sends the values created by applying the `inject` operation on the ' \
149
- 'last value and current value, using for first value ' \
150
- 'the first emitted by the source if no initial value provided' do
151
- trackable = source.inject do |prev, v|
152
- prev + v
153
- end
154
- trackable.on(value: test_on_value)
155
-
156
- expect(test_data.size).to be(3)
157
- expect(test_data).to be == [16, 23, 2037]
158
- end
159
-
160
- it 'sends the initial value if no value is emitted' do
161
- source = described_class.new(-> (t) { t.on_close })
162
- trackable = source.inject(0) do |prev, v|
163
- prev + v
164
- end
165
- trackable.on(value: test_on_value)
166
-
167
- expect(test_data.size).to be(1)
168
- expect(test_data).to be == [0]
169
- end
170
-
171
- it 'sends nothing if no initial value and no value emitted' do
172
- source = described_class.new(-> (t) { t.on_close })
173
- trackable = source.inject do |prev, v|
174
- prev + v
175
- end
176
- trackable.on(value: test_on_value)
177
-
178
- expect(test_data.size).to be(0)
179
- end
180
- end
181
-
182
- context '#diff' do
183
- it 'by default emits arrays with two values the - previous and current ' \
184
- 'element' do
185
- source = described_class.enumerable((1..10))
186
- trackable = source.diff
187
- trackable.on(value: test_on_value, error: test_on_error)
188
-
189
- expect(test_data).to be == [
190
- [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10
191
- ]]
192
- end
193
-
194
- it 'can be passed a diff function to calculate the difference between ' \
195
- 'the previously emitted value and the current and to emit it' do
196
- source = described_class.enumerable((1..10))
197
- trackable = source.diff(Reacto::NO_VALUE, -> (p, c) { c - p })
198
- trackable.on(value: test_on_value, error: test_on_error)
199
-
200
- expect(test_data).to be == [1] * 9
201
- end
202
-
203
- it 'can be passed a diff block to calculate the difference between ' \
204
- 'the previously emitted value and the current and to emit it' do
205
- source = described_class.enumerable((1..10))
206
- trackable = source.diff { |p, c| c - p }
207
- trackable.on(value: test_on_value, error: test_on_error)
208
-
209
- expect(test_data).to be == [1] * 9
210
- end
211
-
212
- it 'can receive initial value to be used as seed - the first value' do
213
- source = described_class.enumerable((1..10))
214
- trackable = source.diff(-5) { |p, c| c - p }
215
- trackable.on(value: test_on_value, error: test_on_error)
216
-
217
- expect(test_data).to be == [6] + ([1] * 9)
218
- end
219
- end
220
-
221
- context '#prepend' do
222
- it 'emits the passed enumerable before the values, emited by the caller' do
223
- source = described_class.enumerable((1..5))
224
- trackable = source.prepend((-5..0))
225
-
226
- trackable.on(value: test_on_value)
227
-
228
- expect(test_data.size).to be(11)
229
- expect(test_data).to be == (-5..5).to_a
230
- end
231
- end
232
-
233
- context '#drop_errors' do
234
- it 'drops all the errors from the source and continues' do
235
- described_class.enumerable((1..5)).concat(
236
- described_class.error(StandardError.new)
237
- ).concat(described_class.enumerable(6..10)).drop_errors.on(
238
- value: test_on_value, error: test_on_error, close: test_on_close
239
- )
240
-
241
- expect(test_data).to be == (1..10).to_a + ['|']
242
- end
243
- end
244
-
245
- context '#drop, #take, #last, #first, #[]' do
246
- let(:test_behaviour) do
247
- lambda do |tracker_subscription|
248
- (1..15).each do |value|
249
- tracker_subscription.on_value(value)
250
- end
251
-
252
- tracker_subscription.on_close
253
- end
254
- end
255
-
256
- context('#drop') do
257
- it 'drops the first `n` values sent by the source' do
258
- source.drop(6).on(value: test_on_value)
259
-
260
- expect(test_data.size).to be(9)
261
- expect(test_data).to be == (7..15).to_a
262
- end
263
- end
264
-
265
- context('#take') do
266
- it 'sents only the first `n` values sent by the source' do
267
- source.take(6).on(value: test_on_value)
268
-
269
- expect(test_data.size).to be(6)
270
- expect(test_data).to be == (1..6).to_a
271
- end
272
- end
273
-
274
- context('#last') do
275
- it 'emits only the last value of the source and the closing ' \
276
- 'notification' do
277
- source.last.on(value: test_on_value, close: test_on_close)
278
-
279
- expect(test_data).to be == [15, '|']
280
- end
281
-
282
- it 'only closes if no value was emitted by the source' do
283
- described_class.close.last.on(
284
- value: test_on_value, close: test_on_close
285
- )
286
-
287
- expect(test_data).to be == ['|']
288
- end
289
-
290
- it 'emits the last value before the error and the error when error ' \
291
- 'notification is received from the source' do
292
- err = StandardError.new('Hey!')
293
- source.concat(described_class.error(err)).last.on(
294
- value: test_on_value, close: test_on_close, error: test_on_error
295
- )
296
-
297
- expect(test_data).to be == [15, err]
298
- end
299
- end
300
-
301
- context('#first') do
302
- it 'emits only the first value of the source and closes' do
303
- source.first.on(
304
- value: test_on_value, close: test_on_close
305
- )
306
-
307
- expect(test_data).to be == [1, '|']
308
- end
309
-
310
- it 'only closes if no value was emitted by the source' do
311
- described_class.close.first.on(
312
- value: test_on_value, close: test_on_close
313
- )
314
-
315
- expect(test_data).to be == ['|']
316
- end
317
- end
318
-
319
- context('#[]') do
320
- it 'emits only the n-th value of the source and closes' do
321
- source[4].on(
322
- value: test_on_value, close: test_on_close
323
- )
324
-
325
- expect(test_data).to be == [5, '|']
326
- end
327
-
328
- it 'just closes if no value was emitted by the source' do
329
- described_class.close[3].on(
330
- value: test_on_value, close: test_on_close
331
- )
332
-
333
- expect(test_data).to be == ['|']
334
- end
335
- end
336
- end
337
-
338
- context '#concat' do
339
- it 'starts emitting the values from the concatenated after emitting the ' \
340
- 'values from the source, then emits a `close` notification' do
341
- trackable = source.concat(described_class.enumerable((6..10)))
342
- trackable.on(value: test_on_value, close: test_on_close)
343
-
344
- expect(test_data).to be == (5..10).to_a + ['|']
345
- end
346
-
347
- it 'can be chained' do
348
- trackable = source
349
- .concat(described_class.enumerable((6..8)))
350
- .concat(described_class.enumerable((9..10)))
351
- trackable.on(value: test_on_value, close: test_on_close)
352
-
353
- expect(test_data).to be == (5..10).to_a + ['|']
354
- end
355
-
356
- it 'closes on error' do
357
- err = StandardError.new('Hey')
358
- trackable = source
359
- .concat(described_class.error(err))
360
- .concat(described_class.enumerable((9..10)))
361
- trackable.on(
362
- value: test_on_value, close: test_on_close, error: test_on_error
363
- )
364
-
365
- expect(test_data).to be == [5, err]
366
- end
367
-
368
- context '#merge' do
369
- it 'merges the passed trackable\'s emitions with the source ones' do
370
- trackable =
371
- described_class.interval(0.2).map { |v| v.to_s + 'a'}.take(5)
372
- to_be_merged =
373
- described_class.interval(0.35).map { |v| v.to_s + 'b'}.take(4)
374
- subscription = trackable.merge(to_be_merged).on(
375
- value: test_on_value, close: test_on_close, error: test_on_error
376
- )
377
- trackable.await(subscription)
378
-
379
- expect(test_data).to be ==
380
- ["0a", "0b", "1a", "2a", "1b", "3a", "4a", "2b", "3b", "|"]
381
- end
382
-
383
- it 'finishes with the error if `delay_error` is true' do
384
- err = StandardError.new('Hey')
385
- trackable = described_class.interval(0.2).map do |v|
386
- raise err if v == 3
387
- v.to_s + 'a'
388
- end.take(5)
389
-
390
- to_be_merged =
391
- described_class.interval(0.35).map { |v| v.to_s + 'b'}.take(4)
392
-
393
- trackable = trackable.merge(to_be_merged, delay_error: true)
394
- subscription = trackable.on(
395
- value: test_on_value, close: test_on_close, error: test_on_error
396
- )
397
- trackable.await(subscription, 2)
398
-
399
- expect(test_data).to be ==
400
- ["0a", "0b", "1a", "2a", "1b", "2b", "3b", err]
401
-
402
- end
403
- end
404
-
405
- context 'uniq' do
406
- it 'sends only uniq values, dropping the repeating ones' do
407
- trackable =
408
- described_class.enumerable([1, 2, 3, 2, 4, 3, 2, 1, 5]).uniq
409
-
410
- trackable.on(
411
- value: test_on_value, close: test_on_close, error: test_on_error
412
- )
413
- expect(test_data).to be == [1, 2, 3, 4, 5, '|']
414
- end
415
- end
416
- end
417
51
  end
@@ -6,6 +6,15 @@ module Helpers
6
6
  let(:test_on_close) { -> () { test_data << '|' }}
7
7
  let(:test_on_error) { -> (e) { test_data << e }}
8
8
 
9
+ let(:test_behaviour) do
10
+ lambda do |tracker_subscription|
11
+ tracker_subscription.on_value(5)
12
+ tracker_subscription.on_close
13
+ end
14
+ end
15
+
16
+ let(:source) { described_class.new(test_behaviour) }
17
+
9
18
  def attach_test_trackers(trackable)
10
19
  trackable.on(
11
20
  value: test_on_value,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reacto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nickolay Tzvetinov - Meddle
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-25 00:00:00.000000000 Z
11
+ date: 2016-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -59,6 +59,7 @@ executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
+ - .gitignore
62
63
  - .rspec
63
64
  - Gemfile
64
65
  - Gemfile.lock
@@ -74,6 +75,7 @@ files:
74
75
  - lib/reacto/operations/drop.rb
75
76
  - lib/reacto/operations/drop_errors.rb
76
77
  - lib/reacto/operations/flat_map.rb
78
+ - lib/reacto/operations/flat_map_latest.rb
77
79
  - lib/reacto/operations/flatten.rb
78
80
  - lib/reacto/operations/inject.rb
79
81
  - lib/reacto/operations/last.rb
@@ -109,7 +111,18 @@ files:
109
111
  - spec/reacto/executors_and_trackable_spec.rb
110
112
  - spec/reacto/operations/track_on_spec.rb
111
113
  - spec/reacto/trackable/buffer_spec.rb
114
+ - spec/reacto/trackable/class_level/never_spec.rb
115
+ - spec/reacto/trackable/concat_spec.rb
116
+ - spec/reacto/trackable/diff_spec.rb
117
+ - spec/reacto/trackable/drop_errors_spec.rb
118
+ - spec/reacto/trackable/flat_map_latest_spec.rb
119
+ - spec/reacto/trackable/flat_map_spec.rb
120
+ - spec/reacto/trackable/flatten_spec.rb
121
+ - spec/reacto/trackable/inject_spec.rb
122
+ - spec/reacto/trackable/merge_spec.rb
123
+ - spec/reacto/trackable/positional_filtering_spec.rb
112
124
  - spec/reacto/trackable/throttle_spec.rb
125
+ - spec/reacto/trackable/uniq_spec.rb
113
126
  - spec/reacto/trackable/zip_spec.rb
114
127
  - spec/reacto/trackable_spec.rb
115
128
  - spec/spec_helper.rb
@@ -143,7 +156,18 @@ test_files:
143
156
  - spec/reacto/executors_and_trackable_spec.rb
144
157
  - spec/reacto/operations/track_on_spec.rb
145
158
  - spec/reacto/trackable/buffer_spec.rb
159
+ - spec/reacto/trackable/class_level/never_spec.rb
160
+ - spec/reacto/trackable/concat_spec.rb
161
+ - spec/reacto/trackable/diff_spec.rb
162
+ - spec/reacto/trackable/drop_errors_spec.rb
163
+ - spec/reacto/trackable/flat_map_latest_spec.rb
164
+ - spec/reacto/trackable/flat_map_spec.rb
165
+ - spec/reacto/trackable/flatten_spec.rb
166
+ - spec/reacto/trackable/inject_spec.rb
167
+ - spec/reacto/trackable/merge_spec.rb
168
+ - spec/reacto/trackable/positional_filtering_spec.rb
146
169
  - spec/reacto/trackable/throttle_spec.rb
170
+ - spec/reacto/trackable/uniq_spec.rb
147
171
  - spec/reacto/trackable/zip_spec.rb
148
172
  - spec/reacto/trackable_spec.rb
149
173
  - spec/spec_helper.rb