makers 0.1.2

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.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +149 -0
  4. data/Rakefile +32 -0
  5. data/lib/generators/makers/model/model_generator.rb +15 -0
  6. data/lib/generators/makers/model/templates/maker.rb +2 -0
  7. data/lib/makers.rb +57 -0
  8. data/lib/makers/callbacks.rb +23 -0
  9. data/lib/makers/configuration.rb +10 -0
  10. data/lib/makers/definitions.rb +43 -0
  11. data/lib/makers/fetcher.rb +18 -0
  12. data/lib/makers/maker.rb +113 -0
  13. data/lib/makers/methods.rb +11 -0
  14. data/lib/makers/proxy.rb +52 -0
  15. data/lib/makers/railtie.rb +33 -0
  16. data/lib/makers/sequence.rb +19 -0
  17. data/lib/makers/version.rb +5 -0
  18. data/test/aliases_test.rb +20 -0
  19. data/test/associations_test.rb +50 -0
  20. data/test/attributes_test.rb +26 -0
  21. data/test/callbacks_test.rb +38 -0
  22. data/test/clean_test.rb +18 -0
  23. data/test/dependent_test.rb +30 -0
  24. data/test/dummy/README.rdoc +28 -0
  25. data/test/dummy/Rakefile +6 -0
  26. data/test/dummy/app/assets/javascripts/application.js +13 -0
  27. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  28. data/test/dummy/app/controllers/application_controller.rb +5 -0
  29. data/test/dummy/app/helpers/application_helper.rb +2 -0
  30. data/test/dummy/app/models/group.rb +2 -0
  31. data/test/dummy/app/models/post.rb +3 -0
  32. data/test/dummy/app/models/user.rb +3 -0
  33. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  34. data/test/dummy/bin/bundle +3 -0
  35. data/test/dummy/bin/rails +4 -0
  36. data/test/dummy/bin/rake +4 -0
  37. data/test/dummy/config.ru +4 -0
  38. data/test/dummy/config/application.rb +22 -0
  39. data/test/dummy/config/boot.rb +5 -0
  40. data/test/dummy/config/database.yml +25 -0
  41. data/test/dummy/config/environment.rb +5 -0
  42. data/test/dummy/config/environments/development.rb +37 -0
  43. data/test/dummy/config/environments/production.rb +87 -0
  44. data/test/dummy/config/environments/test.rb +47 -0
  45. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  46. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  47. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  48. data/test/dummy/config/initializers/inflections.rb +16 -0
  49. data/test/dummy/config/initializers/mime_types.rb +4 -0
  50. data/test/dummy/config/initializers/session_store.rb +3 -0
  51. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  52. data/test/dummy/config/locales/en.yml +23 -0
  53. data/test/dummy/config/routes.rb +56 -0
  54. data/test/dummy/config/secrets.yml +22 -0
  55. data/test/dummy/db/migrate/20140613221835_create_users.rb +13 -0
  56. data/test/dummy/db/migrate/20140615180954_create_posts.rb +10 -0
  57. data/test/dummy/db/schema.rb +33 -0
  58. data/test/dummy/log/test.log +273 -0
  59. data/test/dummy/public/404.html +67 -0
  60. data/test/dummy/public/422.html +67 -0
  61. data/test/dummy/public/500.html +66 -0
  62. data/test/dummy/public/favicon.ico +0 -0
  63. data/test/dummy/test/makers/people.rb +2 -0
  64. data/test/dummy/test/makers/users.rb +3 -0
  65. data/test/fabricators_test.rb +33 -0
  66. data/test/generators_test.rb +13 -0
  67. data/test/inheritance_test.rb +49 -0
  68. data/test/lists_test.rb +33 -0
  69. data/test/load_test.rb +13 -0
  70. data/test/merges_test.rb +31 -0
  71. data/test/test_helper.rb +26 -0
  72. metadata +202 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cf680b76a9d3f14ce6304c691bae71626e5c756c
