composable_operations 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6eeabae9917ce517a8f6ba380b3485479edde5a
4
- data.tar.gz: 94ab6cddddbea6be52e2e426a9cc56088bd4b5ac
3
+ metadata.gz: 35bf16a747c65f1dcd6f9e7003f6fb574d86b4b5
4
+ data.tar.gz: d456bb506cef1eb336fbf82d3d80718d28e0c648
5
5
  SHA512:
6
- metadata.gz: bb094f4b9cd7c25d96cb1ebdc27727c0e23d9dd86ad6c386aa1b40107bad8060cc8635a27d4a01bbb91cad34b1cb3644a6eed92ed88ba27c0df456f8671afb73
7
- data.tar.gz: 62f381ac83ebdf643a5e04d1e1d61b60cd1e578fa6202e386fe88db20972d187223a606ba67fd9b091a02a434a78baaf0a1b0230425114b18e65bad46e3686b6
6
+ metadata.gz: caaec98652d28e2f1af2856a93adef45536ce173ff04e632362e5d97e64c22c7d415bc6a2206da36889675d3435e30222fd96bf7be3cc003e300d03c6a262609
7
+ data.tar.gz: 84498a024f0c4564ef33dd276566090d0898d8fadc10e8a4eff7680e70721140943ba5d1c19dc365e8682d87d8010c513979856d1cc378af7eba983c39c879f7
@@ -1,4 +1,5 @@
1
1
  require 'smart_properties'
2
+ require 'delegate'
2
3
 
3
4
  module ComposableOperations
4
5
  # Your code goes here...
@@ -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
- [nil, *operations, nil].each_cons(2).inject(input) do |data, operations|
55
- if operation = operations.last
56
- operation = operation.new(data)
57
- operation.perform
58
-
59
- if operation.failed?
60
- fail operation.message, operation.result, operation.backtrace
61
- elsif operation.halted?
62
- halt operation.message, operation.result
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
- def transition(a, b, payload)
74
- self.class.transitions.each { |transition| instance_exec(a, b, payload, &transition) }
62
+ operation.result
63
+ end
75
64
  end
76
65
 
77
66
  end
@@ -1,3 +1,3 @@
1
1
  module ComposableOperations
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  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 using the factory method '#chain'" do
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.2.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-12 00:00:00.000000000 Z
11
+ date: 2013-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: smart_properties