composable_operations 0.2.0 → 0.3.0
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35bf16a747c65f1dcd6f9e7003f6fb574d86b4b5
|
4
|
+
data.tar.gz: d456bb506cef1eb336fbf82d3d80718d28e0c648
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: caaec98652d28e2f1af2856a93adef45536ce173ff04e632362e5d97e64c22c7d415bc6a2206da36889675d3435e30222fd96bf7be3cc003e300d03c6a262609
|
7
|
+
data.tar.gz: 84498a024f0c4564ef33dd276566090d0898d8fadc10e8a4eff7680e70721140943ba5d1c19dc365e8682d87d8010c513979856d1cc378af7eba983c39c879f7
|
@@ -1,13 +1,32 @@
|
|
1
1
|
module ComposableOperations
|
2
2
|
class ComposedOperation < Operation
|
3
|
+
|
4
|
+
class AutoConfiguringOperation < SimpleDelegator
|
5
|
+
|
6
|
+
def initialize(operation_class, options = {})
|
7
|
+
super(operation_class)
|
8
|
+
@__options__ = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def new(input = nil, options = {})
|
12
|
+
options = Hash(__options__).merge(Hash(options))
|
13
|
+
__getobj__.new(input, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
attr_reader :__options__
|
19
|
+
|
20
|
+
end
|
21
|
+
|
3
22
|
class << self
|
4
23
|
|
5
24
|
def operations
|
6
25
|
[] + Array((super if defined? super)) + Array(@operations)
|
7
26
|
end
|
8
27
|
|
9
|
-
def use(operation)
|
10
|
-
(@operations ||= []) << operation
|
28
|
+
def use(operation, options = {})
|
29
|
+
(@operations ||= []) << AutoConfiguringOperation.new(operation, options)
|
11
30
|
end
|
12
31
|
|
13
32
|
def compose(*operations, &block)
|
@@ -24,54 +43,24 @@ module ComposableOperations
|
|
24
43
|
end
|
25
44
|
end
|
26
45
|
|
27
|
-
def transitions
|
28
|
-
transitions = []
|
29
|
-
klass = self
|
30
|
-
while klass != Operation
|
31
|
-
klass = klass.superclass
|
32
|
-
transitions += Array(klass.instance_variable_get(:@transitions))
|
33
|
-
end
|
34
|
-
transitions += Array(@transitions)
|
35
|
-
transitions
|
36
|
-
end
|
37
|
-
|
38
|
-
|
39
|
-
protected
|
40
|
-
|
41
|
-
def between(&callback)
|
42
|
-
(@transitions ||= []) << callback
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def operations
|
48
|
-
self.class.operations
|
49
46
|
end
|
50
47
|
|
51
48
|
protected
|
52
49
|
|
53
50
|
def execute
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
transition(*operations, data) if operations.first && operations.last
|
66
|
-
operation.result
|
67
|
-
else
|
68
|
-
data
|
51
|
+
self.class.operations.inject(input) do |data, operation_and_options|
|
52
|
+
operation, options = *operation_and_options
|
53
|
+
operation = operation.new(data, options)
|
54
|
+
operation.perform
|
55
|
+
|
56
|
+
if operation.failed?
|
57
|
+
fail operation.message, operation.result, operation.backtrace
|
58
|
+
elsif operation.halted?
|
59
|
+
halt operation.message, operation.result
|
69
60
|
end
|
70
|
-
end
|
71
|
-
end
|
72
61
|
|
73
|
-
|
74
|
-
|
62
|
+
operation.result
|
63
|
+
end
|
75
64
|
end
|
76
65
|
|
77
66
|
end
|
@@ -26,6 +26,21 @@ describe ComposableOperations::ComposedOperation do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
let(:string_multiplier) do
|
30
|
+
Class.new(ComposableOperations::Operation) do
|
31
|
+
property :multiplicator, default: 1, converts: :to_i, required: true
|
32
|
+
property :separator, default: ' ', converts: :to_s, required: true
|
33
|
+
|
34
|
+
def self.name
|
35
|
+
"StringMultiplier"
|
36
|
+
end
|
37
|
+
|
38
|
+
def execute
|
39
|
+
(Array(input) * multiplicator).join(separator)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
29
44
|
let(:halting_operation) do
|
30
45
|
Class.new(ComposableOperations::Operation) do
|
31
46
|
def execute
|
@@ -50,7 +65,23 @@ describe ComposableOperations::ComposedOperation do
|
|
50
65
|
|
51
66
|
end
|
52
67
|
|
53
|
-
context "when composed of two operations
|
68
|
+
context "when composed of two operations, one that generates a string and one that multiplies it" do
|
69
|
+
|
70
|
+
subject(:composed_operation) do
|
71
|
+
string_generator = self.string_generator
|
72
|
+
string_multiplier = self.string_multiplier
|
73
|
+
|
74
|
+
Class.new(described_class) do
|
75
|
+
use string_generator
|
76
|
+
use string_multiplier, separator: ' - ', multiplicator: 3
|
77
|
+
end.new
|
78
|
+
end
|
79
|
+
|
80
|
+
it { should succeed_to_perform.and_return('chunky bacon - chunky bacon - chunky bacon') }
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when composed of two operations using the factory method '.compose'" do
|
54
85
|
|
55
86
|
subject(:composed_operation) do
|
56
87
|
described_class.compose(string_generator, string_capitalizer).new
|
@@ -101,35 +132,4 @@ describe ComposableOperations::ComposedOperation do
|
|
101
132
|
it { should utilize_operations(string_generator, halting_operation, string_capitalizer) }
|
102
133
|
end
|
103
134
|
|
104
|
-
context "when composed of two operations and provided with a between block" do
|
105
|
-
|
106
|
-
|
107
|
-
let(:logger) { stub("Logger").as_null_object }
|
108
|
-
|
109
|
-
subject(:composed_operation) do
|
110
|
-
string_generator = string_generator()
|
111
|
-
string_capitalizer = string_capitalizer()
|
112
|
-
logger = logger()
|
113
|
-
|
114
|
-
operation = described_class.compose do
|
115
|
-
use string_generator
|
116
|
-
use string_capitalizer
|
117
|
-
|
118
|
-
between do |a, b, payload|
|
119
|
-
logger.info("#{a.name} -> #{b.name} with #{payload.inspect} as payload")
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
operation.new
|
124
|
-
end
|
125
|
-
|
126
|
-
it { should succeed_to_perform.and_return("CHUNKY BACON") }
|
127
|
-
|
128
|
-
it "should generate the correct log message" do
|
129
|
-
logger.should_receive(:info).with("StringGenerator -> StringCapitalizer with \"chunky bacon\" as payload")
|
130
|
-
composed_operation.perform
|
131
|
-
end
|
132
|
-
|
133
|
-
end
|
134
|
-
|
135
135
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: composable_operations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Tennhard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: smart_properties
|