composable_operations 0.9.2 → 0.10.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: 237f6bf42a1d019c2f0de93dd8baa18c187fa276
4
- data.tar.gz: 1c8648513871178ab2d34127fa29b1799adbee28
3
+ metadata.gz: 16bacd4b97dcd28f11356d7a01dbc3957487b5a9
4
+ data.tar.gz: f622ff84700dccf7ed5fc89d99907706b124e0b5
5
5
  SHA512:
6
- metadata.gz: 1f241f35e8737eb4b1aa2a585921ec97d44ccaf62210d7eb9b166e74933cbfb8a9d147c6aee31d36bcf13fca4acf8475ed3bdcb3bde30aa9115bab8c91e645fd
7
- data.tar.gz: 483847be976d67e1afdcd24dd5a5cf28237a1598e4b1419de1ccb48dd623a318b1ec137b68688172d77c4ff6c17056c92dce1413a678bbf631258adb08270fdd
6
+ metadata.gz: 4a2bf743f4f0f86f5ab3f0c8265c68feedf626dbf76cf00c860184ae81e37dd4635a324adf46c9c4f0b7c90af675863ada47bcb0d12f732d4d47180e9683be57
7
+ data.tar.gz: 13dd02a2bdd146fab5bc27a265cf24a5180087303981c89b2aa23d89076a7fab70687be56971a6a63f6d8d78727267bb833b5080ec432776bed055963110eba7
@@ -19,7 +19,7 @@ multiple of these operations in operation pipelines.}
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_dependency "smart_properties", "~> 1.0"
22
+ spec.add_dependency "smart_properties", "~> 1.10"
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.3"
25
25
  spec.add_development_dependency "pry", "~> 0.9.0"
@@ -8,8 +8,9 @@ module ComposableOperations
8
8
  @_options = options
9
9
  end
10
10
 
