usine 1.0.0 → 1.1.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: fbc2a69385641d964ee71c8d4aec4dca3237fbea
4
- data.tar.gz: 50b1d8c0d0eb7d9f122bc3abf59dbb35da29b7cc
3
+ metadata.gz: 989d0ef56df43856ceb3ceee137fdaf56c5d722a
4
+ data.tar.gz: 79dc66c1c26e026fb6bbfa87955a394582042701
5
5
  SHA512:
6
- metadata.gz: 898bc72b754b1eca6709814eef4424e5d199273d8ba4a88fd38a7f16a59faf11dc04a9a02949c7fa336d0ac46277290f6bb4e5009ba2f90babaa200081a253f9
7
- data.tar.gz: 211d45fe40c5457f3313e9802413e2d478c69541c423b16b4a0bc09528b25e0f0fd292602f21091f2dd9db22a2ec2b558aca11e0a9d6afa9b3b8bae2e76f0c37
6
+ metadata.gz: 2b3cc1296fc2abf5c986101c85742ba18baafc109a55f0700d5d9c6c9361e312701cc2c0488935f8abafd46b1cba1f00cdc04d495e2273e704133ce4ea9dd0cd
7
+ data.tar.gz: c12b2dfda625558ead73b5cfc1581ae9791ca210b549e569769b4ed93e56c6b515793502f2b837b0e8f281fe7d432e0d29413f10a17d099ec88886d300a82cbb
data/README.md CHANGED
@@ -23,63 +23,69 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
- ### Create definitions to be used by factories
26
+ ### Definitions
27
+
28
+ Definitions are the base of anything in Usine, they are used in factories to generate
29
+ the hash of params sent to the operation.
27
30
 
28
31
  ```ruby
29
- Usine.definition(Item::Create) do
32
+ Usine.definition(:item) do
30
33
  title { "Some title" }
31
34
  end
35
+
36
+ Usine.definition(:user) do
37
+ email { "j.jaffeux@example.com" }
38
+ end
32
39
  ```
33
40
 
34
- Definition accept unlimited args after the operation class, to allow you to share
35
- definitions.
41
+ ### Factories
36
42
 
37
- ```ruby
38
- SendableDefinition = proc {
39
- sendable { false }
40
- }
43
+ Factories let you build a hash which will be sent to an operation when you need it.
44
+ This is what you will call when building your objects in a test.
41
45
 
42
- Usine.definition(Item::Create, SendableDefinition) do
43
- title { "Some title" }
44
- end
45
-
46
- Usine.definition(Item::Update, SendableDefinition) do
47
- title { "Some title" }
46
+ ```ruby
47
+ Usine.factory(Item::Create) do
48
+ item # if not block given, it will invoke use(:item), which means it will use the :item Definition
49
+ current_user use(:user)
48
50
  end
49
51
  ```
50
52
 
51
- ### Using factories
53
+ ### Invoking factories
52
54
 
53
55
  Usine respects Trailblazer naming differences when creating an operation : call, run and present.
56
+ Which means you have 3 different ways to invoke a factory :
54
57
 
55
58
  ```ruby
56
- Usine.(Item::Create, title: "different title")
57
- Usine.call(Item::Create, title: "different title")
58
- Usine.run(Item::Create, title: "different title")
59
- Usine.present(Item::Create, title: "different title")
59
+ Usine.(Item::Create, item: {title: "different title"})
60
+ Usine.run(Item::Create, item: {title: "different title"})
61
+ Usine.present(Item::Create, item: {title: "different title"})
60
62
  ```
61
63
 
62
64
  `present` for example can be used to access model/contract without calling process in the operation.
63
65
 
66
+ Let see an example in a test :
67
+ ```
68
+ let(:user_id) {
69
+ Usine.(User::Create).model.id
70
+ }
71
+ ```
72
+
64
73
  ### Sequences
65
74
 
75
+ Sequences are used in Definitions to help you create different occurences of the same kind of attribute.
76
+
66
77
  ```ruby
67
78
  # global sequence
68
79
  Usine.sequence(:title) do |n|
69
80
  "title number #{n}"
70
81
  end
71
82
 
72
- # if no block is passed to the attribute, it will call generate(:attribute_name)
73
- Usine.definition(Item::Create) do
74
- title #title number 1
75
- subtitle { generate(:title) } #title number 2
76
- end
77
-
78
- # inline sequence with different initial value
79
- Usine.definition(Item::Create) do
80
- sequence(:title, 'a')
81
- title #title number a
82
- subtitle { generate(:title) } #title number b
83
+ # inline sequence in a definition
84
+ Usine.definition(:user) do
85
+ sequence(:email) { |n| "joffrey_#{n}@example.com" }
86
+ email # if no block given, Usine will try to invoke generate(:email)
87
+ title # and will also search in global sequences
88
+ alt_email { generate(:email) }
83
89
  end
