makers 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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