4
+ data.tar.gz: 32ee7f30fefad366dc28a0cba8e5fb60785375aa
5
+ SHA512:
6
+ metadata.gz: 2140702cff87010956af9acbebe1a74c632dd6b5f9f243f1c3064e96741b08d1783fe5d847f304a913b08e6543d39ec465281026fb18b9bfed356f6596a6471b
7
+ data.tar.gz: 7b54805548f58ad4c9f2075c37f96c62e930f14281910318c796a581b132f06895ccda7e77ee7d87d6749410be9da28109d67f57f5a86bc45e9124e1bf6a0c4b
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Museways
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,149 @@
1
+ [![Gem Version](https://badge.fury.io/rb/makers.svg)](http://badge.fury.io/rb/makers) [![Code Climate](https://codeclimate.com/github/museways/makers/badges/gpa.svg)](https://codeclimate.com/github/museways/makers) [![Build Status](https://travis-ci.org/museways/makers.svg?branch=0.1.0)](https://travis-ci.org/museways/makers) [![Dependency Status](https://gemnasium.com/museways/makers.svg)](https://gemnasium.com/museways/makers)
2
+
3
+ # Makers
4
+
5
+ Minimalistic factory inspired in factory_girl for rails.
6
+
7
+ ## Install
8
+
9
+ Put this line in your Gemfile:
10
+ ```ruby
11
+ gem 'makers', group: [:development, :test]
12
+ ```
13
+
14
+ Then bundle:
15
+ ```
16
+ $ bundle
17
+ ```
18
+
19
+ ## Configuration
20
+
21
+ There is no need to configure anything, all this is done automatically for rspec and minitest:
22
+
23
+ * Loading the definitions.
24
+ * Replacing the fixtures generators.
25
+ * Including the methods inside your testing framework.
26
+ * Cleaning the database after each test.
27
+
28
+ ## Usage
29
+
30
+ ### Methods
31
+
32
+ There are three methods available:
33
+ ```ruby
34
+ attributes_for
35
+ build
36
+ create
37
+ ```
38
+
39
+ Is possible to override the defaults passing a hash:
40
+ ```ruby
41
+ build :user, name: 'other'
42
+ create :category, title: 'other'
43
+ ```
44
+
45
+ To create lists just pass the desired size as second parameter to build and create methods:
46
+ ```ruby
47
+ build :user, 2, name: 'other'
48
+ create :category, 5, title: 'other'
49
+ ```
50
+
51
+ ### Makers
52
+
53
+ Define them in a ruby file inside test/makers or spec/makers folders:
54
+ ```ruby
55
+ maker :user do
56
+ name 'example'
57
+ end
58
+ ```
59
+
60
+ ### Inheritance
61
+
62
+ Can be declare nested or separated:
63
+ ```ruby
64
+ maker :user do
65
+ name 'example'
66
+ maker :user_with_email do
67
+ email 'example@mail.com'
68
+ end
69
+ end
70
+ maker :user_with_age, parent: :user do
71
+ age 9
72
+ end
73
+ ```
74
+
75
+ ### Sequences
76
+
77
+ Generates an unique sequence of numbers for the attribute of the maker:
78
+ ```ruby
79
+ maker :user do
80
+ sequence(:email) { |n| "example#{n}@mail.com" }
81
+ sequence(:age)
82
+ end
83
+ ```
84
+
85
+ ### Associations
86
+
87
+ Associations are used by name:
88
+ ```ruby
89
+ maker :user do
90
+ posts
91
+ comments 4 # You can customize the number of records
92
+ end
93
+ maker :post do
94
+ user
95
+ end
96
+ maker :comment do
97
+ user
98
+ end
99
+ ```
100
+
101
+ ### Aliases
102
+
103
+ The aliases are important when there is the need of context:
104
+ ```ruby
105
+ maker :user, aliases: :author do
106
+ comments
107
+ end
108
+ maker :post, aliases: :comment do
109
+ title
110
+ author
111
+ end
112
+ ```
113
+
114
+ ### Dependent attributes
115
+
116
+ If you need to use some logic that depends of another attribute you can use a block or sequence:
117
+ ```ruby
118
+ maker :user do
119
+ name 'example'
120
+ email { "#{name}@mail.com" }
121
+ sequence(:username) { |n| "#{name}-#{n}" }
122
+ end
123
+ ```
124
+
125
+ ### Callbacks
126
+
127
+ The available callbacks are before(:build), before(:create), after(:build) and after(:create):
128
+ ```ruby
129
+ maker :user do
130
+ after(:build) { |u| u.name = 'sample' }
131
+ end
132
+ ```
133
+
134
+ You can declare global callbacks in your test or spec helper as well:
135
+ ```ruby
136
+ Makers.configure do
137
+ after(:create) do |object|
138
+ log object.errors unless object.valid?
139
+ end
140
+ end
141
+ ```
142
+
143
+ ## Credits
144
+
145
+ This gem is maintained and funded by [museways](http://museways.com).
146
+
147
+ ## License
148
+
149
+ It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Makers'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
22
+ require 'rake/testtask'
23
+
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = false
29
+ end
30
+
31
+
32
+ task default: :test
@@ -0,0 +1,15 @@
1
+ require 'rails/generators/named_base'
2
+
3
+ module Makers
4
+ module Generators
5
+ class ModelGenerator < Rails::Generators::NamedBase
6
+
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def create_fixture_file
10
+ template 'maker.rb', Makers.path.join("#{table_name}.rb")
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,2 @@
1
+ maker :<%= singular_table_name %> do
2
+ end
data/lib/makers.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'makers/callbacks'
2
+ require 'makers/definitions'
3
+ require 'makers/configuration'
4
+ require 'makers/maker'
5
+ require 'makers/sequence'
6
+ require 'makers/fetcher'
7
+ require 'makers/proxy'
8
+ require 'makers/methods'
9
+ require 'makers/railtie'
10
+
11
+ module Makers
12
+ extend Methods
13
+ class << self
14
+
15
+ def reset
16
+ configuration.reset
17
+ definitions.reset
18
+ end
19
+
20
+ def configure(&block)
21
+ configuration.instance_eval &block
22
+ end
23
+
24
+ def configuration
25
+ @configuration ||= Configuration.new
26
+ end
27
+
28
+ def define(&block)
29
+ definitions.instance_eval &block
30
+ end
31
+
32
+ def definitions
33
+ @definitions ||= Definitions.new
34
+ end
35
+
36
+ def clean
37
+ records.pop.destroy until records.empty?
38
+ end
39
+
40
+ def records
41
+ @records ||= []
42
+ end
43
+
44
+ def load
45
+ if path
46
+ Dir[path.join('**', '*.rb')].each do |file|
47
+ definitions.instance_eval File.read(file)
48
+ end
49
+ end
50
+ end
51
+
52
+ def path
53
+ @path ||= %w(test spec).map{ |dir| Rails.root.join(dir) }.find{ |path| Dir.exist?(path) }.try(:join, 'makers')
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,23 @@
1
+ module Makers
2
+ module Callbacks
3
+
4
+ def callbacks
5
+ @callbacks ||= {}
6
+ end
7
+
8
+ %w(after before).each do |moment|
9
+ define_method moment do |actions, &block|
10
+ actions = [actions] unless actions.is_a? Array
11
+ actions.each do |action|
12
+ name = :"#{moment}_#{action}"
13
+ if callbacks[name]
14
+ callbacks[name] << block
15
+ else
16
+ callbacks[name] = [block]
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ module Makers
2
+ class Configuration
3
+ include Callbacks
4
+
5
+ def reset
6
+ @callbacks = {}
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,43 @@
1
+ module Makers
2
+ class Definitions
3
+
4
+ def initialize
5
+ reset
6
+ end
7
+
8
+ def reset
9
+ @makers = {}
10
+ end
11
+
12
+ def maker(name, options={}, &block)
13
+ maker = Maker.new(name, options, &block)
14
+ iterate_names name, options do |name|
15
+ @makers[name] = maker
16
+ end
17
+ end
18
+
19
+ def find(name)
20
+ @makers[name].tap do |definition|
21
+ raise "Definition #{name} not found" unless definition
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def iterate_names(name, options)
28
+ names = [name]
29
+ if aliases = options[:aliases]
30
+ case aliases
31
+ when Array
32
+ names |= aliases
33
+ else
34
+ names << aliases
35
+ end
36
+ end
37
+ names.each do |name|
38
+ yield name
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ module Makers
2
+ class Fetcher
3
+
4
+ def initialize(name, options, &block)
5
+ @name = name
6
+ @options = options
7
+ instance_eval &block
8
+ end
9
+
10
+ def maker(name, options={}, &block)
11
+ Makers.definitions.maker name, @options.merge(options.merge(parent: @name)), &block
12
+ end
13
+
14
+ def method_missing(name, *args, &block)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,113 @@
1
+ module Makers
2
+ class Maker
3
+
4
+ attr_reader :options, :proxy
5
+
6
+ def initialize(name, options={}, &block)
7
+ @name = name
8
+ @options = options
9
+ @block = block
10
+ @loaded = false
11
+ Fetcher.new(name, options, &block)
12
+ end
13
+
14
+ def parent
15
+ @parent ||= begin
16
+ if @options[:parent]
17
+ Makers.definitions.find(@options[:parent])
18
+ end
19
+ end
20
+ end
21
+
22
+ def attributes_for(options={})
23
+ {}.tap do |hash|
24
+ iterate_attributes(options, proxy) do |name, value|
25
+ hash[name] = value
26
+ end
27
+ end
28
+ end
29
+
30
+ %w(build create).each do |name|
31
+ define_method name do |*args|
32
+ options = args.extract_options!
33
+ single_name = :"#{name}_one"
34
+ if args.any?
35
+ [].tap do |list|
36
+ args.first.times do
37
+ list << send(single_name, options)
38
+ end
39
+ end
40
+ else
41
+ send(single_name, options)
42
+ end
43
+ end
44
+ end
45
+
46
+ %w(options attributes_for build create).each do |name|
47
+ define_method :"#{name}_with_load" do |*args|
48
+ load
49
+ send :"#{name}_without_load", *args
50
+ end
51
+ alias_method_chain name, :load
52
+ end
53
+
54
+ protected
55
+
56
+ def load
57
+ unless @loaded
58
+ if parent
59
+ @options = parent.options.merge(@options)
60
+ end
61
+ unless @options[:class] ||= @name.to_s.classify.constantize
62
+ raise "Class not found for maker #{@name}"
63
+ end
64
+ @proxy = Proxy.new(self, &@block)
65
+ @loaded = true
66
+ end
67
+ end
68
+
69
+ def build_one(options={})
70
+ @options[:class].new.tap do |instance|
71
+ trigger :before_build, instance
72
+ iterate_attributes(options, instance) do |name, value|
73
+ instance.send :"#{name}=", value
74
+ end
75
+ trigger :after_build, instance
76
+ end
77
+ end
78
+
79
+ def create_one(options={})
80
+ build_one(options).tap do |instance|
81
+ trigger :before_create, instance
82
+ if instance.save
83
+ Makers.records << instance
84
+ end
85
+ trigger :after_create, instance
86
+ end
87
+ end
88
+
89
+ def trigger(name, instance)
90
+ globals = (Makers.configuration.callbacks[name] || [])
91
+ locals = (proxy.callbacks[name] || [])
92
+ (globals + locals).each do |callback|
93
+ callback.call instance
94
+ end
95
+ end
96
+
97
+ def iterate_attributes(options={}, context)
98
+ proxy.attributes.merge(options).each do |name, value|
99
+ case value
100
+ when Proc
101
+ context.instance_eval &value
102
+ when Sequence
103
+ value.generate context
104
+ else
105
+ value
106
+ end.tap do |value|
107
+ yield name, value
108
+ end
109
+ end
110
+ end
111
+
112
+ end
113
+ end