lev 1.0.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lev (1.0.1)
4
+ lev (2.0.1)
5
5
  actionpack (>= 3.0)
6
6
  active_attr
7
7
  activemodel (>= 3.0)
8
8
  activerecord (>= 3.0)
9
+ hashie
9
10
  transaction_isolation
10
11
  transaction_retry
11
12
 
@@ -48,6 +49,7 @@ GEM
48
49
  debugger-ruby_core_source (1.2.3)
49
50
  diff-lcs (1.2.4)
50
51
  erubis (2.7.0)
52
+ hashie (2.0.5)
51
53
  i18n (0.6.5)
52
54
  minitest (4.7.5)
53
55
  multi_json (1.8.0)
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_runtime_dependency "transaction_isolation"
25
25
  spec.add_runtime_dependency "transaction_retry"
26
26
  spec.add_runtime_dependency "active_attr"
27
+ spec.add_runtime_dependency "hashie"
27
28
 
28
29
  spec.add_development_dependency "bundler", "~> 1.3"
29
30
  spec.add_development_dependency "rake"
data/lib/lev.rb CHANGED
@@ -2,12 +2,15 @@ require "action_view"
2
2
  require "transaction_isolation"
3
3
  require "transaction_retry"
4
4
  require "active_attr"
5
+ require "hashie"
5
6
 
6
7
  require "lev/version"
8
+ require "lev/object"
7
9
  require "lev/utilities"
8
10
  require "lev/exceptions"
9
11
  require "lev/better_active_model_errors"
10
12
  require "lev/term_mapper"
13
+ require "lev/outputs"
11
14
  require "lev/routine"
12
15
  require "lev/handler"
13
16
  require "lev/handle_with"
@@ -13,7 +13,7 @@ module Lev
13
13
  # doing something with it. See Lev::Routine for more information.
14
14
  #
15
15
  # All handlers must:
16
- # 2) include this module ("include Lev::Handler")
16
+ # 2) call "lev_handler"
17
17
  # 3) implement the 'handle' method which takes no arguments and does the
18
18
  # work the handler is charged with
19
19
  # 4) implement the 'authorized?' method which returns true iff the
@@ -32,7 +32,7 @@ module Lev
32
32
  # the Handler class would look like:
33
33
  #
34
34
  # class MyHandler
35
- # include Lev::Handler
35
+ # lev_handler
36
36
  #
37
37
  # paramify :search do
38
38
  # attribute :search_type, type: String
@@ -88,7 +88,7 @@ module Lev
88
88
  # Example:
89
89
  #
90
90
  # class MyHandler
91
- # include Lev::Handler
91
+ # lev_handler
92
92
  # protected
93
93
  # def authorized?
94
94
  # # return true iff exec is allowed to be called, e.g. might
@@ -0,0 +1,25 @@
1
+ class Object
2
+
3
+ def self.lev_routine(options={})
4
+ class_eval do
5
+ include Lev::Routine unless options[:skip_routine_include]
6
+
7
+ # Routine configuration
8
+ options[:transaction] ||= Lev::TransactionIsolation.mysql_default.symbol
9
+ @transaction_isolation = Lev::TransactionIsolation.new(options[:transaction])
10
+ end
11
+ end
12
+
13
+ def self.lev_handler(options={})
14
+ class_eval do
15
+ include Lev::Handler
16
+ end
17
+
18
+ # Do routine configuration
19
+ options[:skip_routine_include] = true
20
+ lev_routine(options)
21
+
22
+ # Do handler configuration (none currently)
23
+ end
24
+
25
+ end
@@ -0,0 +1,39 @@
1
+ module Lev
2
+ class Outputs < Hashie::Mash
3
+
4
+ def initialize(source_hash = nil, default = nil, &blk)
5
+ @array_created = {}
6
+ super(source_hash, default, &blk)
7
+ end
8
+
9
+ def add(name, value)
10
+ if self[name].nil?
11
+ self[name] = value
12
+ elsif @array_created[name]
13
+ self[name].push value
14
+ else
15
+ @array_created[name] = true
16
+ self[name] = [self[name], value]
17
+ end
18
+ end
19
+
20
+ def each
21
+ self.each_key do |key|
22
+ key = key.to_sym
23
+ if @array_created[key]
24
+ self[key].each { |value| yield key, value }
25
+ else
26
+ yield key, self[key]
27
+ end
28
+ end
29
+ end
30
+
31
+ def transfer_to(other_outputs, &name_mapping_block)
32
+ self.each do |name, value|
33
+ new_name = block_given? ? name_mapping_block.call(name) : name
34
+ other_outputs.add(new_name, value)
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -18,7 +18,7 @@ module Lev
18
18
  #
