fabricators 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +34 -26
  3. data/lib/fabricators.rb +26 -12
  4. data/lib/fabricators/callbacks.rb +1 -1
  5. data/lib/fabricators/configuration.rb +10 -0
  6. data/lib/fabricators/definitions.rb +5 -20
  7. data/lib/fabricators/fabricator.rb +13 -4
  8. data/lib/fabricators/{reader.rb → fetcher.rb} +2 -2
  9. data/lib/fabricators/methods.rb +1 -1
  10. data/lib/fabricators/proxy.rb +12 -5
  11. data/lib/fabricators/railtie.rb +1 -1
  12. data/lib/fabricators/{attribute.rb → sequence.rb} +3 -3
  13. data/lib/fabricators/version.rb +1 -1
  14. data/test/aliases_test.rb +4 -10
  15. data/test/associations_test.rb +2 -2
  16. data/test/attributes_test.rb +6 -16
  17. data/test/callbacks_test.rb +5 -3
  18. data/test/dependent_test.rb +9 -5
  19. data/test/dummy/db/migrate/20140613221835_create_users.rb +3 -0
  20. data/test/dummy/db/migrate/20140615180954_create_posts.rb +1 -0
  21. data/test/dummy/db/schema.rb +5 -11
  22. data/test/dummy/log/development.log +15 -0
  23. data/test/dummy/log/test.log +2711 -0
  24. data/test/dummy/test/fabricators/people.rb +2 -0
  25. data/test/fabricators_test.rb +2 -2
  26. data/test/generators_test.rb +2 -2
  27. data/test/inheritance_test.rb +1 -1
  28. data/test/lists_test.rb +2 -2
  29. data/test/load_test.rb +1 -1
  30. data/test/merges_test.rb +3 -3
  31. data/test/test_helper.rb +1 -1
  32. metadata +8 -15
  33. data/test/dummy/db/migrate/20140615152257_add_age_to_users.rb +0 -5
  34. data/test/dummy/db/migrate/20140615175509_add_phone_to_users.rb +0 -5
  35. data/test/dummy/db/migrate/20140615180938_create_groups.rb +0 -9
  36. data/test/dummy/db/migrate/20140615181030_add_group_id_to_users.rb +0 -5
  37. data/test/dummy/db/migrate/20140615181051_add_user_id_to_posts.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aaa3e7a3fadb7a11032d347388fb0ee8e2bc51fc
4
- data.tar.gz: b82cd8864420212b0ec69ed10dcee10553ebb468
3
+ metadata.gz: 4be64faca5c2c0d4113a421b3209ea9d9e201b1b
4
+ data.tar.gz: 3a91647becc2ebe494bdcaadda4c6710acebf736
5
5
  SHA512:
6
- metadata.gz: 60f13c2519e2a42553657c65190a2bc7dbaf9494839d270b1ffa9f07190f9f7aedbb634895545764440a330ed14af35e987198dc7f45c44bc089bd09e0a59b74
7
- data.tar.gz: af6f469463db9c2babb7b038418b9d85ada22d0af24ff66ca95d0628306355486d1cab8405c8f2f6f00aca3bd9c9278a7c84f077f8ee1a4dafe5ddc937584199
6
+ metadata.gz: 3be1d8f754cb2fca13a5e44b4556532f0c443090a38d11b180fc38e8320ed216d61c7f77be6b1d0934ef4a67a2a65b88275d78aa1a2cf0b5f52ee37c5f15642c
7
+ data.tar.gz: 4e0c5a835598acdb78962f3034c617f6a1c7f7d7e556097a34a249d75fa31ad48e2794188efb1db1058e2caf180607712836f091ac757f6ab8588627b3247599
@@ -1,24 +1,24 @@
1
- === NOTE: From version 0.0.2 the syntax has been simplified.
1
+ === NOTE: Important changes in version 0.1.0, read below.
2
2
 
3
3
  ---
