pipetree 0.0.2 → 0.0.3
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/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
|