11
- def create(context, *input)
12
- new *input, Hash[Array(@_options).map do |key, value|
11
+ def new(context, *input)
12
+ input = input.shift(arity)
13
+ __getobj__.new *input, Hash[Array(@_options).map do |key, value|
13
14
  [key, value.kind_of?(Proc) ? context.instance_exec(&value) : value]
14
15
  end]
15
16
  end
@@ -23,6 +24,11 @@ module ComposableOperations
23
24
  end
24
25
 
25
26
  def use(operation, options = {})
27
+ if operations.empty?
28
+ arguments = operation.arguments
29
+ processes(*arguments) unless arguments.empty?
30
+ end
31
+
26
32
  (@operations ||= []) << OperationFactory.new(operation, options)
27
33
  end
28
34
 
@@ -47,9 +53,9 @@ module ComposableOperations
47
53
  def execute
48
54
  self.class.operations.inject(input) do |data, operation|
49
55
  operation = if data.respond_to?(:to_ary)
50
- operation.create(self, *data)
56
+ operation.new(self, *data)
51
57
  else
52
- operation.create(self, data)
58
+ operation.new(self, data)
53
59
  end
54
60
  operation.perform
55
61
 
@@ -4,11 +4,14 @@ module ComposableOperations
4
4
  include SmartProperties
5
5
 
6
6
  class << self
7
+ attr_writer :arguments
7
8
 
8
- attr_writer :arity
9
+ def arguments
10
+ @arguments ||= []
11
+ end
9
12
 
10
13
  def arity
11
- @arity || 0
14
+ arguments.count
12
15
  end
13
16
 
14
17
  def perform(*args)
@@ -57,15 +60,13 @@ module ComposableOperations
57
60
  end
58
61
 
59
62
  def processes(*names)
60
- self.arity = names.length
61
-
62
63
  case names.length
63
64
  when 0
64
65
  raise ArgumentError, "#{self}.#{__callee__} expects at least one argument"
65
66
  else
66
67
  names.each_with_index do |name, index|
67
- define_method(name) { input[index] }
68
- define_method("#{name}=") { |value| input[index] = value }
68
+ property(name, required: true) unless properties.key?(name)
69
+ arguments << name
69
70
  end
70
71
  end
71
72
  end
@@ -90,12 +91,21 @@ module ComposableOperations
90
91
  attr_reader :exception
91
92
 
92
93
  def initialize(*args)
93
- named_input_parameters = args.shift(self.class.arity)
94
- options = args.last.kind_of?(Hash) ? args.pop : {}
95
- unnamed_input_parameters = args
94
+ arity = self.class.arity
95
+ arguments = args.shift(arity)
96
+ attributes = args.last.kind_of?(Hash) ? args.pop : {}
97
+
98
+ raise ArgumentError, "wrong number of arguments #{arguments.length + args.length} for #{arity}" unless args.empty?
99
+
100
+ self.class.arguments.each_with_index do |name, index|
101
+ attributes[name] = arguments[index]
102
+ end
103
+
104
+ super(attributes)
105
+ end
96
106
 
97
- @input = named_input_parameters + unnamed_input_parameters
98
- super(options)
107
+ def input
108
+ self.class.arguments.map { |name| self[name] }
99
109
  end
100
110
 
101
111
  def failed?
@@ -1,3 +1,3 @@
1
1
  module ComposableOperations
2
- VERSION = "0.9.2"
2
+ VERSION = "0.10.0"
3
3
  end
@@ -29,6 +29,7 @@ describe ComposableOperations::ComposedOperation do
29
29
 
30
30
  let(:string_multiplier) do
31
31
  Class.new(ComposableOperations::Operation) do
32
+ processes :text
32
33
  property :multiplicator, default: 1, converts: :to_i, required: true
33
34
  property :separator, default: ' ', converts: :to_s, required: true
34
35
 
@@ -37,20 +38,24 @@ describe ComposableOperations::ComposedOperation do
37
38
  end
38
39
 
39
40
  def execute
40
- (Array(input) * multiplicator).join(separator)
41
+ (Array(text) * multiplicator).join(separator)
41
42
  end
42
43
  end
43
44
  end
44
45
 
45
46
  let(:halting_operation) do
46
47
  Class.new(ComposableOperations::Operation) do
48
+ def self.name
49
+ "HaltingOperation"
50
+ end
51
+
47
52
  def execute
48
53
  halt
49
54
  end
50
55
  end
51
56
  end
52
57
 
53
- context "when composed of one operation that generates a string no matter the input" do
58
+ context "when composed of one operation that generates" do
54
59
  subject(:composed_operation) do
55
60
  operation = string_generator
56
61
 
@@ -60,7 +65,7 @@ describe ComposableOperations::ComposedOperation do
60
65
  end
61
66
 
62
67
  it "should return this string as result" do
63
- expect(composed_operation.perform(nil)).to eq("chunky bacon")
68
+ expect(composed_operation.perform).to eq("chunky bacon")
64
69
  end
65
70
  end
66
71
 
@@ -100,7 +105,7 @@ describe ComposableOperations::ComposedOperation do
100
105
  end
101
106
 
102
107
  it "should return a capitalized version of the generated string" do
103
- expect(composed_operation.perform(nil)).to eq("CHUNKY BACON")
108
+ expect(composed_operation.perform).to eq("CHUNKY BACON")
104
109
  end
105
110
 
106
111
  it { is_expected.to utilize_operations(string_generator, string_capitalizer) }
@@ -123,5 +128,30 @@ describe ComposableOperations::ComposedOperation do
123
128
  end
124
129
  it { is_expected.to utilize_operations(string_generator, halting_operation, string_capitalizer) }
125
130
  end
131
+
132
+ context "when composed of two operations; one that that capitalizes a string and one that repeats the string" do
133
+ subject(:composed_operation) do
134
+ operations = [string_capitalizer, string_multiplier]
135
+
136
+ Class.new(described_class) do
137
+ use operations.first
138
+ use operations.last, multiplicator: 2
139
+ end
140
+ end
141
+
142
+ it "should raise when instantiated with no input" do
143
+ expect { composed_operation.new }.to raise_error(ArgumentError)
144
+ end
145
+
146
+ it "should not raise when instantiated with a string" do
147
+ expect { composed_operation.new("some string") }.to_not raise_error
148
+ end
149
+
150
+ it "should have an input argument with the same name as the first operation" do
151
+ expect(composed_operation.arguments).to eq(string_capitalizer.arguments)
152
+ end
153
+
154
+ it { is_expected.to succeed_to_perform.when_initialized_with("hello").and_return("HELLO HELLO") }
155
+ end
126
156
  end
127
157
 
@@ -16,19 +16,6 @@ describe ComposableOperations::Operation, "input processing:" do
16
16
  it { is_expected.to succeed_to_perform.when_initialized_with(input).and_return(input) }
17
17
  end
18
18
 
19
- describe "An operation that takes no arguments except for a Hash of additional options" do
20
- subject(:operation) do
21
- Class.new(described_class) do
22
- def execute
23
- input
24
- end
25
- end
26
- end
27
-
28
- it { is_expected.to succeed_to_perform.when_initialized_with(key: :value).and_return([]) }
29
- it { is_expected.to succeed_to_perform.when_initialized_with(1, 2, 3, key: :value).and_return([1, 2, 3]) }
30
- end
31
-
32
19
  describe "An operation that takes a Hash as input and an Hash of additional options" do
33
20
  let(:input) { { food: nil } }
34
21
 
@@ -71,7 +58,6 @@ describe ComposableOperations::Operation, "input processing:" do
71
58
  end
72
59
 
73
60
  it { is_expected.to succeed_to_perform.when_initialized_with(1, 2).and_return([1, 2]) }
74
- it { is_expected.to succeed_to_perform.when_initialized_with(1, 2, 3).and_return([1, 2, 3]) }
75
61
  end
76
62
 
77
63
  describe "An operation that takes multiple arguments as input where the last of these arguments is a Hash" do
@@ -89,31 +75,33 @@ describe ComposableOperations::Operation, "input processing:" do
89
75
  it { is_expected.to succeed_to_perform.when_initialized_with(1, 2, operator: :*).and_return(2) }
90
76
  end
91
77
 
92
- describe "An operation that takes multiple arguments as input where the last of these arguments is a Hash, as well as, a Hash of additional options" do
78
+ describe "An operation that takes a named argument and uses the setter for the named argument" do
93
79
  subject(:operation) do
94
80
  Class.new(described_class) do
95
- processes :some_value, :yet_another_value, :a_hash
81
+ processes :some_value
96
82
  def execute
97
- a_hash
83
+ self.some_value = "changed"
84
+ self.some_value
98
85
  end
99
86
  end
100
87
  end
101
88
 
102
- it { is_expected.to succeed_to_perform.when_initialized_with(1, 2, {food: "chunky bacon"}, { additional: :options }).and_return(food: "chunky bacon") }
89
+ it { is_expected.to succeed_to_perform.when_initialized_with("unchanged").and_return("changed") }
103
90
  end
104
91
 
105
- describe "An operation that takes a named argument and uses the setter for the named argument" do
92
+ describe "An operation that manually defines a property for its first input argument that upcases its assgined value" do
106
93
  subject(:operation) do
107
94
  Class.new(described_class) do
108
- processes :some_value
95
+ property :text, converts: :upcase
96
+ processes :text
97
+
109
98
  def execute
110
- self.some_value = "changed"
111
- self.some_value
99
+ text
112
100
  end
113
101
  end
114
102
  end
115
103
 
116
- it { is_expected.to succeed_to_perform.when_initialized_with("unchanged").and_return("changed") }
104
+ it { is_expected.to succeed_to_perform.when_initialized_with("hello").and_return("HELLO") }
117
105
  end
118
106
  end
119
107
 
@@ -2,28 +2,30 @@ require 'spec_helper'
2
2
 
3
3
  describe ComposableOperations::Operation do
4
4
  context "that always returns nil when executed" do
5
- subject(:nil_operation) do
6
- class << (operation = described_class.new(''))
5
+ let(:nil_operation) do
6
+ Class.new(described_class) do
7
7
  def execute
8
8
  nil
9
9
  end
10
10
  end
11
- operation
12
11
  end
13
12
 
13
+ subject { nil_operation.new }
14
+
14
15
  it { is_expected.to succeed_to_perform.and_return(nil) }
15
16
  end
16
17
 
17
18
  context "that always halts and returns its original input" do
18
19
  let(:halting_operation) do
19
20
  Class.new(described_class) do
21
+ processes :message
20
22
  def execute
21
23
  halt "Full stop!", input.first
22
24
  end
23
25
  end
24
26
  end
25
27
 
26
- let(:halting_operation_instance) do
28
+ subject(:halting_operation_instance) do
27
29
  halting_operation.new("Test")
28
30
  end
29
31
 
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.9.2
4
+ version: 0.10.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: 2014-07-15 00:00:00.000000000 Z
11
+ date: 2015-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: smart_properties
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '1.10'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '1.10'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -131,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
131
  version: '0'
132
132
  requirements: []
133
133
  rubyforge_project:
134
- rubygems_version: 2.2.2
134
+ rubygems_version: 2.4.5
135
135
  signing_key:
136
136
  specification_version: 4
137
137
  summary: Tool set for operation pipelines.
@@ -143,3 +143,4 @@ test_files:
143
143
  - spec/composable_operations/operation_input_processing_spec.rb
144
144
  - spec/composable_operations/operation_spec.rb
145
145
  - spec/spec_helper.rb
146
+ has_rdoc: