jrf 0.1.10 → 0.1.12
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/lib/jrf/row_context.rb +14 -4
- data/lib/jrf/stage.rb +29 -0
- data/lib/jrf/version.rb +1 -1
- data/test/jrf_test.rb +87 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ddf9bb5a12260eea615d0107dc7374dec2b5a3fe81c51791ea7e7ffea359d12f
|
|
4
|
+
data.tar.gz: d556b7d230185a9c397af45abaa08b912f485f3a1494bebdf86f2ef44be81c64
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7642e5e7c50e9b4da7f28bf906bf432ee7c6d377839af2ff2b73d299c044e08566876bd3d33d5492abe9432b58f0871df2ebb9d4e7ec45ffe02a495fad1e2fc
|
|
7
|
+
data.tar.gz: '0629e81b1c9cf8070fb0a1fcbe409cf026bb62f72da9855d32fe9f253552de51a21f663b616abdc3b474dd705d9067512838fe5f0e33293f423636a5ea18167f'
|
data/lib/jrf/row_context.rb
CHANGED
|
@@ -59,6 +59,10 @@ module Jrf
|
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
define_reducer(:count_if) do |_ctx, condition, block: nil|
|
|
63
|
+
{ value: condition, initial: 0, step: ->(acc, v) { v ? (acc + 1) : acc } }
|
|
64
|
+
end
|
|
65
|
+
|
|
62
66
|
define_reducer(:min) do |_ctx, value, block: nil|
|
|
63
67
|
{ value: value, initial: nil, step: ->(acc, v) { v.nil? ? acc : (acc.nil? || v < acc ? v : acc) } }
|
|
64
68
|
end
|
|
@@ -170,16 +174,22 @@ module Jrf
|
|
|
170
174
|
@__jrf_current_stage.step_reduce(current_input, initial: initial, &block)
|
|
171
175
|
end
|
|
172
176
|
|
|
173
|
-
def map(&block)
|
|
177
|
+
def map(collection = nil, &block)
|
|
174
178
|
raise ArgumentError, "map requires a block" unless block
|
|
175
179
|
|
|
176
|
-
@__jrf_current_stage.step_map(:map,
|
|
180
|
+
@__jrf_current_stage.step_map(:map, collection || current_input, &block)
|
|
177
181
|
end
|
|
178
182
|
|
|
179
|
-
def map_values(&block)
|
|
183
|
+
def map_values(collection = nil, &block)
|
|
180
184
|
raise ArgumentError, "map_values requires a block" unless block
|
|
181
185
|
|
|
182
|
-
@__jrf_current_stage.step_map(:map_values,
|
|
186
|
+
@__jrf_current_stage.step_map(:map_values, collection || current_input, &block)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def apply(collection = nil, &block)
|
|
190
|
+
raise ArgumentError, "apply requires a block" unless block
|
|
191
|
+
|
|
192
|
+
@__jrf_current_stage.step_apply(collection || current_input, &block)
|
|
183
193
|
end
|
|
184
194
|
|
|
185
195
|
def group_by(key, &block)
|
data/lib/jrf/stage.rb
CHANGED
|
@@ -113,6 +113,35 @@ module Jrf
|
|
|
113
113
|
ReducerToken.new(idx)
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
+
def step_apply(collection, &block)
|
|
117
|
+
raise TypeError, "apply expects Array, got #{collection.class}" unless collection.is_a?(Array)
|
|
118
|
+
|
|
119
|
+
apply_reducers = []
|
|
120
|
+
template = nil
|
|
121
|
+
results = []
|
|
122
|
+
|
|
123
|
+
collection.each do |v|
|
|
124
|
+
with_scoped_reducers(apply_reducers) do
|
|
125
|
+
result = @ctx.send(:__jrf_with_current_input, v) { block.call(v) }
|
|
126
|
+
template ||= result
|
|
127
|
+
results << result
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
if apply_reducers.any?
|
|
132
|
+
self.class.resolve_template(template, apply_reducers)
|
|
133
|
+
else
|
|
134
|
+
results.each_with_object([]) do |mapped, arr|
|
|
135
|
+
next if mapped.equal?(Control::DROPPED)
|
|
136
|
+
if mapped.is_a?(Control::Flat)
|
|
137
|
+
arr.concat(Array(mapped.value))
|
|
138
|
+
else
|
|
139
|
+
arr << mapped
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
116
145
|
def step_group_by(key, &block)
|
|
117
146
|
idx = @cursor
|
|
118
147
|
map_reducer = (@reducers[idx] ||= MapReducer.new(:group_by, false))
|
data/lib/jrf/version.rb
CHANGED
data/test/jrf_test.rb
CHANGED
|
@@ -534,6 +534,23 @@ stdout, stderr, status = run_jrf('count(_["foo"])', input_with_nil)
|
|
|
534
534
|
assert_success(status, stderr, "count(expr) ignores nil")
|
|
535
535
|
assert_equal(%w[2], lines(stdout), "count(expr) ignores nil output")
|
|
536
536
|
|
|
537
|
+
# count_if
|
|
538
|
+
input_count_if = <<~NDJSON
|
|
539
|
+
{"x":1}
|
|
540
|
+
{"x":-2}
|
|
541
|
+
{"x":3}
|
|
542
|
+
{"x":-4}
|
|
543
|
+
{"x":5}
|
|
544
|
+
NDJSON
|
|
545
|
+
|
|
546
|
+
stdout, stderr, status = run_jrf('count_if(_["x"] > 0)', input_count_if)
|
|
547
|
+
assert_success(status, stderr, "count_if")
|
|
548
|
+
assert_equal(%w[3], lines(stdout), "count_if output")
|
|
549
|
+
|
|
550
|
+
stdout, stderr, status = run_jrf('[count_if(_["x"] > 0), count_if(_["x"] < 0)]', input_count_if)
|
|
551
|
+
assert_success(status, stderr, "count_if multiple")
|
|
552
|
+
assert_equal(["[3,2]"], lines(stdout), "count_if multiple output")
|
|
553
|
+
|
|
537
554
|
input_all_nil = <<~NDJSON
|
|
538
555
|
{"foo":null}
|
|
539
556
|
{"bar":1}
|
|
@@ -847,6 +864,44 @@ stdout, stderr, status = run_jrf('_["values"] >> map { |x| x + 1 } >> map { |x|
|
|
|
847
864
|
assert_success(status, stderr, "chained map transforms")
|
|
848
865
|
assert_equal(['[20,110,1010]', '[30,210,2010]', '[40,310,3010]'], lines(stdout), "chained map transforms output")
|
|
849
866
|
|
|
867
|
+
stdout, stderr, status = run_jrf('map { map { |y| [ sum(y[0]), sum(y[1]) ] } }', "[[[1,2]]]\n[[[3,4]]]\n")
|
|
868
|
+
assert_success(status, stderr, "nested map reducer binds to current target")
|
|
869
|
+
assert_equal(['[[[4,6]]]'], lines(stdout), "nested map reducer output")
|
|
870
|
+
|
|
871
|
+
stdout, stderr, status = run_jrf('map_values { |obj| map_values { |v| sum(v) } }', "{\"a\":{\"x\":1,\"y\":2},\"b\":{\"x\":10,\"y\":20}}\n{\"a\":{\"x\":3,\"y\":4},\"b\":{\"x\":30,\"y\":40}}\n")
|
|
872
|
+
assert_success(status, stderr, "nested map_values reducer binds to current target")
|
|
873
|
+
assert_equal(['{"a":{"x":4,"y":6},"b":{"x":40,"y":60}}'], lines(stdout), "nested map_values reducer output")
|
|
874
|
+
|
|
875
|
+
# apply - aggregation
|
|
876
|
+
stdout, stderr, status = run_jrf('[apply { |x| sum(x["foo"]) }, _.length]', '[{"foo":1},{"foo":2}]' + "\n" + '[{"foo":10}]' + "\n")
|
|
877
|
+
assert_success(status, stderr, "apply with sum")
|
|
878
|
+
assert_equal(["[3,2]", "[10,1]"], lines(stdout), "apply with sum output")
|
|
879
|
+
|
|
880
|
+
# apply - passthrough
|
|
881
|
+
stdout, stderr, status = run_jrf('apply { |x| x["foo"] }', '[{"foo":1},{"foo":2}]' + "\n")
|
|
882
|
+
assert_success(status, stderr, "apply passthrough")
|
|
883
|
+
assert_equal(["[1,2]"], lines(stdout), "apply passthrough output")
|
|
884
|
+
|
|
885
|
+
# apply - percentile
|
|
886
|
+
stdout, stderr, status = run_jrf('apply { |x| percentile(x, 0.5) }', '[10,20,30]' + "\n")
|
|
887
|
+
assert_success(status, stderr, "apply with percentile")
|
|
888
|
+
assert_equal(["20"], lines(stdout), "apply with percentile output")
|
|
889
|
+
|
|
890
|
+
# apply with explicit collection inside map
|
|
891
|
+
stdout, stderr, status = run_jrf('map { |o| [apply(o["vals"]) { |x| sum(x) }, o["name"]] }', '[{"name":"a","vals":[1,2]},{"name":"b","vals":[10,20]}]' + "\n")
|
|
892
|
+
assert_success(status, stderr, "apply with explicit collection")
|
|
893
|
+
assert_equal(['[[3,"a"],[30,"b"]]'], lines(stdout), "apply with explicit collection output")
|
|
894
|
+
|
|
895
|
+
# map with explicit collection
|
|
896
|
+
stdout, stderr, status = run_jrf('map(_["items"]) { |x| x * 2 }', '{"items":[1,2,3]}' + "\n")
|
|
897
|
+
assert_success(status, stderr, "map with explicit collection")
|
|
898
|
+
assert_equal(["[2,4,6]"], lines(stdout), "map with explicit collection output")
|
|
899
|
+
|
|
900
|
+
# map_values with explicit collection
|
|
901
|
+
stdout, stderr, status = run_jrf('map_values(_["data"]) { |v| v * 10 }', '{"data":{"a":1,"b":2}}' + "\n")
|
|
902
|
+
assert_success(status, stderr, "map_values with explicit collection")
|
|
903
|
+
assert_equal(['{"a":10,"b":20}'], lines(stdout), "map_values with explicit collection output")
|
|
904
|
+
|
|
850
905
|
input_gb = <<~NDJSON
|
|
851
906
|
{"status":200,"path":"/a","latency":10}
|
|
852
907
|
{"status":404,"path":"/b","latency":50}
|
|
@@ -944,10 +999,18 @@ assert_equal([[2, 3], [4, 5]], j.call([[1, 2], [3, 4]]), "library map transform"
|
|
|
944
999
|
j = Jrf.new(proc { map { |x| sum(x) } })
|
|
945
1000
|
assert_equal([[4, 6]], j.call([[1, 2], [3, 4]]), "library map reduce")
|
|
946
1001
|
|
|
1002
|
+
# nested map reduce binds to current target
|
|
1003
|
+
j = Jrf.new(proc { map { map { |y| [sum(y[0]), sum(y[1])] } } })
|
|
1004
|
+
assert_equal([[[[4, 6]]]], j.call([[[[1, 2]]], [[[3, 4]]]]), "library nested map reduce")
|
|
1005
|
+
|
|
947
1006
|
# map_values transform
|
|
948
1007
|
j = Jrf.new(proc { map_values { |v| v * 10 } })
|
|
949
1008
|
assert_equal([{"a" => 10, "b" => 20}], j.call([{"a" => 1, "b" => 2}]), "library map_values transform")
|
|
950
1009
|
|
|
1010
|
+
# nested map_values reduce binds to current target
|
|
1011
|
+
j = Jrf.new(proc { map_values { |obj| map_values { |v| sum(v) } } })
|
|
1012
|
+
assert_equal([{"a" => {"x" => 4, "y" => 6}, "b" => {"x" => 40, "y" => 60}}], j.call([{"a" => {"x" => 1, "y" => 2}, "b" => {"x" => 10, "y" => 20}}, {"a" => {"x" => 3, "y" => 4}, "b" => {"x" => 30, "y" => 40}}]), "library nested map_values reduce")
|
|
1013
|
+
|
|
951
1014
|
# map hash transform
|
|
952
1015
|
j = Jrf.new(proc { map { |k, v| "#{k}=#{v}" } })
|
|
953
1016
|
assert_equal([["a=1", "b=2"]], j.call([{"a" => 1, "b" => 2}]), "library map hash transform")
|
|
@@ -960,6 +1023,30 @@ assert_equal([[["a", 1], ["b", 2]]], j.call([{"a" => 1, "b" => 2}]), "library ma
|
|
|
960
1023
|
j = Jrf.new(proc { map { |k, v| sum(v + k.length) } })
|
|
961
1024
|
assert_equal([[5, 7]], j.call([{"a" => 1, "b" => 2}, {"a" => 2, "b" => 3}]), "library map hash reduce")
|
|
962
1025
|
|
|
1026
|
+
# apply - aggregation
|
|
1027
|
+
j = Jrf.new(proc { [apply { |x| sum(x["foo"]) }, _.length] })
|
|
1028
|
+
assert_equal([[3, 2], [10, 1]], j.call([[{"foo" => 1}, {"foo" => 2}], [{"foo" => 10}]]), "library apply reducer")
|
|
1029
|
+
|
|
1030
|
+
# apply - passthrough
|
|
1031
|
+
j = Jrf.new(proc { apply { |x| x["foo"] } })
|
|
1032
|
+
assert_equal([[1, 2]], j.call([[{"foo" => 1}, {"foo" => 2}]]), "library apply passthrough")
|
|
1033
|
+
|
|
1034
|
+
# apply - percentile
|
|
1035
|
+
j = Jrf.new(proc { apply { |x| percentile(x, 0.5) } })
|
|
1036
|
+
assert_equal([20], j.call([[10, 20, 30]]), "library apply percentile")
|
|
1037
|
+
|
|
1038
|
+
# apply with explicit collection inside map
|
|
1039
|
+
j = Jrf.new(proc { map { |o| [apply(o["vals"]) { |x| sum(x) }, o["name"]] } })
|
|
1040
|
+
assert_equal([[[3, "a"], [30, "b"]]], j.call([[{"name" => "a", "vals" => [1, 2]}, {"name" => "b", "vals" => [10, 20]}]]), "library apply explicit collection")
|
|
1041
|
+
|
|
1042
|
+
# map with explicit collection
|
|
1043
|
+
j = Jrf.new(proc { map(_["items"]) { |x| x * 2 } })
|
|
1044
|
+
assert_equal([[2, 4, 6]], j.call([{"items" => [1, 2, 3]}]), "library map explicit collection")
|
|
1045
|
+
|
|
1046
|
+
# map_values with explicit collection
|
|
1047
|
+
j = Jrf.new(proc { map_values(_["data"]) { |v| v * 10 } })
|
|
1048
|
+
assert_equal([{"a" => 10, "b" => 20}], j.call([{"data" => {"a" => 1, "b" => 2}}]), "library map_values explicit collection")
|
|
1049
|
+
|
|
963
1050
|
# group_by
|
|
964
1051
|
j = Jrf.new(proc { group_by(_["k"]) { count() } })
|
|
965
1052
|
assert_equal([{"x" => 2, "y" => 1}], j.call([{"k" => "x"}, {"k" => "x"}, {"k" => "y"}]), "library group_by")
|