pipetree 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|