4
4
 
5
- {<img src="https://badge.fury.io/rb/fabricators.png" alt="Gem Version" />}[http://badge.fury.io/rb/fabricators] {<img src="https://codeclimate.com/github/museways/fabricators.png" />}[https://codeclimate.com/github/museways/fabricators] {<img src="https://travis-ci.org/museways/fabricators.png?branch=master" alt="Build Status" />}[https://travis-ci.org/museways/fabricators] {<img src="https://gemnasium.com/museways/fabricators.png" alt="Dependency Status" />}[https://gemnasium.com/museways/fabricators]
5
+ {<img src="https://badge.fury.io/rb/fabricators.png" alt="Gem Version" />}[http://badge.fury.io/rb/fabricators] {<img src="https://codeclimate.com/github/museways/fabricators.png" />}[https://codeclimate.com/github/museways/fabricators] {<img src="https://travis-ci.org/museways/fabricators.png?branch=master" alt="Build Status" />}[https://travis-ci.org/museways/fabricators]
6
6
 
7
7
  = Fabricators
8
8
 
9
- Minimalistic factory alternative inspired in factory_girl.
9
+ Minimalistic factory inspired in factory_girl for rails.
10
10
 
11
11
  = Install
12
12
 
13
13
  Put this line in your Gemfile:
14
- gem 'fabricators'
15
-
14
+ gem 'fabricators', group: [:development, :test]
15
+
16
16
  Then bundle:
17
- $ bundle
17
+ $ bundle
18
18
 
19
19
  = Configuration
20
20
 
21
- There is no need to configure anything, all is done automatically:
21
+ There is no need to configure anything, all this is done automatically for rspec and minitest:
22
22
 
23
23
  - Loading the definitions.
24
24
  - Replacing the fixtures generators.
@@ -38,13 +38,13 @@ Is possible to override the defaults passing a hash:
38
38
  build :user, name: 'other'
39
39
  create :category, title: 'other'
40
40
 
41
- To create lists just pass the desired size as second parameter to build and create:
41
+ To create lists just pass the desired size as second parameter to build and create methods:
42
42
  build :user, 2, name: 'other'
43
43
  create :category, 5, title: 'other'
44
44
 
45
45
  == Fabricators
46
46
 
47
- Define them inside test/fabricators or spec/fabricators:
47
+ Define them in a ruby file inside test/fabricators or spec/fabricators folders:
48
48
  fabricator :user do
49
49
  name 'example'
50
50
  end
@@ -62,24 +62,20 @@ Can be declare nested or separated:
62
62
  age 9
63
63
  end
64
64
 
65
- == Attributes
65
+ == Sequences
66
66
 
67
- Define them outside your fabricators and reference them by name:
68
- attribute(:name) { 'example' }
69
- attribute(:email) { |n| "example#{n}@mail.com" }
70
- attribute(:age)
67
+ Generates an unique sequence of numbers for the attribute of the fabricator:
71
68
  fabricator :user do
72
- name
73
- email
74
- age
69
+ sequence(:email) { |n| "example#{n}@mail.com" }
70
+ sequence(:age)
75
71
  end
76
72
 
77
73
  == Associations
78
74
 
79
- Associations are declared just by the name of the association:
75
+ Associations are used by name:
80
76
  fabricator :user do
81
77
  posts
82
- comments 4 # By default 1, but can be overwritten
78
+ comments 4 # You can customize the number of records
83
79
  end
84
80
  fabricator :post do
85
81
  user
@@ -90,11 +86,8 @@ Associations are declared just by the name of the association:
90
86
 
91
87
  == Aliases
92
88
 
93
- The aliases are essential when there is the need of context:
94
- attribute(:title, aliases: [:first_name, :last_name]) { 'example' }
89
+ The aliases are important when there is the need of context:
95
90
  fabricators :user, aliases: :author do
96
- first_name
97
- last_name
98
91
  comments
99
92
  end
100
93
  fabricators :post, aliases: :comment do
@@ -104,16 +97,31 @@ The aliases are essential when there is the need of context:
104
97
 
105
98
  == Dependent attributes
106
99
 
107
- If you need to use some logic that depends of another attribute you can go:
100
+ If you need to use some logic that depends of another attribute you can use a block or sequence:
108
101
  fabricators :user do
109
102
  name 'example'
110
103
  email { "#{name}@mail.com" }
104
+ sequence(:username) { |n| "#{name}-#{n}" }
111
105
  end
112
106
 
113
107
  == Callbacks
114
108
 
115
109
  The available callbacks are before(:build), before(:create), after(:build) and after(:create):
116
- before(:build) { |u| u.name = 'global' }
117
110
  fabricator :user do
118
- after(:build) { |u| u.name = 'local' }
111
+ after(:build) { |u| u.name = 'sample' }
112
+ end
113
+
114
+ You can declare global callbacks in your test or spec helper as well:
115
+ Fabricators.configure do
116
+ after(:create) do |object|
117
+ log object.errors unless object.valid?
118
+ end
119
119
  end
120
+
121
+ = Credits
122
+
123
+ This gem is maintained and funded by museways[http://museways.com].
124
+
125
+ = License
126
+
127
+ It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
@@ -1,8 +1,9 @@
1
1
  require 'fabricators/callbacks'
2
2
  require 'fabricators/definitions'
3
+ require 'fabricators/configuration'
3
4
  require 'fabricators/fabricator'
4
- require 'fabricators/attribute'
5
- require 'fabricators/reader'
5
+ require 'fabricators/sequence'
6
+ require 'fabricators/fetcher'
6
7
  require 'fabricators/proxy'
7
8
  require 'fabricators/methods'
8
9
  require 'fabricators/railtie'
@@ -11,33 +12,46 @@ module Fabricators
11
12
  extend Methods
12
13
  class << self
13
14
 
14
- def define(&block)
15
- definitions.instance_eval &block
15
+ def reset
16
+ configuration.reset
17
+ definitions.reset
16
18
  end
17
19
 
18
- def clean
19
- records.pop.destroy until records.empty?
20
+ def configure(&block)
21
+ configuration.instance_eval &block
20
22
  end
21
23
 
22
- def records
23
- @records ||= []
24
+ def configuration
25
+ @configuration ||= Configuration.new
26
+ end
27
+
28
+ def define(&block)
29
+ definitions.instance_eval &block
24
30
  end
25
31
 
26
32
  def definitions
27
33
  @definitions ||= Definitions.new
28
34
  end
29
35
 
30
- def path
31
- @path ||= %w(test spec).map{ |dir| Rails.root.join(dir) }.find{ |path| Dir.exist?(path) }.try(:join, 'fabricators')
36
+ def clean
37
+ records.pop.destroy until records.empty?
32
38
  end
33
39
 
34
- def load_files
40
+ def records
41
+ @records ||= []
42
+ end
43
+
44
+ def load
35
45
  if path
36
46
  Dir[path.join('**', '*.rb')].each do |file|
37
- Fabricators.definitions.instance_eval File.read(file)
47
+ definitions.instance_eval File.read(file)
38
48
  end
39
49
  end
40
50
  end
41
51
 
52
+ def path
53
+ @path ||= %w(test spec).map{ |dir| Rails.root.join(dir) }.find{ |path| Dir.exist?(path) }.try(:join, 'fabricators')
54
+ end
55
+
42
56
  end
43
57
  end
@@ -4,7 +4,7 @@ module Fabricators
4
4
  def callbacks
5
5
  @callbacks ||= {}
6
6
  end
7
-
7
+
8
8
  %w(after before).each do |moment|
9
9
  define_method moment do |actions, &block|
10
10
  actions = [actions] unless actions.is_a? Array
@@ -0,0 +1,10 @@
1
+ module Fabricators
2
+ class Configuration
3
+ include Callbacks
4
+
5
+ def reset
6
+ @callbacks = {}
7
+ end
8
+
9
+ end
10
+ end
@@ -1,39 +1,24 @@
1
1
  module Fabricators
2
2
  class Definitions
3
- include Callbacks
4
-
3
+
5
4
  def initialize
6
5
  reset
7
6
  end
8
7
 
9
8
  def reset
10
9
  @fabricators = {}
11
- @attributes = {}
12
- @callbacks = {}
13
10
  end
14
-
11
+
15
12
  def fabricator(name, options={}, &block)
16
13
  fabricator = Fabricator.new(name, options, &block)
17
14
  iterate_names name, options do |name|
18
15
  @fabricators[name] = fabricator
19
16
  end
20
17
  end
21
-
22
- def attribute(name, options={}, &block)
23
- attribute = Attribute.new(&block)
24
- iterate_names name, options do |name|
25
- @attributes[name] = attribute
26
- end
27
- end
28
18
 
29
- def find(name, type)
30
- case type
31
- when :fabricator
32
- @fabricators[name]
33
- when :attribute
34
- @attributes[name]
35
- end.tap do |definition|
36
- raise "Definition #{name} of type #{type} not found" unless definition
19
+ def find(name)
20
+ @fabricators[name].tap do |definition|
21
+ raise "Definition #{name} not found" unless definition
37
22
  end
38
23
  end
39
24
 
@@ -8,13 +8,13 @@ module Fabricators
8
8
  @options = options
9
9
  @block = block
10
10
  @loaded = false
11
- Reader.new(name, options, &block)
11
+ Fetcher.new(name, options, &block)
12
12
  end
13
13
 
14
14
  def parent
15
15
  @parent ||= begin
16
16
  if @options[:parent]
17
- Fabricators.definitions.find(@options[:parent], :fabricator)
17
+ Fabricators.definitions.find(@options[:parent])
18
18
  end
19
19
  end
20
20
  end
@@ -87,7 +87,7 @@ module Fabricators
87
87
  end
88
88
 
89
89
  def trigger(name, instance)
90
- globals = (Fabricators.definitions.callbacks[name] || [])
90
+ globals = (Fabricators.configuration.callbacks[name] || [])
91
91
  locals = (proxy.callbacks[name] || [])
92
92
  (globals + locals).each do |callback|
93
93
  callback.call instance
@@ -96,7 +96,16 @@ module Fabricators
96
96
 
97
97
  def iterate_attributes(options={}, context)
98
98
  proxy.attributes.merge(options).each do |name, value|
99
- yield name, (value.is_a?(Proc) ? context.instance_eval(&value) : 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
100
109
  end
101
110
  end
102
111
 
@@ -1,12 +1,12 @@
1
1
  module Fabricators
2
- class Reader
2
+ class Fetcher
3
3
 
4
4
  def initialize(name, options, &block)
5
5
  @name = name
6
6
  @options = options
7
7
  instance_eval &block
8
8
  end
9
-
9
+
10
10
  def fabricator(name, options={}, &block)
11
11
  Fabricators.definitions.fabricator name, @options.merge(options.merge(parent: @name)), &block
12
12
  end
@@ -3,7 +3,7 @@ module Fabricators
3
3
 
4
4
  %w(build create attributes_for).each do |method|
5
5
  define_method method do |name, *args|
6
- Fabricators.definitions.find(name, :fabricator).send(method, *args)
6
+ Fabricators.definitions.find(name).send(method, *args)
7
7
  end
8
8
  end
9
9
 
@@ -5,6 +5,7 @@ module Fabricators
5
5
  def initialize(fabricator, &block)
6
6
  @fabricator = fabricator
7
7
  @attributes = []
8
+ @sequences = {}
8
9
  instance_eval &block
9
10
  end
10
11
 
@@ -19,18 +20,24 @@ module Fabricators
19
20
  end
20
21
  end
21
22
 
23
+ def sequence(name, &block)
24
+ @attributes << name
25
+ @sequences[name] = Sequence.new(&block)
26
+ class_eval do
27
+ define_method(name) { @sequences[name] }
28
+ end
29
+ end
30
+
22
31
  def method_missing(name, *args, &block)
23
32
  unless name == :fabricator
24
33
  options = args.extract_options!
25
34
  strategy = options.delete(:strategy) || :build
26
35
  if block_given?
27
36
  logic = block
28
- elsif fabricator = Fabricators.definitions.find(name, :fabricator) rescue nil
37
+ elsif fabricator = Fabricators.definitions.find(name) rescue nil
29
38
  logic = -> { fabricator.send(strategy, options) }
30
- elsif fabricator = Fabricators.definitions.find(name.to_s.singularize.to_sym, :fabricator) rescue nil
39
+ elsif fabricator = Fabricators.definitions.find(name.to_s.singularize.to_sym) rescue nil
31
40
  logic = -> { fabricator.send(strategy, (args.first || 1), options) }
32
- elsif attribute = Fabricators.definitions.find(name, :attribute) rescue nil
33
- logic = -> { attribute.generate }
34
41
  elsif args.any?
35
42
  logic = -> { args.first }
36
43
  end
@@ -40,6 +47,6 @@ module Fabricators
40
47
  end
41
48
  end
42
49
  end
43
-
50
+
44
51
  end
45
52
  end
@@ -26,7 +26,7 @@ module Fabricators
26
26
  end
27
27
 
28
28
  config.after_initialize do
29
- Fabricators.load_files
29
+ Fabricators.load
30
30
  end
31
31
 
32
32
  end
@@ -1,15 +1,15 @@
1
1
  module Fabricators
2
- class Attribute
2
+ class Sequence
3
3
 
4
4
  def initialize(&block)
5
5
  @index = 0
6
6
  @block = block
7
7
  end
8
8
 
9
- def generate
9
+ def generate(context)
10
10
  @index += 1
11
11
  if @block
12
- @block.call(@index)
12
+ context.instance_exec @index, &@block
13
13
  else
14
14
  @index
15
15
  end
@@ -1,5 +1,5 @@
1
1
  module Fabricators
2
2
 
3
- VERSION = '0.0.4'
3
+ VERSION = '0.1.0'
4
4
 
5
5
  end
@@ -4,7 +4,6 @@ class AliasesTest < ActiveSupport::TestCase
4
4
 
5
5
  setup do
6
6
  Fabricators.define do
7
- attribute(:mobile, aliases: :phone)
8
7
  fabricator :user, aliases: [:owner, :author] do
9
8
  name 'name'
10
9
  phone
@@ -12,15 +11,10 @@ class AliasesTest < ActiveSupport::TestCase
12
11
  end
13
12
  end
14
13
 
15
- test "generator aliases" do
16
- assert_kind_of Fabricators::Attribute, Fabricators.definitions.find(:mobile, :attribute)
17
- assert_kind_of Fabricators::Attribute, Fabricators.definitions.find(:phone, :attribute)
18
- end
19
-
20
- test "fabricator aliases" do
21
- assert_kind_of Fabricators::Fabricator, Fabricators.definitions.find(:user, :fabricator)
22
- assert_kind_of Fabricators::Fabricator, Fabricators.definitions.find(:owner, :fabricator)
23
- assert_kind_of Fabricators::Fabricator, Fabricators.definitions.find(:author, :fabricator)
14
+ test "aliases" do
15
+ assert_kind_of Fabricators::Fabricator, Fabricators.definitions.find(:user)
16
+ assert_kind_of Fabricators::Fabricator, Fabricators.definitions.find(:owner)
17
+ assert_kind_of Fabricators::Fabricator, Fabricators.definitions.find(:author)
24
18
  end
25
19
 
26
20
  end