pipetree 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +4 -0
- data/lib/pipetree.rb +0 -2
- data/lib/pipetree/flow.rb +81 -76
- data/lib/pipetree/flow/inspect.rb +25 -3
- data/lib/pipetree/insert.rb +18 -12
- data/lib/pipetree/inspect.rb +11 -8
- data/lib/pipetree/version.rb +2 -2
- data/test/altering_test.rb +3 -1
- data/test/flow_test.rb +39 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb0c97eae32d5e5a171288529691ed79df1a66ab
|
4
|
+
data.tar.gz: eff1309c70264642f6b4a75f8e8e47baa8e7d45d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97fde978c2a3c47f32fbb3161c88331b94d9c6e2d1722de2b2c07eedb1552bb93ec2d9b79ebdda5b696df09a28f493200ed4f95529ff769bf742382bd60dd514
|
7
|
+
data.tar.gz: ded7af052db73f8428d8d2c5865e3fddfd3377037a5ec6f6ccd622b552ed72fba12af966f0406418e8ccc9b5c5ece397ca1bf6f8c7027c1c40a2874abb10bd26
|
data/CHANGES.md
CHANGED
data/lib/pipetree.rb
CHANGED
data/lib/pipetree/flow.rb
CHANGED
@@ -1,104 +1,109 @@
|
|
1
|
-
class Pipetree
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
class Pipetree < Array
|
2
|
+
class Flow < Array # yes, we could inherit, and so on.
|
3
|
+
require "pipetree/flow/inspect"
|
4
|
+
include Inspect
|
5
|
+
|
6
|
+
module Operators
|
7
|
+
# Optimize the most common steps with Stay/And objects that are faster than procs.
|
8
|
+
def <(proc, options={})
|
9
|
+
_insert On.new(Left, Stay.new(proc)), options, proc, "<"
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
# OnRight-> ? Right, input : Left, input
|
13
|
+
def &(proc, options={})
|
14
|
+
_insert On.new(Right, And.new(proc)), options, proc, "&"
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
# TODO: test me.
|
18
|
+
def >(proc, options={})
|
19
|
+
_insert On.new(Right, Stay.new(proc)), options, proc, ">"
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
def >>(proc, options={})
|
23
|
+
_insert On.new(Right,
|
24
|
+
->(last, input, options) { [Right, proc.(input, options)] } ), options, proc, ">>"
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
def %(proc, options={})
|
28
|
+
# no condition is needed, and we want to stay on the same track, too.
|
29
|
+
_insert Stay.new(proc), options, proc, "%"
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
# :private:
|
33
|
+
# proc is the original step proc, e.g. Validate.
|
34
|
+
def _insert(step, options, original_proc, operator)
|
35
|
+
name = options[:name]
|
36
|
+
options = { append: true } if options.empty? || options.keys == [:name]
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
insert!(step, options).tap do
|
39
|
+
@step2proc ||= {}
|
40
|
+
@step2proc[step] = Inspect::Proc.new(name, original_proc, operator)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# :private:
|
45
|
+
def index(step) # @step2proc: { <On @proc> => {proc: @proc, name: "trb.validate", operator: "&"} }
|
46
|
+
method = step.is_a?(String) ? :name : :proc
|
47
|
+
@step2proc.find { |on, inspect_proc| inspect_proc.send(method) == step and return super(on) }
|
39
48
|
end
|
40
49
|
end
|
41
|
-
|
42
|
-
include Operators
|
50
|
+
include Operators
|
43
51
|
|
44
|
-
|
45
|
-
|
46
|
-
|
52
|
+
# Actual implementation of Pipetree:Flow. Yes, it's that simple!
|
53
|
+
def call(input, options)
|
54
|
+
input = [Right, input]
|
47
55
|
|
48
|
-
|
49
|
-
|
50
|
-
|
56
|
+
inject(input) do |memooo, step|
|
57
|
+
last, memo = memooo
|
58
|
+
step.call(last, memo, options)
|
59
|
+
end
|
51
60
|
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def index(step) # @debug maps the original user's step proc to the On instance (or any kind of wrapper proc).
|
55
|
-
@debug.find { |on, inspect_proc| inspect_proc.proc == step and return super(on) }
|
56
|
-
end
|
57
61
|
|
58
|
-
|
59
|
-
|
60
|
-
|
62
|
+
# Directions emitted by steps.
|
63
|
+
Left = Class.new
|
64
|
+
Right = Class.new
|
61
65
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
66
|
+
# Incoming direction must be Left/Right.
|
67
|
+
class On
|
68
|
+
def initialize(direction, proc)
|
69
|
+
@direction, @proc = direction, proc
|
70
|
+
end
|
67
71
|
|
68
|
-
|
69
|
-
|
70
|
-
|
72
|
+
def call(last, input, options)
|
73
|
+
return [last, input] unless last == @direction # return unless incoming direction is Right (or Left).
|
74
|
+
@proc.(last, input, options)
|
75
|
+
end
|
71
76
|
end
|
72
|
-
end
|
73
77
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
78
|
+
# Call step proc and return (Right || Left).
|
79
|
+
class And
|
80
|
+
def initialize(proc)
|
81
|
+
@proc = proc
|
82
|
+
end
|
79
83
|
|
80
|
-
|
81
|
-
|
84
|
+
def call(last, input, options)
|
85
|
+
@proc.(input, options) ? [Right, input] : [Left, input]
|
86
|
+
end
|
82
87
|
end
|
83
|
-
end
|
84
88
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
89
|
+
# Call step proc and return incoming last step.
|
90
|
+
class Stay < And
|
91
|
+
def call(last, input, options)
|
92
|
+
@proc.(input, options)
|
93
|
+
[last, input] # simply pass through the current direction: either [Left, input] or [Right, input].
|
94
|
+
end
|
90
95
|
end
|
91
|
-
end
|
92
96
|
|
93
97
|
|
94
98
|
|
95
99
|
|
96
100
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
+
require "pipetree/insert"
|
102
|
+
module Macros
|
103
|
+
def insert!(new_function, options)
|
104
|
+
Pipetree::Insert.(self, new_function, options)
|
105
|
+
end
|
101
106
|
end
|
107
|
+
include Macros # FIXME: we shouldn't expose #insert!
|
102
108
|
end
|
103
|
-
include Macros # FIXME: we shouldn't expose #insert!
|
104
109
|
end
|
@@ -3,11 +3,11 @@ require "pipetree/inspect"
|
|
3
3
|
module Pipetree::Flow::Inspect
|
4
4
|
include ::Pipetree::Inspect
|
5
5
|
|
6
|
-
Proc = Struct.new(:proc, :operator)
|
6
|
+
Proc = Struct.new(:name, :proc, :operator)
|
7
7
|
|
8
8
|
def inspect_for(step)
|
9
|
-
|
10
|
-
[super(
|
9
|
+
cfg = @step2proc[step]
|
10
|
+
[cfg.name || super(cfg.proc), cfg.operator]
|
11
11
|
end
|
12
12
|
|
13
13
|
def inspect_line(names)
|
@@ -18,4 +18,26 @@ module Pipetree::Flow::Inspect
|
|
18
18
|
def inspect_row(index, name)
|
19
19
|
"#{index} #{name.last}#{name.first}"
|
20
20
|
end
|
21
|
+
|
22
|
+
def inspect_rows(names)
|
23
|
+
string = names.collect do |i, (name, operator)|
|
24
|
+
|
25
|
+
op = "#{operator}#{name}"
|
26
|
+
padding = 38
|
27
|
+
|
28
|
+
proc = if operator == "<"
|
29
|
+
sprintf("%- #{padding}s", op)
|
30
|
+
elsif [">", ">>", "&"].include?(operator.to_s)
|
31
|
+
sprintf("% #{padding}s", op)
|
32
|
+
else
|
33
|
+
pad = " " * ((padding - op.length) / 2)
|
34
|
+
"#{pad}#{op}#{pad}"
|
35
|
+
end
|
36
|
+
|
37
|
+
proc = proc.gsub(" ", "=")
|
38
|
+
|
39
|
+
sprintf("%2d %s", i, proc)
|
40
|
+
end.join("\n")
|
41
|
+
"\n#{string}"
|
42
|
+
end
|
21
43
|
end
|
data/lib/pipetree/insert.rb
CHANGED
@@ -15,24 +15,30 @@ module Pipetree::Function
|
|
15
15
|
|
16
16
|
private
|
17
17
|
def replace!(arr, old_func, new_func)
|
18
|
-
arr.
|
19
|
-
if func.is_a?(Collect)
|
20
|
-
arr[index] = Collect[*Pipeline::Insert.(func, new_func, replace: old_func)]
|
21
|
-
end
|
18
|
+
arr[arr.index(old_func)] = new_func
|
22
19
|
|
23
|
-
|
24
|
-
|
20
|
+
# arr.each_with_index { |func, index|
|
21
|
+
# if func.is_a?(::Pipetree::Collect)
|
22
|
+
# arr[index] = Collect[*Pipeline::Insert.(func, new_func, replace: old_func)]
|
23
|
+
# end
|
24
|
+
|
25
|
+
# arr[index] = new_func if func==old_func
|
26
|
+
# }
|
27
|
+
arr
|
25
28
|
end
|
26
29
|
|
27
30
|
def delete!(arr, removed_func)
|
28
|
-
arr.
|
31
|
+
index = arr.index(removed_func)
|
32
|
+
arr.delete_at(index)
|
29
33
|
|
30
34
|
# TODO: make nice.
|
31
|
-
arr.each_with_index { |func, index|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
}
|
35
|
+
# arr.each_with_index { |func, index|
|
36
|
+
# if func.is_a?(Collect)
|
37
|
+
# arr[index] = Collect[*Pipeline::Insert.(func, removed_func, delete: true)]
|
38
|
+
# end
|
39
|
+
# }
|
40
|
+
|
41
|
+
arr
|
36
42
|
end
|
37
43
|
|
38
44
|
# TODO: not nested.
|
data/lib/pipetree/inspect.rb
CHANGED
@@ -7,14 +7,7 @@ module Pipetree::Inspect
|
|
7
7
|
end
|
8
8
|
|
9
9
|
return inspect_line(names) if options[:style] == :line
|
10
|
-
|
11
|
-
string = names.collect do |i, name|
|
12
|
-
index = sprintf("%2d", i)
|
13
|
-
inspect_row(index, name)
|
14
|
-
end.join("\n")
|
15
|
-
# name = sprintf("%-60.300s", name) # no idea what i'm doing here.
|
16
|
-
# "#{index}) #{name} #{func.source_location.join(":")}"
|
17
|
-
"\n#{string}"
|
10
|
+
inspect_rows(names)
|
18
11
|
end
|
19
12
|
|
20
13
|
# open source file to retrieve the constant name.
|
@@ -27,6 +20,16 @@ module Pipetree::Inspect
|
|
27
20
|
"[#{string}]"
|
28
21
|
end
|
29
22
|
|
23
|
+
def inspect_rows(names)
|
24
|
+
string = names.collect do |i, name|
|
25
|
+
index = sprintf("%2d", i)
|
26
|
+
inspect_row(index, name)
|
27
|
+
end.join("\n")
|
28
|
+
# name = sprintf("%-60.300s", name) # no idea what i'm doing here.
|
29
|
+
# "#{index}) #{name} #{func.source_location.join(":")}"
|
30
|
+
"\n#{string}"
|
31
|
+
end
|
32
|
+
|
30
33
|
def inspect_row(index, name)
|
31
34
|
"#{index}|>#{name}"
|
32
35
|
end
|
data/lib/pipetree/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.0.
|
1
|
+
class Pipetree < Array
|
2
|
+
VERSION = "0.0.3"
|
3
3
|
end
|
data/test/altering_test.rb
CHANGED
@@ -28,6 +28,7 @@ class AlteringTest < Minitest::Spec
|
|
28
28
|
it { Pipetree[].insert!(C, prepend: true).inspect.must_equal %{[C]} }
|
29
29
|
end
|
30
30
|
|
31
|
+
require "pipetree/flow"
|
31
32
|
class FlowInsertTest < Minitest::Spec
|
32
33
|
A = ->{ }
|
33
34
|
B = ->{ }
|
@@ -38,7 +39,8 @@ class FlowInsertTest < Minitest::Spec
|
|
38
39
|
it { pipe = Pipetree::Flow[].>(A).>(B).>(C, after: A).inspect.must_equal %{[>A,>C,>B]} }
|
39
40
|
it { pipe = Pipetree::Flow[].>(A).>(C, append: true).inspect.must_equal %{[>A,>C]} }
|
40
41
|
it { pipe = Pipetree::Flow[].>(A).>(C, prepend: true).inspect.must_equal %{[>C,>A]} }
|
41
|
-
|
42
|
+
it { pipe = Pipetree::Flow[].>(A).>(C, replace: A).inspect.must_equal %{[>C]} }
|
43
|
+
it { pipe = Pipetree::Flow[].>(A)._insert(A, {delete: true}, nil, nil).inspect.must_equal %{[]} }
|
42
44
|
|
43
45
|
# FIXME: add :delete and :replace.
|
44
46
|
end
|
data/test/flow_test.rb
CHANGED
@@ -28,17 +28,17 @@ require "json"
|
|
28
28
|
class FlowTest < Minitest::Spec
|
29
29
|
# TODO: test each function from & to > is only called once!
|
30
30
|
# describe "#call" do
|
31
|
-
# let (:pipe) { Pipetree::Flow
|
31
|
+
# let (:pipe) { Pipetree::Flow.new }
|
32
32
|
# it do
|
33
33
|
# pipe.>> ->(*) { puts "snippet" }
|
34
34
|
# pipe.({},{})
|
35
35
|
# end
|
36
36
|
# end
|
37
37
|
|
38
|
-
|
39
|
-
B
|
38
|
+
Aaa = ->(*) { }
|
39
|
+
B = ->(*) { }
|
40
40
|
|
41
|
-
let (:pipe) { pipe = Pipetree::Flow
|
41
|
+
let (:pipe) { pipe = Pipetree::Flow.new
|
42
42
|
pipe.& ->(value, options) { value && options["deserializer.result"] = JSON.parse(value) }
|
43
43
|
pipe.& ->(value, options) { options["deserializer.result"]["key"] == 1 ? true : (options["contract.errors"]=false) }
|
44
44
|
pipe.& ->(value, options) { options["deserializer.result"]["key2"] == 2 ? true : (options["contract.errors.2"]="screwd";false) }
|
@@ -64,7 +64,7 @@ class FlowTest < Minitest::Spec
|
|
64
64
|
options.must_equal({"deserializer.result"=>{"key"=>2}, "contract.errors"=>false, "after_deserialize.fail"=>true, "meantime"=>true, "after_meantime.left?"=>true})
|
65
65
|
end
|
66
66
|
|
67
|
-
it
|
67
|
+
it do
|
68
68
|
options = {}
|
69
69
|
pipe.(%{{"key": 1,"key2":null}}, options)#.must_equal ""
|
70
70
|
|
@@ -83,7 +83,7 @@ class FlowTest < Minitest::Spec
|
|
83
83
|
#---
|
84
84
|
# #>
|
85
85
|
describe "#>" do
|
86
|
-
let (:pipe) { Pipetree::Flow
|
86
|
+
let (:pipe) { Pipetree::Flow.new }
|
87
87
|
it {
|
88
88
|
pipe.> ->(input, options) { input.reverse }
|
89
89
|
# pipe.| B
|
@@ -94,7 +94,7 @@ class FlowTest < Minitest::Spec
|
|
94
94
|
|
95
95
|
# #>>
|
96
96
|
describe "#>>" do
|
97
|
-
let (:pipe) { Pipetree::Flow
|
97
|
+
let (:pipe) { Pipetree::Flow.new }
|
98
98
|
it {
|
99
99
|
pipe.>> ->(input, options) { input.reverse }
|
100
100
|
pipe.("Hallo", {}).must_equal [Pipetree::Flow::Right, "ollaH"]
|
@@ -103,22 +103,47 @@ class FlowTest < Minitest::Spec
|
|
103
103
|
|
104
104
|
#---
|
105
105
|
# #inspect
|
106
|
+
Seventeen = ->(*) { snippet }
|
107
|
+
Long = ->(*) { snippet }
|
108
|
+
|
106
109
|
describe "#inspect" do
|
107
|
-
let (:pipe) { Pipetree::Flow
|
110
|
+
let (:pipe) { Pipetree::Flow.new.&(Aaa).>>(Long).<(B).%(Aaa).<(Seventeen).>(Long) }
|
108
111
|
|
109
|
-
it { pipe.inspect.must_equal %{[&
|
112
|
+
it { pipe.inspect.must_equal %{[&Aaa,>>Long,<B,%Aaa,<Seventeen,>Long]} }
|
110
113
|
|
111
114
|
it { pipe.inspect(style: :rows).must_equal %{
|
112
|
-
0
|
113
|
-
1
|
114
|
-
2
|
115
|
+
0 ==================================&Aaa
|
116
|
+
1 ================================>>Long
|
117
|
+
2 <B====================================
|
118
|
+
3 =================%Aaa=================
|
119
|
+
4 <Seventeen============================
|
120
|
+
5 =================================>Long} }
|
115
121
|
end
|
116
122
|
|
117
123
|
describe "#index" do
|
118
|
-
let (:pipe) { Pipetree::Flow
|
124
|
+
let (:pipe) { Pipetree::Flow.new.&(Aaa).<(B).%(Aaa, name: "a.triple") }
|
119
125
|
|
120
126
|
it { pipe.index(B).must_equal 1 }
|
121
|
-
it { pipe.index(
|
127
|
+
it { pipe.index(Aaa).must_equal 0 }
|
128
|
+
# with alias
|
129
|
+
it { pipe.index("a.triple").must_equal 2 }
|
130
|
+
end
|
131
|
+
|
132
|
+
#---
|
133
|
+
# with aliases
|
134
|
+
it do
|
135
|
+
pipe = Pipetree::Flow.new.
|
136
|
+
>(Aaa, name: "pipe.aaa").
|
137
|
+
>(B, name: "pipe.b").
|
138
|
+
>(Aaa, name: "pipe.aaa.aaa")
|
139
|
+
|
140
|
+
pipe.inspect.must_equal %{[>pipe.aaa,>pipe.b,>pipe.aaa.aaa]}
|
141
|
+
pipe.inspect(style: :rows).must_equal %{
|
142
|
+
0 =============================>pipe.aaa
|
143
|
+
1 ===============================>pipe.b
|
144
|
+
2 =========================>pipe.aaa.aaa}
|
145
|
+
|
146
|
+
pipe.>(Long, after: "pipe.b").inspect.must_equal %{[>pipe.aaa,>pipe.b,>Long,>pipe.aaa.aaa]}
|
122
147
|
end
|
123
148
|
end
|
124
149
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pipetree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|