19
19
  # A class becomes a routine by adding:
20
20
  #
21
- # include Lev::Routine
21
+ # lev_routine
22
22
  #
23
23
  # in its definition.
24
24
  #
@@ -36,9 +36,19 @@ module Lev
36
36
  # routines aren't typically instantiated with state).
37
37
  #
38
38
  # A routine is automatically run within a transaction. The isolation level
39
- # of the routine can be set by overriding the "default_transaction_isolation"
40
- # class method and having it return an instance of Lev::TransactionIsolation.
41
- # This is also how routines can be set to not be run in a transaction.
39
+ # of the routine can be set by passing a :transaction option to the lev_routine
40
+ # call (or to the lev_handler call, if appropriate). The value must be one of
41
+ #
42
+ # :no_transaction
43
+ # :read_uncommitted
44
+ # :read_committed
45
+ # :repeatable_read
46
+ # :serializable
47
+ #
48
+ # e.g.
49
+ #
50
+ # class MyRoutine
51
+ # lev_routine transaction: :no_transaction
42
52
  #
43
53
  # As mentioned above, routines can call other routines. While this is of
44
54
  # course possible just by calling the other routine's call method directly,
@@ -91,7 +101,7 @@ module Lev
91
101
  # context. E.g., in the following class:
92
102
  #
93
103
  # class Routine1
94
- # include Lev::Routine
104
+ # lev_routine
95
105
  # uses_routine Routine2,
96
106
  # translations: {
97
107
  # inputs: { map: {bar: :foo} }
@@ -176,14 +186,9 @@ module Lev
176
186
  attr_reader :errors
177
187
 
178
188
  def initialize
179
- @outputs = {}
189
+ @outputs = Outputs.new
180
190
  @errors = Errors.new
181
191
  end
182
-
183
- def add_output(name, value)
184
- outputs[name] = [outputs[name], value].flatten.compact
185
- outputs[name] = outputs[name].first if outputs[name].size == 1
186
- end
187
192
  end
188
193
 
189
194
  def self.included(base)
@@ -213,11 +218,7 @@ module Lev
213
218
  end
214
219
 
215
220
  def transaction_isolation
216
- @transaction_isolation ||= default_transaction_isolation
217
- end
218
-
219
- def default_transaction_isolation
220
- TransactionIsolation.mysql_default
221
+ @transaction_isolation ||= TransactionIsolation.mysql_default
221
222
  end
222
223
 
223
224
  def nested_routines
@@ -323,8 +324,8 @@ module Lev
323
324
  options[:errors_are_fatal] = true if !options.has_key?(:errors_are_fatal)
324
325
  transfer_errors_from(run_result.errors, input_mapper, options[:errors_are_fatal])
325
326
 
326
- run_result.outputs.each do |name, value|
327
- self.result.add_output(output_mapper.map(name), value)
327
+ run_result.outputs.transfer_to(outputs) do |name|
328
+ output_mapper.map(name)
328
329
  end
329
330
 
330
331
  run_result
@@ -380,7 +381,7 @@ module Lev
380
381
  def runner=(runner)
381
382
  @runner = runner
382
383
 
383
- if topmost_runner.class.transaction_isolation.weaker_than(self.class.default_transaction_isolation)
384
+ if topmost_runner.class.transaction_isolation.weaker_than(self.class.transaction_isolation)
384
385
  raise IsolationMismatch,
385
386
  "The routine being run has a stronger isolation requirement than " +
386
387
  "the isolation being used by the routine(s) running it; call the " +
@@ -1,3 +1,3 @@
1
1
  module Lev
2
- VERSION = "1.0.1"
2
+ VERSION = "2.0.1"
3
3
  end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lev::Outputs do
