reacto 0.1.0 → 1.0.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/.gitignore +2 -0
- data/README.md +932 -11
- data/doc/reactive_programming_with_reacto.md +238 -0
- data/lib/reacto.rb +70 -0
- data/lib/reacto/behaviours.rb +24 -1
- data/lib/reacto/constants.rb +4 -1
- data/lib/reacto/executors.rb +8 -10
- data/lib/reacto/labeled_trackable.rb +14 -2
- data/lib/reacto/operations.rb +23 -2
- data/lib/reacto/operations/act.rb +69 -0
- data/lib/reacto/operations/append.rb +45 -0
- data/lib/reacto/operations/blocking_enumerable.rb +40 -0
- data/lib/reacto/operations/buffer.rb +1 -4
- data/lib/reacto/operations/chunk.rb +81 -0
- data/lib/reacto/operations/chunk_while.rb +56 -0
- data/lib/reacto/operations/cycle.rb +27 -0
- data/lib/reacto/operations/delay_each.rb +75 -0
- data/lib/reacto/operations/depend_on.rb +4 -5
- data/lib/reacto/operations/diff.rb +8 -10
- data/lib/reacto/operations/drop.rb +6 -8
- data/lib/reacto/operations/drop_while.rb +23 -0
- data/lib/reacto/operations/each_collect.rb +57 -0
- data/lib/reacto/operations/each_with_object.rb +31 -0
- data/lib/reacto/operations/extremums.rb +54 -0
- data/lib/reacto/operations/find_index.rb +28 -0
- data/lib/reacto/operations/flat_map.rb +2 -2
- data/lib/reacto/operations/flatten.rb +2 -7
- data/lib/reacto/operations/flatten_labeled.rb +44 -0
- data/lib/reacto/operations/{label.rb → group_by_label.rb} +1 -1
- data/lib/reacto/operations/include.rb +40 -0
- data/lib/reacto/operations/inject.rb +15 -9
- data/lib/reacto/operations/map.rb +15 -13
- data/lib/reacto/operations/merge.rb +17 -16
- data/lib/reacto/operations/operation_on_labeled.rb +29 -0
- data/lib/reacto/operations/partition.rb +52 -0
- data/lib/reacto/operations/prepend.rb +0 -3
- data/lib/reacto/operations/rescue_and_replace_error.rb +21 -0
- data/lib/reacto/operations/retry.rb +26 -0
- data/lib/reacto/operations/retry_when.rb +30 -0
- data/lib/reacto/operations/select.rb +2 -6
- data/lib/reacto/operations/slice.rb +50 -0
- data/lib/reacto/operations/slice_when.rb +41 -0
- data/lib/reacto/operations/split_labeled.rb +32 -0
- data/lib/reacto/operations/take.rb +9 -14
- data/lib/reacto/operations/take_while.rb +28 -0
- data/lib/reacto/operations/throttle.rb +2 -3
- data/lib/reacto/operations/track_on.rb +1 -3
- data/lib/reacto/shared_trackable.rb +2 -5
- data/lib/reacto/subscriptions/buffered_subscription.rb +10 -9
- data/lib/reacto/subscriptions/executor_subscription.rb +12 -4
- data/lib/reacto/subscriptions/tracker_subscription.rb +0 -4
- data/lib/reacto/subscriptions/zipping_subscription.rb +0 -1
- data/lib/reacto/trackable.rb +429 -64
- data/lib/reacto/version.rb +1 -1
- data/reacto.gemspec +2 -3
- data/spec/reacto/labeled_trackable_spec.rb +17 -0
- data/spec/reacto/trackable/act_spec.rb +15 -0
- data/spec/reacto/trackable/all_spec.rb +38 -0
- data/spec/reacto/trackable/any_spec.rb +39 -0
- data/spec/reacto/trackable/append_spec.rb +38 -0
- data/spec/reacto/trackable/buffer_spec.rb +11 -15
- data/spec/reacto/trackable/chunk_spec.rb +86 -0
- data/spec/reacto/trackable/chunk_while_spec.rb +22 -0
- data/spec/reacto/trackable/class_level/combine_last_spec.rb +1 -3
- data/spec/reacto/trackable/class_level/interval_spec.rb +4 -6
- data/spec/reacto/trackable/class_level/make_spec.rb +0 -15
- data/spec/reacto/trackable/{zip_spec.rb → class_level/zip_spec.rb} +0 -2
- data/spec/reacto/trackable/concat_spec.rb +12 -12
- data/spec/reacto/trackable/count_spec.rb +38 -0
- data/spec/reacto/trackable/cycle_spec.rb +14 -0
- data/spec/reacto/trackable/delay_each_spec.rb +18 -0
- data/spec/reacto/trackable/depend_on_spec.rb +6 -9
- data/spec/reacto/trackable/diff_spec.rb +3 -5
- data/spec/reacto/trackable/drop_errors_spec.rb +1 -3
- data/spec/reacto/trackable/drop_while_spec.rb +15 -0
- data/spec/reacto/trackable/each_cons_spec.rb +53 -0
- data/spec/reacto/trackable/each_slice_spec.rb +37 -0
- data/spec/reacto/trackable/each_with_index_spec.rb +33 -0
- data/spec/reacto/trackable/each_with_object_spec.rb +26 -0
- data/spec/reacto/trackable/entries_spec.rb +25 -0
- data/spec/reacto/trackable/execute_on_spec.rb +33 -0
- data/spec/reacto/trackable/find_index_spec.rb +31 -0
- data/spec/reacto/trackable/find_spec.rb +34 -0
- data/spec/reacto/trackable/first_spec.rb +36 -0
- data/spec/reacto/trackable/flat_map_latest_spec.rb +5 -5
- data/spec/reacto/trackable/flat_map_spec.rb +25 -0
- data/spec/reacto/trackable/flatten_labeled_spec.rb +48 -0
- data/spec/reacto/trackable/grep_spec.rb +29 -0
- data/spec/reacto/trackable/grep_v_spec.rb +23 -0
- data/spec/reacto/trackable/{label_spec.rb → group_by_label_spec.rb} +4 -11
- data/spec/reacto/trackable/include_spec.rb +23 -0
- data/spec/reacto/trackable/inject_spec.rb +30 -4
- data/spec/reacto/trackable/lift_spec.rb +1 -3
- data/spec/reacto/trackable/map_spec.rb +17 -3
- data/spec/reacto/trackable/max_by_spec.rb +12 -0
- data/spec/reacto/trackable/max_spec.rb +19 -0
- data/spec/reacto/trackable/merge_spec.rb +6 -7
- data/spec/reacto/trackable/min_by_spec.rb +12 -0
- data/spec/reacto/trackable/min_spec.rb +19 -0
- data/spec/reacto/trackable/minmax_by_spec.rb +12 -0
- data/spec/reacto/trackable/minmax_spec.rb +19 -0
- data/spec/reacto/trackable/none_spec.rb +38 -0
- data/spec/reacto/trackable/on_spec.rb +11 -4
- data/spec/reacto/trackable/one_spec.rb +38 -0
- data/spec/reacto/trackable/partition_spec.rb +23 -0
- data/spec/reacto/trackable/prepend_spec.rb +1 -3
- data/spec/reacto/trackable/reject_spec.rb +21 -0
- data/spec/reacto/trackable/rescue_and_replace_error_spec.rb +48 -0
- data/spec/reacto/trackable/rescue_and_replace_error_with_spec.rb +26 -0
- data/spec/reacto/trackable/retry_spec.rb +50 -0
- data/spec/reacto/trackable/retry_when_spec.rb +33 -0
- data/spec/reacto/trackable/select_spec.rb +18 -7
- data/spec/reacto/trackable/slice_after_spec.rb +38 -0
- data/spec/reacto/trackable/slice_before_spec.rb +38 -0
- data/spec/reacto/trackable/slice_when_spec.rb +26 -0
- data/spec/reacto/trackable/sort_by_spec.rb +16 -0
- data/spec/reacto/trackable/sort_spec.rb +23 -0
- data/spec/reacto/trackable/split_labeled_spec.rb +37 -0
- data/spec/reacto/trackable/take_while_spec.rb +16 -0
- data/spec/reacto/trackable/throttle_spec.rb +2 -3
- data/spec/reacto/trackable/track_on_spec.rb +2 -3
- data/spec/reacto/trackable/uniq_spec.rb +2 -4
- data/spec/support/helpers.rb +9 -1
- metadata +135 -25
- data/Gemfile.lock +0 -32
- data/lib/reacto/operations/cache.rb +0 -53
- data/spec/reacto/trackable/cache_spec.rb +0 -64
@@ -0,0 +1,38 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
subject(:source) { described_class.enumerable([1, 2, 4, 2]) }
|
3
|
+
|
4
|
+
context '#count' do
|
5
|
+
it 'returns a Trackable, emitting only one value - the number of values ' \
|
6
|
+
'emitted by the caller of this operation' do
|
7
|
+
counting_trackable = source.count
|
8
|
+
|
9
|
+
attach_test_trackers(counting_trackable)
|
10
|
+
|
11
|
+
expect(test_data.size).to be 2
|
12
|
+
expect(test_data.first).to eq(4)
|
13
|
+
expect(test_data.last).to eq('|')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'returns a Trackable, emitting only one value - the number of values, ' \
|
17
|
+
'equal to the given as argument one, if such is given' do
|
18
|
+
counting_trackable = source.count(2)
|
19
|
+
|
20
|
+
attach_test_trackers(counting_trackable)
|
21
|
+
|
22
|
+
expect(test_data.size).to be 2
|
23
|
+
expect(test_data.first).to eq(2)
|
24
|
+
expect(test_data.last).to eq('|')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns a Trackable, emitting only one value - the number of values, ' \
|
28
|
+
'yielding a true value if a block is given' do
|
29
|
+
counting_trackable = source.count { |v| v.even? }
|
30
|
+
|
31
|
+
attach_test_trackers(counting_trackable)
|
32
|
+
|
33
|
+
expect(test_data.size).to be 2
|
34
|
+
expect(test_data.first).to eq(3)
|
35
|
+
expect(test_data.last).to eq('|')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
subject(:source) { described_class.enumerable(%w(a b c)) }
|
3
|
+
|
4
|
+
context '#cycle' do
|
5
|
+
it 'emits all the elements of the source repeatedly the given `n` times ' do
|
6
|
+
trackable = source.cycle(3)
|
7
|
+
|
8
|
+
attach_test_trackers(trackable)
|
9
|
+
|
10
|
+
expect(test_data.size).to eq(10)
|
11
|
+
expect(test_data).to eq((%w(a b c) * 3) + %w(|))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
context '#delay_each' do
|
3
|
+
it 'emits every notification from the source Trackable, but waits ' \
|
4
|
+
'the given delay seconds for between every emit' do
|
5
|
+
trackable = described_class.enumerable((1..5)).delay_each(0.3)
|
6
|
+
|
7
|
+
trackable.on(
|
8
|
+
value: test_on_value, close: test_on_close, error: test_on_error
|
9
|
+
)
|
10
|
+
|
11
|
+
sleep 1
|
12
|
+
expect(test_data).to eq([1, 2, 3])
|
13
|
+
|
14
|
+
sleep 1
|
15
|
+
expect(test_data).to eq([1, 2, 3, 4, 5, '|'])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
context Reacto::Trackable do
|
4
2
|
context '#depend_on' do
|
5
3
|
it 'suspends its caller untill the passed Trackable emits its ' \
|
@@ -18,7 +16,7 @@ context Reacto::Trackable do
|
|
18
16
|
expect(test_data[1].data).to be 10
|
19
17
|
expect(test_data[2].value).to be 4
|
20
18
|
expect(test_data[2].data).to be 10
|
21
|
-
expect(test_data.last).to
|
19
|
+
expect(test_data.last).to eq('|')
|
22
20
|
end
|
23
21
|
|
24
22
|
it 'it uses the first emitted value for the data from the dependency ' \
|
@@ -37,13 +35,12 @@ context Reacto::Trackable do
|
|
37
35
|
expect(test_data[1].data).to be 5
|
38
36
|
expect(test_data[2].value).to be 4
|
39
37
|
expect(test_data[2].data).to be 5
|
40
|
-
expect(test_data.last).to
|
38
|
+
expect(test_data.last).to eq('|')
|
41
39
|
end
|
42
40
|
|
43
41
|
it 'uses the block passed to accumulate the dependency data' do
|
44
|
-
|
45
|
-
|
46
|
-
) { |prev, v| prev + v }
|
42
|
+
dependency = described_class.enumerable((1..10))
|
43
|
+
trackable = described_class.enumerable([5, 4]).depend_on(dependency, &:+)
|
47
44
|
|
48
45
|
attach_test_trackers(trackable)
|
49
46
|
|
@@ -52,7 +49,7 @@ context Reacto::Trackable do
|
|
52
49
|
expect(test_data[0].data).to be 55
|
53
50
|
expect(test_data[1].value).to be 4
|
54
51
|
expect(test_data[1].data).to be 55
|
55
|
-
expect(test_data.last).to
|
52
|
+
expect(test_data.last).to eq('|')
|
56
53
|
end
|
57
54
|
|
58
55
|
it 'sends the error if the dependency has an error' do
|
@@ -64,7 +61,7 @@ context Reacto::Trackable do
|
|
64
61
|
attach_test_trackers(trackable)
|
65
62
|
|
66
63
|
expect(test_data.size).to be 1
|
67
|
-
expect(test_data.last).to
|
64
|
+
expect(test_data.last).to eq(error)
|
68
65
|
end
|
69
66
|
end
|
70
67
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
context Reacto::Trackable do
|
4
2
|
context '#diff' do
|
5
3
|
it 'by default emits arrays with two values the - previous and current ' \
|
@@ -8,15 +6,15 @@ context Reacto::Trackable do
|
|
8
6
|
trackable = source.diff
|
9
7
|
trackable.on(value: test_on_value, error: test_on_error)
|
10
8
|
|
11
|
-
expect(test_data).to
|
9
|
+
expect(test_data).to eq([
|
12
10
|
[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10
|
13
|
-
]]
|
11
|
+
]])
|
14
12
|
end
|
15
13
|
|
16
14
|
it 'can be passed a diff function to calculate the difference between ' \
|
17
15
|
'the previously emitted value and the current and to emit it' do
|
18
16
|
source = described_class.enumerable((1..10))
|
19
|
-
trackable = source.diff(Reacto::NO_VALUE
|
17
|
+
trackable = source.diff(Reacto::NO_VALUE) { |p, c| c - p }
|
20
18
|
trackable.on(value: test_on_value, error: test_on_error)
|
21
19
|
|
22
20
|
expect(test_data).to be == [1] * 9
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
context Reacto::Trackable do
|
4
2
|
context '#drop_errors' do
|
5
3
|
it 'drops all the errors from the source and continues' do
|
@@ -9,7 +7,7 @@ context Reacto::Trackable do
|
|
9
7
|
value: test_on_value, error: test_on_error, close: test_on_close
|
10
8
|
)
|
11
9
|
|
12
|
-
expect(test_data).to
|
10
|
+
expect(test_data).to eq((1..10).to_a + ['|'])
|
13
11
|
end
|
14
12
|
end
|
15
13
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
context '#drop_while' do
|
3
|
+
it 'drops elements up to, but not including, the first element for which ' \
|
4
|
+
'the block returns nil or false' do
|
5
|
+
trackable = described_class.enumerable((1..5)).drop_while do |val|
|
6
|
+
val < 4
|
7
|
+
end
|
8
|
+
|
9
|
+
attach_test_trackers(trackable)
|
10
|
+
|
11
|
+
expect(test_data.size).to be(3)
|
12
|
+
expect(test_data).to eq([4, 5, '|'])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
context '#each_cons' do
|
3
|
+
subject(:test_source) { described_class.enumerable((1..10)) }
|
4
|
+
|
5
|
+
it 'raises an ArgumentError if the size given as first argument '\
|
6
|
+
'is zero or smaller' do
|
7
|
+
expect do
|
8
|
+
test_source.each_cons(0) do |v|
|
9
|
+
p v
|
10
|
+
end
|
11
|
+
end.to raise_error(ArgumentError).with_message('invalid size')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'behaves as #each/#on if the size given is 1' do
|
15
|
+
test_data = []
|
16
|
+
test_source.each_cons(1) { |v| test_data << v }
|
17
|
+
|
18
|
+
expect(test_data).to eq((1..10).to_a)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'calls the given block for each array of consecutive <n> emitted ' \
|
22
|
+
'values' do
|
23
|
+
test_data = []
|
24
|
+
test_source.each_cons(2) { |v| test_data << v }
|
25
|
+
|
26
|
+
expect(test_data).to eq(
|
27
|
+
[
|
28
|
+
[1, 2], [2, 3], [3, 4], [4, 5], [5, 6],
|
29
|
+
[6, 7], [7, 8], [8, 9], [9, 10]
|
30
|
+
]
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns a Reacto::Subscription' do
|
35
|
+
subscription = test_source.each_cons(3) { |v| test_data << v }
|
36
|
+
|
37
|
+
expect(subscription).to_not be(nil)
|
38
|
+
expect(subscription).to be_kind_of(Reacto::Subscriptions::Subscription)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns a new Trackable with the each_cons behavior ' \
|
42
|
+
'if no block was given' do
|
43
|
+
trackable = test_source.each_cons(4)
|
44
|
+
|
45
|
+
attach_test_trackers(trackable)
|
46
|
+
|
47
|
+
expect(test_data).to eq([
|
48
|
+
[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8],
|
49
|
+
[6, 7, 8, 9], [7, 8, 9, 10], '|'
|
50
|
+
])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
context '#each_slice' do
|
3
|
+
subject(:test_source) { described_class.enumerable((1..10)) }
|
4
|
+
|
5
|
+
it 'raises an ArgumentError if the size given as first argument '\
|
6
|
+
'is zero or smaller' do
|
7
|
+
expect do
|
8
|
+
test_source.each_slice(-1) { |v| p v }
|
9
|
+
end.to raise_error(ArgumentError).with_message('invalid size')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'calls the given block for each slice of <n> emitted values' do
|
13
|
+
test_data = []
|
14
|
+
test_source.each_slice(3) { |v| test_data << v }
|
15
|
+
|
16
|
+
expect(test_data).to eq([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]])
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns a Reacto::Subscription' do
|
20
|
+
subscription = test_source.each_slice(3) { |v| test_data << v }
|
21
|
+
|
22
|
+
expect(subscription).to_not be(nil)
|
23
|
+
expect(subscription).to be_kind_of(Reacto::Subscriptions::Subscription)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns a new Trackable with the each_slice behavior ' \
|
27
|
+
'if no block was given' do
|
28
|
+
trackable = test_source.each_slice(1)
|
29
|
+
|
30
|
+
attach_test_trackers(trackable)
|
31
|
+
|
32
|
+
expect(test_data).to eq([
|
33
|
+
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], '|'
|
34
|
+
])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
context '#each_with_index' do
|
3
|
+
subject(:test_source) { described_class.enumerable(('A'..'F')) }
|
4
|
+
|
5
|
+
it 'calls the given block with two arguments, the value and its index, ' \
|
6
|
+
'for each emitted value' do
|
7
|
+
|
8
|
+
test_source.each_with_index { |v, i| test_data << [v, i] }
|
9
|
+
|
10
|
+
expect(test_data).to eq([
|
11
|
+
['A', 0], ['B', 1], ['C', 2], ['D', 3], ['E', 4], ['F', 5]
|
12
|
+
])
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns a Reacto::Subscription' do
|
16
|
+
subscription = test_source.each_with_index { |v, i| test_data << [v, i] }
|
17
|
+
|
18
|
+
expect(subscription).to_not be(nil)
|
19
|
+
expect(subscription).to be_kind_of(Reacto::Subscriptions::Subscription)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns a new Trackable with the each_with_index behavior ' \
|
23
|
+
'if no block was given' do
|
24
|
+
trackable = test_source.each_with_index
|
25
|
+
|
26
|
+
attach_test_trackers(trackable)
|
27
|
+
|
28
|
+
expect(test_data).to eq([
|
29
|
+
['A', 0], ['B', 1], ['C', 2], ['D', 3], ['E', 4], ['F', 5], '|'
|
30
|
+
])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
context '#each_with_object' do
|
3
|
+
subject(:test_source) do
|
4
|
+
lyrics = 'I am drinking I am rolling I am hiding I am running'
|
5
|
+
described_class.enumerable(lyrics.split(''))
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'calls the given block for each value emitted by the source ' \
|
9
|
+
'with an arbitrary object given, and emits the initially given object' do
|
10
|
+
trackable = test_source.each_with_object({}) do |v, memo|
|
11
|
+
unless v.strip.empty?
|
12
|
+
memo[v] ||= 0
|
13
|
+
memo[v] += 1
|
14
|
+
end
|
15
|
+
end
|
16
|
+
attach_test_trackers(trackable)
|
17
|
+
|
18
|
+
expect(test_data.size).to eq(2)
|
19
|
+
expect(test_data.first).to eq({
|
20
|
+
'I' => 4, 'a' => 4, 'm' => 4, 'd' => 2, 'r' => 3, 'i' => 6, 'n' => 7,
|
21
|
+
'k' => 1, 'g' => 4, 'o' => 1, 'l' => 2, 'h' => 1, 'u' => 1
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
context '#entries' do
|
3
|
+
subject(:test_source) { described_class.enumerable((1..100)) }
|
4
|
+
|
5
|
+
it 'returns an array containing all the values emitted by the source' do
|
6
|
+
result = test_source.entries
|
7
|
+
|
8
|
+
expect(result).to eq((1..100).to_a)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'returns an array containing the first <n> values emitted by the ' \
|
12
|
+
'source if a number is given' do
|
13
|
+
result = test_source.entries(5)
|
14
|
+
|
15
|
+
expect(result).to eq([1, 2, 3, 4, 5])
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'blocks and waits for the array to be ready even if the source is ' \
|
19
|
+
'executing on background executor' do
|
20
|
+
result = test_source.delay_each(0.2).entries(3)
|
21
|
+
|
22
|
+
expect(result).to eq([1, 2, 3])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
subject(:test_source) do
|
3
|
+
described_class.new do |tracker_subscription|
|
4
|
+
tracker_subscription.on_value(32)
|
5
|
+
sleep 1
|
6
|
+
|
7
|
+
tracker_subscription.on_close
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context '#execute_on' do
|
12
|
+
it 'executes the whole chain of methods on a background managed thread' do
|
13
|
+
threads = []
|
14
|
+
|
15
|
+
trackable = test_source
|
16
|
+
.act { |n| threads << Thread.current }
|
17
|
+
.map { |v| v / 8 }
|
18
|
+
.execute_on(:background)
|
19
|
+
|
20
|
+
subscription = attach_test_trackers(trackable)
|
21
|
+
trackable.await(subscription)
|
22
|
+
|
23
|
+
expect(test_data).to eq([4, '|'])
|
24
|
+
|
25
|
+
threads = threads.uniq
|
26
|
+
expect(threads.size).to be(1)
|
27
|
+
|
28
|
+
thread = threads.first
|
29
|
+
|
30
|
+
expect(thread).to_not be(Thread.current)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
subject(:test_source) { described_class.enumerable(('a'..'z')) }
|
3
|
+
|
4
|
+
context '#find_index' do
|
5
|
+
it 'passes each emitted value from the source to block. Emits the ' \
|
6
|
+
'index of the first for which the evaluated value is non-false. ' do
|
7
|
+
trackable = test_source.find_index { |val| val == 'i' || val == 'h' }
|
8
|
+
|
9
|
+
attach_test_trackers(trackable)
|
10
|
+
|
11
|
+
expect(test_data).to eq([7, '|'])
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'compares each emitted value with the given value, if such is given. ' \
|
15
|
+
'Emits the index of the first which is equal to the value, given.' do
|
16
|
+
trackable = test_source.find_index('j')
|
17
|
+
|
18
|
+
attach_test_trackers(trackable)
|
19
|
+
|
20
|
+
expect(test_data).to eq([9, '|'])
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'emits only the close notification if there is no match' do
|
24
|
+
trackable = test_source.find_index('A')
|
25
|
+
|
26
|
+
attach_test_trackers(trackable)
|
27
|
+
|
28
|
+
expect(test_data).to eq(['|'])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
context Reacto::Trackable do
|
2
|
+
context '#find' do
|
3
|
+
subject(:source) { described_class.enumerable([0, 5, 2, 3, 4, 1, 6]) }
|
4
|
+
|
5
|
+
it 'doesn\'t notify with values not passing the filter block' do
|
6
|
+
trackable = source.find { |v| v > 10 }
|
7
|
+
trackable.on(value: test_on_value)
|
8
|
+
|
9
|
+
expect(test_data.size).to be(0)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'notifies with the first value passing the filter block' do
|
13
|
+
trackable = source.find do |v|
|
14
|
+
v % 2 == 1
|
15
|
+
end
|
16
|
+
|
17
|
+
trackable.on(value: test_on_value)
|
18
|
+
|
19
|
+
expect(test_data.size).to be(1)
|
20
|
+
expect(test_data.first).to be(5)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'notifies with the given value if value is given and nothing is found' do
|
24
|
+
trackable = source.find(15) do |v|
|
25
|
+
v > 10
|
26
|
+
end
|
27
|
+
|
28
|
+
trackable.on(value: test_on_value)
|
29
|
+
|
30
|
+
expect(test_data.size).to be(1)
|
31
|
+
expect(test_data.first).to be(15)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|