journeyman 0.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 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: