makers 0.1.3 → 0.2.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +64 -70
  4. data/Rakefile +1 -14
  5. data/lib/generators/makers/install_generator.rb +20 -0
  6. data/lib/generators/makers/templates/definitions.rb +2 -0
  7. data/lib/makers.rb +8 -35
  8. data/lib/makers/definitions.rb +18 -27
  9. data/lib/makers/dsl/maker.rb +74 -0
  10. data/lib/makers/extensions/active_support/test_case.rb +15 -0
  11. data/lib/makers/maker.rb +32 -81
  12. data/lib/makers/proxy.rb +3 -42
  13. data/lib/makers/railtie.rb +10 -21
  14. data/lib/makers/version.rb +1 -1
  15. data/test/dummy/Rakefile +0 -1
  16. data/test/dummy/app/views/layouts/application.html.erb +9 -11
  17. data/test/dummy/bin/bundle +1 -0
  18. data/test/dummy/bin/rails +1 -0
  19. data/test/dummy/bin/rake +1 -0
  20. data/test/dummy/bin/setup +30 -0
  21. data/test/dummy/config/application.rb +3 -0
  22. data/test/dummy/config/database.yml +4 -22
  23. data/test/dummy/config/database.yml.travis +3 -0
  24. data/test/dummy/config/environments/development.rb +6 -2
  25. data/test/dummy/config/environments/production.rb +16 -24
  26. data/test/dummy/config/environments/test.rb +7 -12
  27. data/test/dummy/config/initializers/assets.rb +11 -0
  28. data/test/dummy/config/secrets.yml +1 -1
  29. data/test/dummy/db/migrate/20140613221835_create_users.rb +0 -2
  30. data/test/dummy/db/migrate/20140615180954_create_posts.rb +0 -3
  31. data/test/dummy/db/schema.rb +38 -14
  32. data/test/dummy/log/development.log +176 -0
  33. data/test/dummy/log/test.log +1529 -0
  34. data/test/dummy/test/makers.rb +20 -0
  35. data/test/generator_test.rb +18 -0
  36. data/test/makers_test.rb +66 -0
  37. data/test/test_helper.rb +5 -18
  38. metadata +31 -48
  39. data/lib/generators/makers/model/model_generator.rb +0 -15
  40. data/lib/generators/makers/model/templates/maker.rb +0 -2
  41. data/lib/makers/callbacks.rb +0 -23
  42. data/lib/makers/configuration.rb +0 -10
  43. data/lib/makers/fetcher.rb +0 -18
  44. data/lib/makers/methods.rb +0 -11
  45. data/lib/makers/sequence.rb +0 -19
  46. data/test/aliases_test.rb +0 -20
  47. data/test/associations_test.rb +0 -50
  48. data/test/attributes_test.rb +0 -26
  49. data/test/callbacks_test.rb +0 -38
  50. data/test/clean_test.rb +0 -18
  51. data/test/dependent_test.rb +0 -30
  52. data/test/dummy/README.rdoc +0 -28
  53. data/test/dummy/test/makers/people.rb +0 -2
  54. data/test/dummy/test/makers/users.rb +0 -3
  55. data/test/fabricators_test.rb +0 -33
  56. data/test/generators_test.rb +0 -13
  57. data/test/inheritance_test.rb +0 -49
  58. data/test/lists_test.rb +0 -33
  59. data/test/load_test.rb +0 -13
  60. data/test/merges_test.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3143ece0f562a4ced85734c5a998a5e8d4dccd07
4
- data.tar.gz: ad42645a69354b63eedb3bfd3f9c3c1fda66c84e
3
+ metadata.gz: 1755d396dc8957e00c67a9444667654b0b4664aa
4
+ data.tar.gz: 8be1fb5dd093e611a339b498c7167566775efd01
5
5
  SHA512:
6
- metadata.gz: bdddac354402744691e34740640745827eaf956bbbaa1d23fa6e20ab2ae30551823adc0bc6116be26eda38690633ad65a04baf2793cc75df7f8b6e84793c8297
7
- data.tar.gz: 1bb0f2b8e9ca1c561179a7c638a2d2d3d97114f88b2a1658c886a2f5a77f7d78c4d95f2f832c547f5b77d5c0d31de8c274c438cdd11523c3281fb66e2c4bb487
6
+ metadata.gz: d750ffd12a45749f57e39cc9d05f8caac89bea2f3ce481bbd676a73c9339a4022273985dbeac99507d74fbe6cd6cca76abb1f876246607791a8b16f299caad94
7
+ data.tar.gz: ba20ae75fc27e14830c1ff4613183f6b5bf6dfd99bf4a489a000a095726dbc3353659ee283345edda24553d4e424295369ea35d25971419962d28d244c28cd7b
@@ -1,4 +1,4 @@
1
- Copyright 2015 Mathías Montossi
1
+ Copyright 2016 Mathías Montossi
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,11 +1,19 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/makers.svg)](http://badge.fury.io/rb/makers)
2
2
  [![Code Climate](https://codeclimate.com/github/mmontossi/makers/badges/gpa.svg)](https://codeclimate.com/github/mmontossi/makers)
3
- [![Build Status](https://travis-ci.org/mmontossi/makers.svg](https://travis-ci.org/mmontossi/makers)
3
+ [![Build Status](https://travis-ci.org/mmontossi/makers.svg)](https://travis-ci.org/mmontossi/makers)
4
4
  [![Dependency Status](https://gemnasium.com/mmontossi/makers.svg)](https://gemnasium.com/mmontossi/makers)
5
5
 
6
6
  # Makers
7
7
 
8
- Minimalistic factory inspired in factory_girl for rails.
8
+ Minimalistic factories to replace fixtures in rails.
9
+
10
+ ## Why
11
+
12
+ I did this gem to add some enhancements to my projects:
13
+
14
+ - Enforce better practices removing unnecessary options.
15
+ - Avoid the need to use another method to create lists.
16
+ - Quicker syntax to handle associations.
9
17
 
10
18
  ## Install
11
19
 
@@ -21,20 +29,26 @@ $ bundle
21
29
 
22
30
  ## Configuration
23
31
 
24
- There is no need to configure anything, all this is done automatically for rspec and minitest:
32
+ Generate the configuration file:
33
+ ```
34
+ bundle exec rails g makers:install
35
+ ```
25
36
 
26
- * Loading the definitions.
27
- * Replacing the fixtures generators.
28
- * Including the methods inside your testing framework.
29
- * Cleaning the database after each test.
37
+ Define makers in test/makers.rb or spec/makers.rb:
38
+ ```ruby
39
+ Makers.define do
40
+ maker :user do
41
+ name 'example'
42
+ end
43
+ end
44
+ ```
30
45
 
31
46
  ## Usage
32
47
 
33
48
  ### Methods
34
49
 
35
- There are three methods available:
50
+ There are two methods available:
36
51
  ```ruby
37
- attributes_for
38
52
  build
39
53
  create
40
54
  ```
@@ -45,100 +59,80 @@ build :user, name: 'other'
45
59
  create :category, title: 'other'
46
60
  ```
47
61
 
48
- To create lists just pass the desired size as second parameter to build and create methods:
62
+ To create lists just pass the desired size as second parameter:
49
63
  ```ruby
50
64
  build :user, 2, name: 'other'
51
65
  create :category, 5, title: 'other'
52
66
  ```
53
67
 
54
- ### Makers
55
-
56
- Define them in a ruby file inside test/makers or spec/makers folders:
57
- ```ruby
58
- maker :user do
59
- name 'example'
60
- end
61
- ```
62
-
63
68
  ### Inheritance
64
69
 
65
- Can be declare nested or separated:
70
+ Just concatenate makers:
66
71
  ```ruby
67
- maker :user do
68
- name 'example'
69
- maker :user_with_email do
70
- email 'example@mail.com'
72
+ Makers.define do
73
+ maker :user do
74
+ name 'example'
75
+ maker :user_with_email do
76
+ email 'example@mail.com'
77
+ end
71
78
  end
72
79
  end
73
- maker :user_with_age, parent: :user do
74
- age 9
75
- end
76
80
  ```
77
81
 
78
82
  ### Sequences
79
83
 
80
- Generates an unique sequence of numbers for the attribute of the maker:
84
+ Generates an unique sequence of numbers for an attribute:
81
85
  ```ruby
82
- maker :user do
83
- sequence(:email) { |n| "example#{n}@mail.com" }
84
- sequence(:age)
86
+ Makers.define do
87
+ maker :user do
88
+ sequence(:email) { |n| "example#{n}@mail.com" }
89
+ sequence(:phone)
90
+ end
85
91
  end
86
92
  ```
87
93
 
88
94
  ### Associations
89
95
 
90
- Associations are used by name:
96
+ Associations are defined by name or by the association method:
91
97
  ```ruby
92
- maker :user do
93
- posts
94
- comments 4 # You can customize the number of records
95
- end
96
- maker :post do
97
- user
98
- end
99
- maker :comment do
100
- user
98
+ Makers.define do
99
+ maker :user do
100
+ posts
101
+ comments 4, strategy: :create
102
+ end
103
+ maker :comment do
104
+ association :user
105
+ end
106
+ maker :post do
107
+ user
108
+ end
101
109
  end
102
110
  ```
103
111
 
104
112
  ### Aliases
105
113
 
106
- The aliases are important when there is the need of context:
114
+ Aliases can be assigned in the initialization:
107
115
  ```ruby
108
- maker :user, aliases: :author do
109
- comments
110
- end
111
- maker :post, aliases: :comment do
112
- title
113
- author
116
+ Makers.define do
117
+ maker :user, aliases: :author do
118
+ comments
119
+ end
120
+ maker :post, aliases: :comment do
121
+ title
122
+ author
123
+ end
114
124
  end
115
125
  ```
116
126
 
117
127
  ### Dependent attributes
118
128
 
119
- If you need to use some logic that depends of another attribute you can use a block or sequence:
120
- ```ruby
121
- maker :user do
122
- name 'example'
123
- email { "#{name}@mail.com" }
124
- sequence(:username) { |n| "#{name}-#{n}" }
125
- end
126
- ```
127
-
128
- ### Callbacks
129
-
130
- The available callbacks are before(:build), before(:create), after(:build) and after(:create):
131
- ```ruby
132
- maker :user do
133
- after(:build) { |u| u.name = 'sample' }
134
- end
135
- ```
136
-
137
- You can declare global callbacks in your test or spec helper as well:
129
+ If you need to use some logic that depends of another attribute you can use a block:
138
130
  ```ruby
139
- Makers.configure do
140
- after(:create) do |object|
141
- log object.errors unless object.valid?
131
+ Makers.define do
132
+ maker :user do
133
+ name 'example'
134
+ email { "#{name}@mail.com" }
135
+ sequence(:username) { |n| "#{name}-#{n}" }
142
136
  end
143
137
  end
144
138
  ```
data/Rakefile CHANGED
@@ -4,19 +4,6 @@ rescue LoadError
4
4
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
5
  end
6
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
7
  Bundler::GemHelper.install_tasks
21
8
 
22
9
  require 'rake/testtask'
@@ -26,7 +13,7 @@ Rake::TestTask.new(:test) do |t|
26
13
  t.libs << 'test'
27
14
  t.pattern = 'test/**/*_test.rb'
28
15
  t.verbose = false
16
+ t.warning = false
29
17
  end
30
18
 
31
-
32
19
  task default: :test
@@ -0,0 +1,20 @@
1
+ require 'rails/generators'
2
+
3
+ module Makers
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ def create_definitions_file
10
+ if Dir.exist?(Rails.root.join('spec'))
11
+ directory = 'spec'
12
+ else
13
+ directory = 'test'
14
+ end
15
+ template 'definitions.rb', "#{directory}/makers.rb"
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,2 @@
1
+ Makers.define do
2
+ end
@@ -1,56 +1,29 @@
1
- require 'makers/callbacks'
1
+ require 'generators/makers/install_generator'
2
+ require 'makers/dsl/maker'
3
+ require 'makers/extensions/active_support/test_case'
2
4
  require 'makers/definitions'
3
- require 'makers/configuration'
4
5
  require 'makers/maker'
5
- require 'makers/sequence'
6
- require 'makers/fetcher'
7
6
  require 'makers/proxy'
8
- require 'makers/methods'
9
7
  require 'makers/railtie'
8
+ require 'makers/version'
10
9
 
11
10
  module Makers
12
- extend Methods
13
11
  class << self
14
12
 
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
13
  def configuration
25
14
  @configuration ||= Configuration.new
26
15
  end
27
16
 
28
- def define(&block)
29
- definitions.instance_eval &block
17
+ def configure
18
+ yield configuration
30
19
  end
31
20
 
32
21
  def definitions
33
22
  @definitions ||= Definitions.new
34
23
  end
35
24
 
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')
25
+ def define(&block)
26
+ Proxy.new &block
54
27
  end
55
28
 
56
29
  end
@@ -1,42 +1,33 @@
1
1
  module Makers
2
2
  class Definitions
3
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
4
+ def contains?(name)
5
+ registry.has_key? name
17
6
  end
18
7
 
19
8
  def find(name)
20
- @makers[name].tap do |definition|
21
- raise "Definition #{name} not found" unless definition
9
+ if contains?(name)
10
+ registry[name]
11
+ else
12
+ raise "Definition #{name} not found"
22
13
  end
23
14
  end
24
15
 
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
16
+ def add(names, *args)
17
+ maker = Maker.new(*args)
18
+ names.each do |name|
19
+ if contains?(name)
20
+ raise "Maker #{name} already registered"
33
21
  else
34
- names << aliases
22
+ registry[name] = maker
35
23
  end
36
24
  end
37
- names.each do |name|
38
- yield name
39
- end
25
+ end
26
+
27
+ private
28
+
29
+ def registry
30
+ @registry ||= {}
40
31
  end
41
32
 
42
33
  end
@@ -0,0 +1,74 @@
1
+ module Makers
2
+ module DSL
3
+ class Maker
4
+
5
+ def initialize(name, options={}, &block)
6
+ @name = name
7
+ @options = options.reverse_merge(class_name: name.to_s.classify)
8
+ @class = @options[:class_name].constantize
9
+ @assignments = {}
10
+ if block_given?
11
+ instance_eval &block
12
+ end
13
+ Makers.definitions.add(
14
+ [@name] + Array(@options[:aliases]),
15
+ @options,
16
+ @assignments
17
+ )
18
+ end
19
+
20
+ def maker(name, overrides={}, &block)
21
+ options = @options.dup
22
+ options.delete :aliases
23
+ options.merge! overrides
24
+ options.merge! parent: @name
25
+ DSL::Maker.new name, options, &block
26
+ end
27
+
28
+ def sequence(name, &block)
29
+ index = 0
30
+ if block_given?
31
+ @assignments[name] = -> {
32
+ index += 1
33
+ instance_exec index, &block
34
+ }
35
+ else
36
+ @assignments[name] = -> {
37
+ index += 1
38
+ }
39
+ end
40
+ end
41
+
42
+ def association(name, *args)
43
+ options = args.extract_options!
44
+ name = (options[:maker] || name)
45
+ strategy = (options[:strategy] || :build)
46
+ case @class.reflections[name.to_s].macro
47
+ when :belongs_to,:has_one
48
+ @assignments[name] = -> {
49
+ maker = Makers.definitions.find(name)
50
+ maker.send strategy
51
+ }
52
+ when :has_many
53
+ @assignments[name] = -> {
54
+ maker = Makers.definitions.find(name.to_s.singularize.to_sym)
55
+ (args.first || 1).times.map do
56
+ maker.send strategy
57
+ end
58
+ }
59
+ end
60
+ end
61
+
62
+ def method_missing(name, *args, &block)
63
+ if @class.reflections.has_key?(name.to_s)
64
+ association name, *args
65
+ elsif block_given?
66
+ @assignments[name] = block
67
+ elsif args.size > 0
68
+ @assignments[name] = -> { args.first }
69
+ end
70
+ end
71
+
72
+ end
73
+ end
74
+ end