84
90
  ```
85
91
 
@@ -1,10 +1,10 @@
1
1
  module Usine
2
- class Evaluator
2
+ class DefinitionEvaluator
3
3
  attr_reader :attributes
4
4
  attr_reader :sequences
5
5
  attr_reader :scoped_sequences
6
6
 
7
- def initialize(sequences = {})
7
+ def initialize(sequences = [])
8
8
  @sequences = sequences
9
9
  @scoped_sequences = []
10
10
  @attributes = {}
@@ -24,7 +24,11 @@ module Usine
24
24
  elsif sequence = sequences.detect { |x| x.attribute == attribute }
25
25
  sequence.next
26
26
  else
27
- raise(UsineError::SequenceNotFound, "Couldn’t find a sequence named : `#{attribute}`")
27
+ message = <<-MSG
28
+ Couldn’t find a sequence named: #{attribute}
29
+ Available sequences: #{scoped_sequences.concat(sequences).map(&:attribute).join(',')}
30
+ MSG
31
+ raise(UsineError::SequenceNotFound, message)
28
32
  end
29
33
  end
30
34
 
data/lib/usine/factory.rb CHANGED
@@ -1,55 +1,13 @@
1
1
  module Usine
2
2
  class Factory
3
- attr_reader :mode
4
3
  attr_reader :operation
5
4
  attr_reader :attributes
6
- attr_accessor :definition
5
+ attr_reader :block
7
6
 
8
- def self.call(mode, operation, attributes = {})
9
- factory = new(mode, operation, attributes, definitions)
10
- factory.process!
11
- end
12
-
13
- def initialize(mode, operation, attributes = {})
14
- @mode = mode
7
+ def initialize(operation, attributes = {}, &block)
15
8
  @operation = operation
16
- @definitions = attributes.delete(:definitions) || Usine.definitions.fetch(operation, [])
17
- @sequences = attributes.delete(:sequences) || Usine.sequences
18
- @attributes = attributes || {}
19
- end
20
-
21
- def process!
22
- @operation.send(@mode, merged_attributes)
23
- end
24
-
25
- def merged_attributes
26
- evaluated_factory.attributes.merge(@attributes)
27
- end
28
-
29
- def evaluated_factory
30
- @evaluated_factory ||= evaluate_with_definitions(@sequences)
31
- end
32
-
33
- protected
34
-
35
- def filtered_definitions
36
- filtered = @definitions.select do |definition|
37
- definition.name == @operation
38
- end
39
-
40
- if filtered.empty?
41
- raise UsineError::DefinitionNotFound, "No definition found for `#{@operation}`"
42
- end
43
-
44
- filtered
45
- end
46
-
47
- def evaluate_with_definitions(sequences)
48
- evaluator = Evaluator.new(sequences)
49
- filtered_definitions.each do |definition|
50
- evaluator.instance_eval(&definition.block)
51
- end
52
- evaluator
9
+ @attributes = attributes
10
+ @block = block
53
11
  end
54
12
  end
55
13
  end
