pipetree 0.0.3 → 0.0.4
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/.travis.yml +8 -0
- data/Gemfile +0 -2
- data/README.md +9 -0
- data/lib/pipetree/flow/inspect.rb +1 -1
- data/lib/pipetree/flow/step_map.rb +24 -0
- data/lib/pipetree/flow.rb +8 -18
- data/lib/pipetree/insert.rb +11 -7
- data/lib/pipetree/inspect.rb +12 -3
- data/lib/pipetree/version.rb +1 -1
- data/test/altering_test.rb +5 -3
- data/test/flow_test.rb +39 -4
- data/test/inspect_test.rb +5 -3
- data/test/pipetree_test.rb +13 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13019affb084e0a3dc4470feec4f21c904a1af83
|
4
|
+
data.tar.gz: ea2b5913c8afad622ad624cd77736c9b6a601304
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 521d4af02d44620e9a510a8e9703d843cda87aaccc02962d9b194881c837f56d3d1b4d9d77d0e5d127c66f9f24333ccabc94af763679eea3b98709b28d4ccf98
|
7
|
+
data.tar.gz: f49f1e93b4371a6282f71bfc24ab6241a86d118810cf0ab35a44f88f43adcd12529e6ad8fbac6ac8bbc156897ede6ad1fd9eabdcc368b70adc9b0f426373ce00
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -16,6 +16,15 @@ Instead of implementing the perfect API where users can override methods, call `
|
|
16
16
|
|
17
17
|
This is way less tedious than climbing through `super` calls and callstacks.
|
18
18
|
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
In your `Gemfile`.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem "pipetree"
|
25
|
+
```
|
26
|
+
|
27
|
+
Pipetree runs with Ruby >= 1.9.3.
|
19
28
|
|
20
29
|
## TODO
|
21
30
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Map original proc or its name to the wrapped On.
|
2
|
+
# This class is solely dedicated for inspect and insert operations, and not
|
3
|
+
# involved at run-time at all.
|
4
|
+
class Pipetree::Flow::StepMap
|
5
|
+
def initialize
|
6
|
+
@hash = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def []=(step, (name, original_proc, operator))
|
10
|
+
@hash[step] = Pipetree::Flow::Inspect::Proc.new(name, original_proc, operator)
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](key)
|
14
|
+
@hash[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_proc(original_proc)
|
18
|
+
method = original_proc.is_a?(String) ? :name : :proc
|
19
|
+
|
20
|
+
@hash.find do |step, inspect_proc|
|
21
|
+
inspect_proc.send(method) == original_proc and return step
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/pipetree/flow.rb
CHANGED
@@ -2,6 +2,8 @@ class Pipetree < Array
|
|
2
2
|
class Flow < Array # yes, we could inherit, and so on.
|
3
3
|
require "pipetree/flow/inspect"
|
4
4
|
include Inspect
|
5
|
+
require "pipetree/flow/step_map"
|
6
|
+
require "pipetree/insert"
|
5
7
|
|
6
8
|
module Operators
|
7
9
|
# Optimize the most common steps with Stay/And objects that are faster than procs.
|
@@ -32,19 +34,17 @@ class Pipetree < Array
|
|
32
34
|
# :private:
|
33
35
|
# proc is the original step proc, e.g. Validate.
|
34
36
|
def _insert(step, options, original_proc, operator)
|
35
|
-
|
36
|
-
options = { append: true } if options.empty? || options.keys == [:name]
|
37
|
+
options = { append: true }.merge(options)
|
37
38
|
|
38
39
|
insert!(step, options).tap do
|
39
|
-
@step2proc ||=
|
40
|
-
@step2proc[step] =
|
40
|
+
@step2proc ||= StepMap.new
|
41
|
+
@step2proc[step] = options[:name], original_proc, operator
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
44
45
|
# :private:
|
45
|
-
def index(
|
46
|
-
|
47
|
-
@step2proc.find { |on, inspect_proc| inspect_proc.send(method) == step and return super(on) }
|
46
|
+
def index(proc) # @step2proc: { <On @proc> => {proc: @proc, name: "trb.validate", operator: "&"} }
|
47
|
+
on = @step2proc.find_proc(proc) and return super(on)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
include Operators
|
@@ -94,16 +94,6 @@ class Pipetree < Array
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
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
|
106
|
-
end
|
107
|
-
include Macros # FIXME: we shouldn't expose #insert!
|
97
|
+
include Function::Insert::Macros # #insert!
|
108
98
|
end
|
109
99
|
end
|
data/lib/pipetree/insert.rb
CHANGED
@@ -2,12 +2,10 @@ module Pipetree::Function
|
|
2
2
|
class Insert
|
3
3
|
def call(arr, func, options)
|
4
4
|
# arr = arr.dup
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
return
|
9
|
-
return append!(arr, options[:append], func) if options[:append]
|
10
|
-
return prepend!(arr, options[:prepend], func) if options[:prepend]
|
5
|
+
operations = [:delete, :replace, :before, :after, :append, :prepend]
|
6
|
+
|
7
|
+
# replace!(arr, options[:replace], func)
|
8
|
+
options.keys.reverse.each { |k| operations.include?(k) and return send("#{k}!", arr, options[k], func) }
|
11
9
|
|
12
10
|
raise "[Pipetree] Unknown command #{options.inspect}" # TODO: test.
|
13
11
|
# arr
|
@@ -27,7 +25,7 @@ module Pipetree::Function
|
|
27
25
|
arr
|
28
26
|
end
|
29
27
|
|
30
|
-
def delete!(arr, removed_func)
|
28
|
+
def delete!(arr, _, removed_func)
|
31
29
|
index = arr.index(removed_func)
|
32
30
|
arr.delete_at(index)
|
33
31
|
|
@@ -59,6 +57,12 @@ module Pipetree::Function
|
|
59
57
|
def prepend!(arr, old_func, new_func)
|
60
58
|
arr.unshift(new_func)
|
61
59
|
end
|
60
|
+
|
61
|
+
module Macros
|
62
|
+
def insert!(new_function, options)
|
63
|
+
Pipetree::Insert.(self, new_function, options)
|
64
|
+
end
|
65
|
+
end
|
62
66
|
end
|
63
67
|
end
|
64
68
|
|
data/lib/pipetree/inspect.rb
CHANGED
@@ -3,7 +3,7 @@ module Pipetree::Inspect
|
|
3
3
|
# TODO: remove in Representable::Debug.
|
4
4
|
def inspect(options={ style: :line })
|
5
5
|
names = each_with_index.collect do |func, i|
|
6
|
-
[i,
|
6
|
+
[i, inspect_func(func)]
|
7
7
|
end
|
8
8
|
|
9
9
|
return inspect_line(names) if options[:style] == :line
|
@@ -11,8 +11,17 @@ module Pipetree::Inspect
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# open source file to retrieve the constant name.
|
14
|
-
def
|
15
|
-
|
14
|
+
def inspect_func(func)
|
15
|
+
return inspect_object(func) unless func.is_a?(Proc)
|
16
|
+
inspect_proc(func)
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect_object(obj)
|
20
|
+
obj.inspect.sub(/0x\w+/, "")
|
21
|
+
end
|
22
|
+
|
23
|
+
def inspect_proc(proc)
|
24
|
+
File.readlines(proc.source_location[0])[proc.source_location[1]-1].match(/^\s+([\w\:]+)/)[1]
|
16
25
|
end
|
17
26
|
|
18
27
|
def inspect_line(names)
|
data/lib/pipetree/version.rb
CHANGED
data/test/altering_test.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
3
|
class AlteringTest < Minitest::Spec
|
4
|
-
A = ->(*) { }
|
4
|
+
A = ->(*) { "bla ruby 1.9 needs that" }
|
5
5
|
B = ->(*) { }
|
6
|
-
C = ->(*) { }
|
6
|
+
C = ->(*) { "otherwise it'll confuse empty procs" }
|
7
7
|
|
8
8
|
# constructor.
|
9
9
|
it do
|
@@ -26,6 +26,9 @@ class AlteringTest < Minitest::Spec
|
|
26
26
|
|
27
27
|
it { Pipetree[A,B].insert!(C, prepend: true).inspect.must_equal %{[C|>A|>B]} }
|
28
28
|
it { Pipetree[].insert!(C, prepend: true).inspect.must_equal %{[C]} }
|
29
|
+
|
30
|
+
# last option wins
|
31
|
+
it { Pipetree[A,B].insert!(C, after: B, prepend: true).inspect.must_equal %{[C|>A|>B]} }
|
29
32
|
end
|
30
33
|
|
31
34
|
require "pipetree/flow"
|
@@ -41,6 +44,5 @@ class FlowInsertTest < Minitest::Spec
|
|
41
44
|
it { pipe = Pipetree::Flow[].>(A).>(C, prepend: true).inspect.must_equal %{[>C,>A]} }
|
42
45
|
it { pipe = Pipetree::Flow[].>(A).>(C, replace: A).inspect.must_equal %{[>C]} }
|
43
46
|
it { pipe = Pipetree::Flow[].>(A)._insert(A, {delete: true}, nil, nil).inspect.must_equal %{[]} }
|
44
|
-
|
45
47
|
# FIXME: add :delete and :replace.
|
46
48
|
end
|
data/test/flow_test.rb
CHANGED
@@ -35,7 +35,7 @@ class FlowTest < Minitest::Spec
|
|
35
35
|
# end
|
36
36
|
# end
|
37
37
|
|
38
|
-
Aaa = ->(*) {
|
38
|
+
Aaa = ->(*) { "yo" }
|
39
39
|
B = ->(*) { }
|
40
40
|
|
41
41
|
let (:pipe) { pipe = Pipetree::Flow.new
|
@@ -105,11 +105,12 @@ class FlowTest < Minitest::Spec
|
|
105
105
|
# #inspect
|
106
106
|
Seventeen = ->(*) { snippet }
|
107
107
|
Long = ->(*) { snippet }
|
108
|
+
Callable = Object.new # random callable object.
|
108
109
|
|
109
110
|
describe "#inspect" do
|
110
|
-
let (:pipe) { Pipetree::Flow.new.&(Aaa).>>(Long).<(B).%(Aaa).<(Seventeen).>(Long) }
|
111
|
+
let (:pipe) { Pipetree::Flow.new.&(Aaa).>>(Long).<(B).%(Aaa).<(Seventeen).>(Long).>(Callable) }
|
111
112
|
|
112
|
-
it { pipe.inspect.must_equal %{[&Aaa,>>Long,<B,%Aaa,<Seventeen,>Long]} }
|
113
|
+
it { pipe.inspect.must_equal %{[&Aaa,>>Long,<B,%Aaa,<Seventeen,>Long,>#<Object:>]} }
|
113
114
|
|
114
115
|
it { pipe.inspect(style: :rows).must_equal %{
|
115
116
|
0 ==================================&Aaa
|
@@ -117,7 +118,8 @@ class FlowTest < Minitest::Spec
|
|
117
118
|
2 <B====================================
|
118
119
|
3 =================%Aaa=================
|
119
120
|
4 <Seventeen============================
|
120
|
-
5 =================================>Long
|
121
|
+
5 =================================>Long
|
122
|
+
6 ===========================>#<Object:>} }
|
121
123
|
end
|
122
124
|
|
123
125
|
describe "#index" do
|
@@ -145,6 +147,39 @@ class FlowTest < Minitest::Spec
|
|
145
147
|
|
146
148
|
pipe.>(Long, after: "pipe.b").inspect.must_equal %{[>pipe.aaa,>pipe.b,>Long,>pipe.aaa.aaa]}
|
147
149
|
end
|
150
|
+
|
151
|
+
#---
|
152
|
+
# test decompose array
|
153
|
+
it do
|
154
|
+
pipe = Pipetree::Flow.new.
|
155
|
+
>>( ->(input, options) { [options[:key], input] } ). # passes [bla, input] as input.
|
156
|
+
&( ->((value, input), options) { input["x"] = value } ) # decomposes input.
|
157
|
+
|
158
|
+
pipe.(input={}, options={key: 1}).must_equal [Pipetree::Flow::Right, [1, {"x"=>1}]]
|
159
|
+
input.inspect.must_equal %{{"x"=>1}}
|
160
|
+
options.inspect.must_equal %{{:key=>1}}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
#- StepMap
|
165
|
+
class StepMapTest < Minitest::Spec
|
166
|
+
it do
|
167
|
+
map = Pipetree::Flow::StepMap.new
|
168
|
+
|
169
|
+
original_proc = ->(*) { snippet }
|
170
|
+
step = ->(*) { original_proc }
|
171
|
+
|
172
|
+
original_proc2 = ->(*) { snippet }
|
173
|
+
step2 = ->(*) { original_proc2 }
|
174
|
+
|
175
|
+
map[step] = "my.step", original_proc, ">"
|
176
|
+
map[step2] = "my.step2", original_proc2, ">"
|
177
|
+
|
178
|
+
map.find_proc(original_proc).must_equal step
|
179
|
+
map.find_proc("my.step").must_equal step
|
180
|
+
map.find_proc(original_proc2).must_equal step2
|
181
|
+
map.find_proc("my.step2").must_equal step2
|
182
|
+
end
|
148
183
|
end
|
149
184
|
|
150
185
|
# TODO: instead of testing #index, test all options like :before, etc.
|
data/test/inspect_test.rb
CHANGED
@@ -6,8 +6,9 @@ class InspectTest < Minitest::Spec
|
|
6
6
|
|
7
7
|
M::AlphaConstant = ->(*) { }
|
8
8
|
M::Beta = ->(*) { }
|
9
|
+
Callable = Object.new
|
9
10
|
|
10
|
-
let (:pipe) { ::Pipetree[M::Beta, M::AlphaConstant, M::Beta, M::AlphaConstant, M::Beta, M::AlphaConstant, M::Beta, M::AlphaConstant, M::Beta, M::AlphaConstant, M::Beta] }
|
11
|
+
let (:pipe) { ::Pipetree[M::Beta, M::AlphaConstant, M::Beta, M::AlphaConstant, M::Beta, M::AlphaConstant, M::Beta, M::AlphaConstant, M::Beta, M::AlphaConstant, M::Beta, Callable] }
|
11
12
|
|
12
13
|
it do
|
13
14
|
puts pipe.inspect
|
@@ -25,9 +26,10 @@ class InspectTest < Minitest::Spec
|
|
25
26
|
7|>M::AlphaConstant
|
26
27
|
8|>M::Beta
|
27
28
|
9|>M::AlphaConstant
|
28
|
-
10|>M::Beta
|
29
|
+
10|>M::Beta
|
30
|
+
11|>#<Object:>}
|
29
31
|
end
|
30
32
|
|
31
33
|
# different separator
|
32
|
-
it { ::Pipetree[M::AlphaConstant,M::Beta].inspect.must_equal %{[M::AlphaConstant|>M::Beta]} }
|
34
|
+
it { ::Pipetree[M::AlphaConstant,M::Beta,Callable].inspect.must_equal %{[M::AlphaConstant|>M::Beta|>#<Object:>]} }
|
33
35
|
end
|
data/test/pipetree_test.rb
CHANGED
@@ -71,6 +71,17 @@ class PipelineTest < MiniTest::Spec
|
|
71
71
|
Pipetree[First, Second].("", options={}, memory={})
|
72
72
|
end
|
73
73
|
|
74
|
+
#---
|
75
|
+
#- #index
|
76
|
+
it do
|
77
|
+
A = ->(*) { snippet }
|
78
|
+
B = ->(*) { snippet }
|
79
|
+
|
80
|
+
pipe = Pipetree[A, B]
|
81
|
+
pipe.index(A).must_equal 0
|
82
|
+
pipe.index(B).must_equal 1
|
83
|
+
end
|
84
|
+
|
74
85
|
# ######### collection :ratings
|
75
86
|
|
76
87
|
# let (:ratings) {
|
@@ -147,6 +158,8 @@ class PipelineTest < MiniTest::Spec
|
|
147
158
|
|
148
159
|
# it "replaces if exists" do
|
149
160
|
# # pipeline.insert!(R::Default, replace: R::StopOnSkipable)
|
161
|
+
|
162
|
+
|
150
163
|
# P::Insert.(pipeline, R::Default, replace: R::StopOnSkipable).must_equal P[R::GetValue, R::Default, R::StopOnNil]
|
151
164
|
# pipeline.must_equal P[R::GetValue, R::StopOnSkipable, R::StopOnNil]
|
152
165
|
# end
|
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.4
|
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-09 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
|
+
- ".travis.yml"
|
62
63
|
- CHANGES.md
|
63
64
|
- Gemfile
|
64
65
|
- README.md
|
@@ -66,6 +67,7 @@ files:
|
|
66
67
|
- lib/pipetree.rb
|
67
68
|
- lib/pipetree/flow.rb
|
68
69
|
- lib/pipetree/flow/inspect.rb
|
70
|
+
- lib/pipetree/flow/step_map.rb
|
69
71
|
- lib/pipetree/insert.rb
|
70
72
|
- lib/pipetree/inspect.rb
|
71
73
|
- lib/pipetree/version.rb
|