lev 1.0.1 → 2.0.1

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.
@@ -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