journeyman 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cc88ba880fcd67214a896dac32304a317037a538
4
+ data.tar.gz: 5e943948aea70eb2bcc2f4e58ce65671ef04a691
5
+ SHA512:
6
+ metadata.gz: 4d2deabc6944da9b531b69861d78a7867d74a0f05eb1b7f8dffe5620916fd7d64190a8d265715f5c0fd5b046a79b24130701de0c234680a45a9363b57dc0f786
7
+ data.tar.gz: 0ed0da538b523579bf98500ff50e70de99ea7b80384b60190d9810279b8acbb981c9c6122f499f662b12b54cadee4e65404a577013c23be86579f8fb2f7021f7
data/README.md ADDED
@@ -0,0 +1,189 @@
1
+ Journeyman [![Gem Version](https://badge.fury.io/rb/journeyman.svg)](http://badge.fury.io/rb/journeyman) [![Build Status](https://travis-ci.org/ElMassimo/journeyman.svg)](https://travis-ci.org/ElMassimo/journeyman) [![Test Coverage](https://codeclimate.com/repos/5372dce769568034ff0304c2/badges/e014d258ab0dbe3f668e/coverage.svg)](https://codeclimate.com/repos/5372dce769568034ff0304c2/feed) [![Code Climate](https://codeclimate.com/repos/5372dce769568034ff0304c2/badges/e014d258ab0dbe3f668e/gpa.png)](https://codeclimate.com/repos/5372dce769568034ff0304c2/feed) [![Inline docs](http://inch-ci.org/github/ElMassimo/journeyman.svg)](http://inch-ci.org/github/ElMassimo/journeyman) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ElMassimo/journeyman/blob/master/LICENSE.txt)
2
+ =====================
3
+
4
+ Journeyman is a fixtures replacement with an extremely light definition syntax,
5
+ providing two default build strategies, but allowing full customization on how
6
+ to build an object.
7
+
8
+ ## Usage
9
+ Journeyman is built to work out of the box with RSpec and Cucumber, and any
10
+ console environment, if you need support for other testing frameworks we can
11
+ work it out :smiley:.
12
+
13
+ Since it has no dependencies, it's possible to use it in any Ruby project.
14
+
15
+ ### Load
16
+ Journeyman will attempt to load files under the `spec/factories` directory, but
17
+ you may overwrite `Journeyman.factories_paths` by providing an Array that
18
+ containst different paths for factories.
19
+
20
+ ### Definition
21
+ Journeyman allows you to provide the default attributes for creation as the
22
+ return value of the definition block.
23
+
24
+ ```ruby
25
+ Journeyman.define :album do |c|
26
+ {
27
+ title: 'Wish You Were Here',
28
+ recorded_ago: -> { (Date.today - Date.new(1975, 9, 12)).round / 365 },
29
+ band: -> { Journeyman.create(:band, name: 'Pink Floyd') }
30
+ }
31
+ end
32
+ ```
33
+ The default values are superseded by the value you provide to `build` or `create`.
34
+
35
+ ```ruby
36
+ pink_floyd = find_band('Pink Floyd')
37
+
38
+ Journeyman.build(:album, band: pink_floyd) == Album.new({
39
+ title: 'Wish You Were Here',
40
+ recorded_ago: -> { ... }.call,
41
+ band: pink_floyd
42
+ })
43
+ ```
44
+ The default values can be static, or dynamic. If you specify a `Proc` or `lambda`
45
+ as a default value for an attribute, it will be evaluated whenever the attribute
46
+ is not provided when an object is built.
47
+
48
+ ### Configuration
49
+ Journeyman is a configurable beast, yet has really strong defaults.
50
+ ```ruby
51
+ # DSL Methods
52
+ find, process, ignore, build, after_create
53
+
54
+ # Configuration Options
55
+ [:parent, :model, :finder_attribute]
56
+ ```
57
+
58
+ #### DSL
59
+ Journeyman provides a nice DSL that lets you provide a block or lambda with your
60
+ own builder, or finder, and other miscellanous (and handy) hooks.
61
+
62
+ * `find:` Allows you to define the finder, takes a single argument.
63
+
64
+ * `build:` You can provide a custom builder, receives a Hash of attributes, but
65
+ you have full liberty of what you do with them, the return value must be the
66
+ built object.
67
+
68
+ * `process:` If you need to process the attributes before building you can
69
+ provide a block to do just that, make sure to return the attributes at the end.
70
+
71
+ * `ignore:` There are cases where you want to ignore certain attributes during
72
+ the `build`, but you want them in the `after_create` callback. You can ignore
73
+ those attributes by passing a list, or Array with the attributes you wish to
74
+ ignore.
75
+
76
+ * `after_create`: Callback that takes the newly built object, and the original
77
+ attributes. Specially useful when combined with ignore.
78
+
79
+ ```ruby
80
+ Journeyman.define :employee do
81
+ find { |id| Person.find(id) }
82
+
83
+ build { |attrs|
84
+ attrs.delete(:company).new_employee(attrs)
85
+ }
86
+
87
+ ignore :work_history
88
+
89
+ after_create { |employee, attrs|
90
+ attrs[:work_history].each do |history|
91
+ check_references(history)
92
+ end
93
+ }
94
+ end
95
+ ```
96
+
97
+ #### Configuration Options
98
+ Configuration options can be passed alongside the name in the factory definition:
99
+
100
+ * `parent:` Name of the factory that is going to be used as a parent, if `parent`
101
+ is set, the default builder consists of invoking the parent factory builder.
102
+
103
+ * `model:` Expects a class that will be used for the default builder and finder.
104
+ Useful for cases where the inferrence from the name does not work, or the factory
105
+ name is simply different than the object class it's building.
106
+
107
+ * `finder_attribute:` Name of the attribute used to find an object by the default
108
+ finder. The default is `:name`.
109
+
110
+ ```ruby
111
+ Journeyman.define :employee, model: People, finder_attribute: :social_security_id do
112
+ ...
113
+ end
114
+
115
+ Journeyman.define :journeyman, parent: :employee do
116
+ ...
117
+ end
118
+ ```
119
+
120
+ ## Setup
121
+ ```ruby
122
+ # Gemfile
123
+ group :test do
124
+ gem 'journeyman'
125
+ end
126
+
127
+ # Generic Use (mock script)
128
+ require 'journeyman'
129
+
130
+ Journeyman.load(self)
131
+ ````
132
+ ### RSpec
133
+ ```ruby
134
+ # spec/support/spec_helper.rb or similar
135
+ require 'journeyman'
136
+
137
+ Journeyman.load(self, framework: :rspec)
138
+ ````
139
+
140
+ ### Cucumber
141
+ ```ruby
142
+ # features/support/journeyman.rb or similar
143
+ require 'journeyman'
144
+
145
+ Journeyman.load(self, framework: :cucumber)
146
+ ````
147
+
148
+ ## Advantages
149
+
150
+ * You have full control of how your objects are created, *and* have to write
151
+ less boilerplate.
152
+ * You can chain several factories using parent, which allows you to create
153
+ different factories for the same object with less effort.
154
+ * Code is highly optimized, so the library is much faster than say, FactoryGirl,
155
+ specially when building objects without database interaction.
156
+
157
+
158
+ ### Examples
159
+
160
+ You can check the [specs](https://github.com/ElMassimo/journeyman/tree/master/spec) of the project
161
+ to check how to check some basic factories, and learn how to set it up.
162
+
163
+ ## Notes
164
+ * The DSL does not use instance_exec to allow access to the external context.
165
+
166
+
167
+ License
168
+ --------
169
+
170
+ Copyright (c) 2014 Máximo Mussini
171
+
172
+ Permission is hereby granted, free of charge, to any person obtaining
173
+ a copy of this software and associated documentation files (the
174
+ "Software"), to deal in the Software without restriction, including
175
+ without limitation the rights to use, copy, modify, merge, publish,
176
+ distribute, sublicense, and/or sell copies of the Software, and to
177
+ permit persons to whom the Software is furnished to do so, subject to
178
+ the following conditions:
179
+
180
+ The above copyright notice and this permission notice shall be
181
+ included in all copies or substantial portions of the Software.
182
+
183
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
184
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
185
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
186
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
187
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
188
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
189
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/journeyman.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'journeyman/load'
2
+ require 'journeyman/integration'
3
+ require 'journeyman/definition'
4
+
5
+ # Public: Allows to define and use factory methods. It is capable of providing
6
+ # `build`, `create`, `find`, and `default` methods, the last two are optional.
7
+ #
8
+ # Examples:
9
+ #
10
+ # Journeyman.define :user do |t|
11
+ # {
12
+ # name: "Johnnie Walker",
13
+ # date_of_birth: ->{ 150.years.ago }
14
+ # }
15
+ # end
16
+ #
17
+ # Journeyman.build(:user) => build_user
18
+ # Journeyman.create(:user) => create_user
19
+ #
20
+ module Journeyman
21
+ extend Load
22
+ extend Integration
23
+ extend Definition
24
+
25
+ # Public: Initializes Journeyman by loading the libraries, attaching to the
26
+ # current context, and configuring the testing libraries.
27
+ def self.load(env, framework: nil)
28
+ @helpers = Module.new
29
+ attach(env)
30
+ load_factories
31
+ setup_integration(env, framework)
32
+ end
33
+
34
+ # Public: Attaches Journeyman to the specified context, which enables the use
35
+ # of the convenience acessors for the factory methods, like `Journeyman.build`.
36
+ def self.attach(context)
37
+ @context = context
38
+ end
39
+
40
+ # Public: Convenience accessor for build methods.
41
+ def self.build(name, *args, &block)
42
+ @context.send("build_#{name}", *args, &block)
43
+ end
44
+
45
+ # Public: Convenience accessor for create methods.
46
+ def self.create(name, *args, &block)
47
+ @context.send("create_#{name}", *args, &block)
48
+ end
49
+
50
+ # Public: Convenience accessor for default methods.
51
+ def self.default(name)
52
+ @context.send("default_#{name}")
53
+ end
54
+
55
+ # Internal: Executes a proc in the context that is currently attached.
56
+ def self.execute(proc, *args)
57
+ if proc
58
+ if proc.arity == 0
59
+ @context.instance_exec(&proc)
60
+ else
61
+ @context.instance_exec(*args, &proc)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,66 @@
1
+ require 'journeyman/configuration'
2
+ module Journeyman
3
+
4
+ # Internal: Builds and creates objects, using the configuration provided.
5
+ class Builder
6
+ extend Forwardable
7
+
8
+ attr_reader :config
9
+ def_delegators(:config, *Configuration::OPTIONS, *Configuration::METHOD_OPTIONS, :name)
10
+
11
+ def initialize(name, options, config)
12
+ @config = Configuration.new(name, options, config)
13
+ end
14
+
15
+ # Internal: Executes the finder.
16
+ def find(id)
17
+ config.finder.call(id)
18
+ end
19
+
20
+ # Internal: Builds a new instance, using the configuration specified in the
21
+ # factory.
22
+ #
23
+ # attrs - The attributes used to build the object
24
+ #
25
+ # Returns a new instance of the object.
26
+ def build(attrs={})
27
+ check_build_arguments(attrs)
28
+ attrs = merge_defaults(attrs)
29
+ attrs = Journeyman.execute(processor, attrs) if processor
30
+ config.builder.call(attrs)
31
+ end
32
+
33
+ # Internal: Create a new instance, using the configuration specified in the
34
+ # factory.
35
+ #
36
+ # attrs - The attributes used to build the object
37
+ #
38
+ # Returns a new instance of the object.
39
+ def create(attrs={})
40
+ build(attrs).tap { |instance|
41
+ instance.save!
42
+ Journeyman.execute(after_create_callback, instance, attrs)
43
+ }
44
+ end
45
+
46
+ private
47
+
48
+ # Internal: Merges the default attributes to the specified attributes Hash.
49
+ #
50
+ # Returns the modified Hash.
51
+ def merge_defaults(attributes={})
52
+ attributes.tap do |attrs|
53
+ attrs.merge!(static_defaults){ |key, user, default| user } # Reverse Merge
54
+ dynamic_defaults.each { |key, value| attrs[key] ||= Journeyman.execute(value, attrs) }
55
+ end
56
+ end
57
+
58
+ # Internal: Checks the attributes to make sure it's a Hash, to provide more
59
+ # insight on wrong usage.
60
+ def check_build_arguments(attrs)
61
+ unless attrs.is_a?(Hash)
62
+ raise ArgumentError, "Journeyman expected a Hash, but received: #{attrs}"
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,168 @@
1
+ module Journeyman
2
+
3
+ # Public: Provides a DSL for configuration of the factories.
4
+ class Configuration
5
+
6
+ METHOD_OPTIONS = [:finder, :builder, :processor]
7
+
8
+ OPTIONS = [
9
+ :parent, :defaults, :finder_attribute, # Public
10
+ :static_defaults, :dynamic_defaults, :after_create_callback # Internal
11
+ ]
12
+
13
+ # Internal: Name of the factory, and configuration options.
14
+ attr_reader :name, :options
15
+
16
+ # Public: Receives the name of the factory, and configuration options.
17
+ #
18
+ # Yields itself to the block passed to the `Journeyman.define`.
19
+ def initialize(name, options, config)
20
+ @name, @options = name, options
21
+ extract_defaults config.call(self)
22
+ verify_valid_or_exit
23
+ end
24
+
25
+ # Public: DSL to configure a Journeyman definition. The following are only
26
+ # the methods that take a block, other configuration options exist but take
27
+ # a single argument.
28
+
29
+ # Public: Defines how to find an instance.
30
+ #
31
+ # find { |id|
32
+ # User.find_by(name_or_email(id) => id)
33
+ # }
34
+ #
35
+ # Yields the find argument passed to the `find_#{name}` method.
36
+ def find(proc=nil, &block)
37
+ options[:finder] = proc || block
38
+ end
39
+
40
+ # Public: Defines how to build an instance. Highly customizable.
41
+ #
42
+ # build { |attributes|
43
+ # blueprint, patient = attributes.delete(:blueprint), attributes.delete(:patient)
44
+ # blueprint.enroll(patient)
45
+ # }
46
+ #
47
+ # Yields the arguments passed to the `build_#{name}` method after adding the
48
+ # defaults and invoking the processor.
49
+ def build(proc=nil, &block)
50
+ options[:builder] ||= proc || block
51
+ end
52
+
53
+ # Public: Attributes processor, allows to modify the passed attributes
54
+ # before building an instance.
55
+ def process(proc=nil, &block)
56
+ options[:processor] ||= proc || block
57
+ end
58
+
59
+ # Public: Allows to ignore certain attributes, that can be accessed in the
60
+ # after_create callback.
61
+ def ignore(*ignored)
62
+ options[:ignored] = ->(attrs) do
63
+ attrs = attrs.dup; ignored.each { |key| attrs.delete(key) }; attrs
64
+ end
65
+ end
66
+
67
+ # Public: Invoked after creating an object, useful for setting up secondary
68
+ # or optional relations.
69
+ def after_create(proc=nil, &block)
70
+ options[:after_create_callback] ||= proc || block
71
+ end
72
+
73
+
74
+ # Internal: Configuration Options provided for the Journeyman builder. Here
75
+ # is where you can stop reading unless you are interested in the internals.
76
+
77
+ # Internal: Class of the model to build, used in the default build strategy.
78
+ def model
79
+ options[:model] ||= infer_model_class(name)
80
+ end
81
+
82
+ # Internal: Returns the finder proc, or the default finder strategy.
83
+ def finder
84
+ options[:finder] ||= default_finder
85
+ end
86
+
87
+ # Internal: Returns the finder proc, or the default builder strategy.
88
+ def builder
89
+ options[:builder] ||= parent_builder || default_builder
90
+ end
91
+
92
+ # Internal: Returns a custom processor, or ignore directive.
93
+ def processor
94
+ options[:ignored] || options[:processor]
95
+ end
96
+
97
+ private
98
+
99
+ # Internal: Default finder strategy used.
100
+ def default_finder
101
+ options[:finder_attribute] ||= :name
102
+ ->(name) { model.find_by(finder_attribute => name) }
103
+ end
104
+
105
+ # Internal: Creates the object by simply using the initializer.
106
+ def default_builder
107
+ ->(attrs={}) { model.new(attrs) }
108
+ end
109
+
110
+ # Internal: Uses the builder of the parent to construct the object.
111
+ #
112
+ # Returns the builder if a :parent was set, or nil.
113
+ def parent_builder
114
+ ->(attrs={}) { Journeyman.build(parent, attrs) } if parent
115
+ end
116
+
117
+ # Internal: Prepares the default arguments for the builder.
118
+ # The return value of the configuration block may provide the defaults.
119
+ #
120
+ # result - The return value of the configuration block.
121
+ #
122
+ # Returns nothing.
123
+ def extract_defaults(result)
124
+ defaults = options[:defaults] || (result if result.is_a?(Hash)) || {}
125
+
126
+ options[:dynamic_defaults], options[:static_defaults] = partition_defaults(defaults)
127
+ end
128
+
129
+ # Internal: Splits static from dynamic arguments for runtime performance.
130
+ def partition_defaults(defaults)
131
+ defaults.partition { |key, value| value.is_a?(Proc) }.map(&:to_h)
132
+ end
133
+
134
+ # Internal: Infers a model class.
135
+ def infer_model_class(name)
136
+ if defined? ActiveSupport
137
+ name.to_s.classify.constantize
138
+ else
139
+ Object.const_get(name.to_s.split('_').collect!{ |w| w.capitalize }.join)
140
+ end
141
+ end
142
+
143
+ # Internal: Checks the configuration's consistency
144
+ def verify_valid_or_exit
145
+ if options[:parent] && options[:builder]
146
+ raise InvalidArgumentError, 'custom builder can not be used in combination with `parent: true`'
147
+ end
148
+ if options[:ignored] && options[:processor]
149
+ raise InvalidArgumentError, 'custom processor can not be used in combination with `ignore`'
150
+ end
151
+ end
152
+
153
+ # Internal: Performance optimization, the option method is defined the first
154
+ # time it's accessed.
155
+ def self.define_option_method(name)
156
+ class_eval <<-OPTION
157
+ def #{name}(value=nil)
158
+ options[:#{name}] = value if value
159
+ options[:#{name}]
160
+ end
161
+ OPTION
162
+ end
163
+
164
+ OPTIONS.each do |name|
165
+ define_option_method(name)
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,55 @@
1
+ require 'journeyman/builder'
2
+ module Journeyman
3
+
4
+ # Internal: Contains all the factory method definition logic.
5
+ module Definition
6
+
7
+ # Public: Defines a new factory for Journeyman, which consists in a build
8
+ # and create method, and may optionally include finder and default methods.
9
+ #
10
+ # Returns Builder for debug purposes.
11
+ def define(name, options={}, &config)
12
+ finder, default = options.delete(:include_finder), options.delete(:include_default)
13
+
14
+ Builder.new(name, options, config).tap do |builder|
15
+ define_find_method(name, builder) unless finder == false
16
+ define_build_method(name, builder)
17
+ define_create_method(name, builder)
18
+ define_default_method(name) if default
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # Factories Definitions
25
+
26
+ # Internal: Defines the finder method.
27
+ def define_find_method(name, builder)
28
+ define_helper "find_#{name}", ->(id) { builder.find(id) }
29
+ end
30
+
31
+ # Internal: Defines the builder method.
32
+ def define_build_method(name, builder)
33
+ define_helper "build_#{name}", ->(attrs={}) { builder.build(attrs) }
34
+ end
35
+
36
+ # Internal: Defines the create method.
37
+ def define_create_method(name, builder)
38
+ define_helper "create_#{name}", ->(attrs={}) { builder.create(attrs) }
39
+ end
40
+
41
+ # Internal: Defines the default method.
42
+ def define_default_method(name)
43
+ @helpers.send :class_eval, <<-EVAL
44
+ def default_#{name}
45
+ @#{name} ||= Journeyman.create(:'#{name}')
46
+ end
47
+ EVAL
48
+ end
49
+
50
+ # Internal: Syntax sugar to define a method in the helpers module.
51
+ def define_helper(name, proc)
52
+ @helpers.send :define_method, name, proc
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,38 @@
1
+ module Journeyman
2
+
3
+ # Internal: Integrations with testing frameworks.
4
+ module Integration
5
+
6
+ # Internal: Sets up the integration with the framework being used.
7
+ def setup_integration(env, framework)
8
+ case framework
9
+ when :rspec then setup_rspec_integration(env)
10
+ when :cucumber then setup_cucumber_integration(env)
11
+ else setup_default_integration(env)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ # Internal: Sets up the default integration, which is helpful for console and
18
+ # mock scripts.
19
+ def setup_default_integration(env)
20
+ env.send :include, @helpers
21
+ Journeyman.attach(env)
22
+ end
23
+
24
+ # Internal: Attaches Journeyman to the RSpec context, and adds the helpers.
25
+ def setup_rspec_integration(env)
26
+ RSpec.configure do |config|
27
+ config.include @helpers
28
+ config.before(:each) { Journeyman.attach(self) }
29
+ end
30
+ end
31
+
32
+ # Internal: Attaches Journeyman to the Cucumber context, and adds the helpers.
33
+ def setup_cucumber_integration(cucumber)
34
+ cucumber.World(@helpers)
35
+ cucumber.Before { Journeyman.attach(self) }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,52 @@
1
+ module Journeyman
2
+
3
+ # Internal: Contains all the file requirement logic, to load the factory definitions.
4
+ module Load
5
+
6
+ # Public: Paths that will be loaded expecting factory definitions.
7
+ attr_accessor :factories_paths
8
+
9
+ def self.extended(journeyman)
10
+ journeyman.factories_paths = %w(spec/factories)
11
+ end
12
+
13
+ # Internal: Loads all the factory files and processes the factory definitions.
14
+ def load_factories
15
+ absolute_factories_paths.each do |path|
16
+ load_factories_if_file(path)
17
+ load_factories_if_directory(path)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ # Internal: Builds the absolute path for the factories location.
24
+ def absolute_factories_paths
25
+ if root_path
26
+ factories_paths.map { |path| root_path.join(path) }
27
+ else
28
+ factories_paths.map { |path| File.expand_path(path) }.uniq
29
+ end
30
+ end
31
+
32
+ # Internal: If the path matches a file, it loads the factories defined in it.
33
+ def load_factories_if_file(path)
34
+ Kernel.load("#{path}.rb") if File.exists?("#{path}.rb")
35
+ end
36
+
37
+ # Internal: If the path is a directory, it loads all the factories in that path.
38
+ def load_factories_if_directory(path)
39
+ if File.directory?(path)
40
+ Dir[File.join(path, '**', '*.rb')].sort.each { |file| Kernel.load file }
41
+ end
42
+ end
43
+
44
+ # Internal: Returns the root path of the project
45
+ # TODO: Extract Rails and Sinatra integration.
46
+ def root_path
47
+ defined?(Rails) && Rails.root ||
48
+ defined?(Sinatra::Application) && Pathname.new(Sinatra::Application.root) ||
49
+ defined?(ROOT_DIR) && Pathname.new(ROOT_DIR)
50
+ end
51
+ end
52
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: journeyman
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Máximo Mussini
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-16 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Journeyman allows you to define factories with custom build methods,
14
+ allowing you to easily bend object creation to the nuances of your application and
15
+ domain. This means you can rely more in Ruby, and less on your ORM
16
+ email:
17
+ - maximomussini@gmail.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files:
21
+ - README.md
22
+ files:
23
+ - README.md
24
+ - lib/journeyman.rb
25
+ - lib/journeyman/builder.rb
26
+ - lib/journeyman/configuration.rb
27
+ - lib/journeyman/definition.rb
28
+ - lib/journeyman/integration.rb
29
+ - lib/journeyman/load.rb
30
+ homepage: https://github.com/ElMassimo/journeyman
31
+ licenses:
32
+ - MIT
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options:
36
+ - "--charset=UTF-8"
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.9.3
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 2.2.2
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Let your factories use your business logic, keeping them flexible and making
55
+ them easier to update.
56
+ test_files: []
57
+ has_rdoc: