usine 1.0.0 → 1.1.0

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