4
+
5
+ let(:outputs) { Lev::Outputs.new }
6
+
7
+ it "should return a non-array when given just one non-array" do
8
+ outputs.add(:x, 4)
9
+ expect(outputs[:x]).to eq 4
10
+ end
11
+
12
+ it "should return an array when given just one array" do
13
+ outputs.add(:x, [1,2])
14
+ expect(outputs[:x]).to eq [1,2]
15
+ end
16
+
17
+ it "should work when given a non-array and an array" do
18
+ outputs.add(:x, 4)
19
+ outputs.add(:x, [1,2])
20
+ expect(outputs[:x]).to eq [4, [1,2]]
21
+ end
22
+
23
+ it "should work when given two or three non-arrays" do
24
+ outputs.add(:x, 1)
25
+ outputs.add(:x, 2)
26
+ expect(outputs.x).to eq [1,2]
27
+ outputs.add(:x, 3)
28
+ expect(outputs.x).to eq [1,2,3]
29
+ end
30
+
31
+ it "should work when given a mix" do
32
+ outputs.add(:x, [3,4])
33
+ outputs.add(:x, "hi")
34
+ outputs.add(:x, {a: 2})
35
+ expect(outputs.x).to eq [[3,4], "hi", {a: 2}]
36
+ end
37
+
38
+ it "should transfer well" do
39
+ outputs.add(:x, 4)
40
+ outputs.add(:x, 5)
41
+
42
+ other_outputs = Lev::Outputs.new
43
+
44
+ outputs.each do |name, value|
45
+ other_outputs.add(name, value)
46
+ end
47
+
48
+ other_outputs.add(:x, 6)
49
+
50
+ expect(other_outputs.x).to eq [4,5,6]
51
+ end
52
+
53
+ it "should work via transfer_to with name mapping" do
54
+ outputs.add(:x, 4)
55
+ outputs.add(:x, 5)
56
+
57
+ other_outputs = Lev::Outputs.new
58
+
59
+ outputs.transfer_to(other_outputs) do |name|
60
+ :y
61
+ end
62
+
63
+ other_outputs.add(:y, 6)
64
+ expect(other_outputs.y).to eq [4,5,6]
65
+ end
66
+
67
+ it "should work via transfer_to without name mapping" do
68
+ outputs.add(:x, 4)
69
+ outputs.add(:x, 5)
70
+
71
+ other_outputs = Lev::Outputs.new
72
+
73
+ outputs.transfer_to(other_outputs)
74
+
75
+ other_outputs.add(:y, 6)
76
+ expect(other_outputs.x).to eq [4,5]
77
+ expect(other_outputs.y).to eq 6
78
+ end
79
+
80
+ end
@@ -1,6 +1,6 @@
1
1
  class CreateSprocket
2
2
 
3
- include Lev::Routine
3
+ lev_routine
4
4
 
5
5
  protected
6
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lev
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -107,6 +107,22 @@ dependencies:
107
107
  - - ! '>='
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: hashie
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
110
126
  - !ruby/object:Gem::Dependency
111
127
  name: bundler
112
128
  requirement: !ruby/object:Gem::Requirement
@@ -200,6 +216,8 @@ files:
200
216
  - lib/lev/handle_with.rb
201
217
  - lib/lev/handler.rb
202
218
  - lib/lev/handler_helper.rb
219
+ - lib/lev/object.rb
220
+ - lib/lev/outputs.rb
203
221
  - lib/lev/routine.rb
204
222
  - lib/lev/term_mapper.rb
205
223
  - lib/lev/transaction_isolation.rb
@@ -207,6 +225,7 @@ files:
207
225
  - lib/lev/version.rb
208
226
  - spec/create_sprocket_spec.rb
209
227
  - spec/deep_merge_spec.rb
228
+ - spec/outputs_spec.rb
210
229
  - spec/routine_spec.rb
211
230
  - spec/spec_helper.rb
212
231
  - spec/sprocket_spec.rb
@@ -227,7 +246,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
227
246
  version: '0'
228
247
  segments:
229
248
  - 0
230
- hash: 1251683534568030962
249
+ hash: 55854544372342664
231
250
  required_rubygems_version: !ruby/object:Gem::Requirement
232
251
  none: false
233
252
  requirements:
@@ -236,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
236
255
  version: '0'
237
256
  segments:
238
257
  - 0
239
- hash: 1251683534568030962
258
+ hash: 55854544372342664
240
259
  requirements: []
241
260
  rubyforge_project:
242
261
  rubygems_version: 1.8.25
@@ -246,6 +265,7 @@ summary: Ride the rails but don't touch them.
246
265
  test_files:
247
266
  - spec/create_sprocket_spec.rb
248
267
  - spec/deep_merge_spec.rb
268
+ - spec/outputs_spec.rb
249
269
  - spec/routine_spec.rb
250
270
  - spec/spec_helper.rb
251
271
  - spec/sprocket_spec.rb