@@ -0,0 +1,73 @@
1
+ module Usine
2
+ class FactoryEvaluator
3
+ attr_reader :mode
4
+ attr_reader :attributes
5
+ attr_reader :generated_attributes
6
+ attr_reader :factory
7
+
8
+ def self.call(factory, mode, attributes = {})
9
+ factory = new(factory, mode, attributes)
10
+ factory.process!
11
+ end
12
+
13
+ def definitions=(definitions)
14
+ @definitions = definitions
15
+ end
16
+
17
+ def definitions
18
+ @definitions ||= Usine.definitions
19
+ end
20
+
21
+ def sequences=(sequences)
22
+ @sequences = sequences
23
+ end
24
+
25
+ def sequences
26
+ @sequences ||= Usine.sequences
27
+ end
28
+
29
+ def initialize(factory, mode, attributes = {})
30
+ @mode = mode
31
+ @factory = factory
32
+ @attributes = attributes
33
+ @generated_attributes = {}
34
+ end
35
+
36
+ def use(definition_name, *args)
37
+ definition = definitions.detect do |definition|
38
+ definition.name == definition_name
39
+ end
40
+
41
+ if definition.nil?
42
+ message = <<-MSG
43
+ Couldn’t find a definition named: #{definition_name}
44
+ Available definitions: #{definitions.map(&:name).join(',')}
45
+ MSG
46
+ raise(UsineError::DefinitionNotFound, message)
47
+ end
48
+
49
+ evaluated_definition = DefinitionEvaluator.new(sequences)
50
+ evaluated_definition.instance_eval(&definition.block)
51
+ evaluated_definition.attributes
52
+ end
53
+
54
+ def method_missing(method_symbol, *args, &block)
55
+ if block
56
+ @generated_attributes[method_symbol] = self.instance_eval(&block)
57
+ else
58
+ @generated_attributes[method_symbol] = use(method_symbol, *args)
59
+ end
60
+ end
61
+
62
+ def process!
63
+ self.instance_eval(&factory.block)
64
+ @factory.operation.send(@mode, merged_attributes)
65
+ end
66
+
67
+ protected
68
+
69
+ def merged_attributes
70
+ Utils.merge_hashes(@generated_attributes, @attributes)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,17 @@
1
+ module Usine
2
+ class Utils
3
+ def self.merge_hashes(a, b)
4
+ b.each_pair do |current_key, other_value|
5
+ this_value = a[current_key]
6
+
7
+ a[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
8
+ Usine::Utils.merge_hashes(this_value, other_value)
9
+ else
10
+ other_value
11
+ end
12
+ end
13
+
14
+ a
15
+ end
16
+ end
17
+ end
data/lib/usine/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Usine
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/usine.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require "usine/version"
2
+ require "usine/utils"
2
3
  require "usine/factory"
4
+ require "usine/factory_evaluator"
3
5
  require "usine/exceptions"
4
- require "usine/evaluator"
6
+ require "usine/definition_evaluator"
5
7
  require "usine/definition"
6
8
  require "usine/sequence"
7
9
  require "uber/inheritable_attr"
@@ -9,35 +11,58 @@ require "uber/inheritable_attr"
9
11
  module Usine
10
12
  extend Uber::InheritableAttr
11
13
  inheritable_attr :definitions
12
- self.definitions = {}
14
+ self.definitions = []
15
+ inheritable_attr :factories
16
+ self.factories = []
13
17
  inheritable_attr :sequences
14
18
  self.sequences = []
15
19
 
16
20
  class << self
17
- def call(*args)
18
- Factory.(:call, args.shift, args.shift)
19
- end
20
21
 
21
- def run(*args)
22
- Factory.(:run, args.shift, args.shift)
22
+ [:call, :run, :present].each do |mode|
23
+ define_method mode, ->(*args, &block) {
24
+ operation = args.shift
25
+ factory = find_factory_for_operation(operation)
26
+ FactoryEvaluator.call(factory, mode, args.shift)
27
+ }
23
28
  end
24
29
 
25
- def present(*args)
26
- Factory.(:present, args.shift, args.shift)
30
+ def factory(operation, *extensions, &block)
31
+ self.factories ||= []
32
+
33
+ self.factories << Factory.new(operation, *extensions, &block)
34
+
35
+ extensions.each do |extension|
36
+ self.factories << Factory.new(operation, *extension, &block)
37
+ end
27
38
  end
28
39
 
29
40
  def sequence(name, initial_value = 1, &block)
30
41
  self.sequences << Sequence.new(name, initial_value, &block)
31
42
  end
32
43
 
33
- def definition(operation, *extensions, &block)
34
- self.definitions[operation] ||= []
44
+ def definition(attribute, *extensions, &block)
45
+ self.definitions ||= []
35
46
 
36
- self.definitions[operation] << Definition.new(operation, &block)
47
+ self.definitions << Definition.new(attribute, &block)
37
48
 
38
49
  extensions.each do |extension|
39
- self.definitions[operation] << Definition.new(operation, &block)
50
+ self.definitions << Definition.new(attribute, &block)
51
+ end
52
+ end
53
+
54
+ protected
55
+
56
+ def find_factory_for_operation(operation)
57
+ factory = Usine.factories.detect do |f|
58
+ f.operation == operation
40
59
  end
60
+
61
+ if factory.nil?
62
+ raise "NOT FOUND FACTORY for #{operation}"
63
+ end
64
+
65
+ factory
41
66
  end
42
67
  end
43
68
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usine
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joffrey JAFFEUX
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-07-22 00:00:00.000000000 Z
11
+ date: 2016-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uber
@@ -99,10 +99,12 @@ files:
99
99
  - bin/setup
100
100
  - lib/usine.rb
101
101
  - lib/usine/definition.rb
102
- - lib/usine/evaluator.rb
102
+ - lib/usine/definition_evaluator.rb
103
103
  - lib/usine/exceptions.rb
104
104
  - lib/usine/factory.rb
105
+ - lib/usine/factory_evaluator.rb
105
106
  - lib/usine/sequence.rb
107
+ - lib/usine/utils.rb
106
108
  - lib/usine/version.rb
107
109
  - usine.gemspec
108
110
  homepage: https://github.com/jjaffeux/usine