modelizer 4.0.0 → 5.0.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.
- data/CHANGELOG.rdoc +5 -0
- data/Manifest.txt +1 -1
- data/README.rdoc +52 -40
- data/Rakefile +2 -0
- data/lib/modelizer.rb +75 -111
- data/lib/modelizer/all.rb +3 -0
- data/lib/modelizer/assertions.rb +2 -0
- data/lib/modelizer/validations.rb +12 -25
- metadata +13 -14
- data/test/test_modelizer.rb +0 -14
data/CHANGELOG.rdoc
CHANGED
data/Manifest.txt
CHANGED
data/README.rdoc
CHANGED
@@ -5,72 +5,84 @@
|
|
5
5
|
== Description
|
6
6
|
|
7
7
|
Need a simple, consistent way to create model instances and check
|
8
|
-
validations in your ActiveRecord 3.1+ tests? Use the Modelizer.
|
8
|
+
validations in your ActiveRecord 3.1+ tests? Use the Modelizer. Just
|
9
|
+
don't trust the docs, since lots changed in 5.x and I got lazy.
|
9
10
|
|
10
11
|
== Examples
|
11
12
|
|
12
|
-
First, enable the Modelizer
|
13
|
+
First, enable the Modelizer in your test helper. In Rails, try
|
14
|
+
something like:
|
15
|
+
|
16
|
+
require "modelizer/all"
|
13
17
|
|
14
18
|
class ActiveSupport::TestCase
|
15
19
|
include Modelizer
|
20
|
+
extend Modelizer::Validations
|
16
21
|
end
|
17
22
|
|
18
|
-
Next, define
|
19
|
-
|
20
|
-
|
21
|
-
<tt>
|
23
|
+
Next, define some fixtures and factories. Modelizer will load these
|
24
|
+
when the module is included, using
|
25
|
+
<tt>"test/{factories,fixtures}/**/*.rb"</tt> as a default glob. Change
|
26
|
+
it by setting <tt>Modelizer.glob</tt> before module inclusion.
|
27
|
+
|
28
|
+
Fixture and factory definitions look remarkably similar. The only real
|
29
|
+
difference is that fixtures get loaded into the DB once at module
|
30
|
+
inclusion and factories don't. Factories will also generally use
|
31
|
+
autogenerated/random data generators. Some examples:
|
32
|
+
|
33
|
+
# from test/fixtures/user.rb
|
22
34
|
|
23
|
-
|
35
|
+
fixture :user, User do |u|
|
36
|
+
u.account = use :account
|
37
|
+
u.email = "default@example.org
|
38
|
+
u.name = "A User"
|
39
|
+
u.password = "123456"
|
40
|
+
u.state = "active"
|
41
|
+
end
|
24
42
|
|
25
|
-
# a simple list of attributes
|
26
|
-
model_template_for User, :name => "Bob"
|
27
43
|
|
28
|
-
|
29
|
-
model_template_for User do
|
30
|
-
{ :name => "Bob", :address => addresses(:default) }
|
31
|
-
end
|
44
|
+
# from test/factories/user.rb
|
32
45
|
|
46
|
+
factory :user, User do |u|
|
47
|
+
u.account = use :account
|
48
|
+
u.email = Faker::Internet.email
|
49
|
+
u.name = Faker::Name.name
|
50
|
+
u.password = Faker::Lorem.words(1).first
|
33
51
|
end
|
34
52
|
|
35
|
-
|
53
|
+
To get a reference to a fixture, the <tt>use</tt> method is added to your
|
54
|
+
test class:
|
55
|
+
|
56
|
+
def test_something
|
57
|
+
refute_equal use(:artist).name, use("artist/child").name
|
58
|
+
end
|
36
59
|
|
37
|
-
|
38
|
-
|
39
|
-
* <tt>def new_user(extras = {})</tt>
|
40
|
-
* <tt>def new_user_without(*excluded)</tt>
|
41
|
-
* <tt>def create_user(extras = {})</tt>
|
42
|
-
* <tt>def create_user!(extras = {})</tt>
|
43
|
-
* <tt>def create_user_without(*excluded)</tt>
|
44
|
-
* <tt>def create_user_without!(*excluded)</tt>
|
60
|
+
To get an instance from a factory, the <tt>build</tt> and <tt>create</tt> methods
|
61
|
+
are available:
|
45
62
|
|
46
|
-
|
63
|
+
def test_something_else
|
64
|
+
assert_equal "foo", build(:artist, name: "foo").name
|
65
|
+
refute create(:artist).new_record?
|
66
|
+
end
|
47
67
|
|
48
68
|
=== Custom Assertions
|
49
69
|
|
50
|
-
|
70
|
+
If you require <tt>"modelizer/all"</tt> or include
|
71
|
+
<tt>Modelizer::Assertions</tt>, Modelizer adds one additional
|
72
|
+
assertion, <tt>assert_invalid</tt>.
|
51
73
|
|
52
74
|
assert_invalid :email, model, /is bad/
|
53
75
|
|
54
76
|
The third argument is optional.
|
55
77
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
def test_pointless_stuff
|
62
|
-
assert new_user.valid?
|
63
|
-
assert_invalid :name, new_user_without(:name)
|
64
|
-
|
65
|
-
assert !create_user.new_record?
|
78
|
+
def test_pointless_stuff
|
79
|
+
assert new_user.valid?
|
80
|
+
assert_invalid :name, build(:artist, name: nil)
|
81
|
+
end
|
66
82
|
|
67
|
-
|
68
|
-
create_user_without! :name
|
69
|
-
end
|
83
|
+
=== Testing Validations
|
70
84
|
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
85
|
+
I should really write some docs for this.
|
74
86
|
|
75
87
|
== Installation
|
76
88
|
|
data/Rakefile
CHANGED
data/lib/modelizer.rb
CHANGED
@@ -1,138 +1,102 @@
|
|
1
|
-
require "
|
2
|
-
require "modelizer/validations"
|
1
|
+
require "zlib"
|
3
2
|
|
4
3
|
module Modelizer
|
5
4
|
|
6
|
-
|
7
|
-
VERSION = "4.0.0"
|
5
|
+
VERSION = "5.0.0"
|
8
6
|
|
9
|
-
|
7
|
+
def build name, overrides = nil, &block
|
8
|
+
model, *initializers = Modelizer.factories[name]
|
9
|
+
raise "Can't find the \"#{name}\" factory." unless model
|
10
10
|
|
11
|
-
|
12
|
-
# tests for a model template.
|
11
|
+
obj = model.new
|
13
12
|
|
14
|
-
|
13
|
+
initializers << block if block_given?
|
14
|
+
initializers.each { |i| instance_exec obj, &i }
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
overrides.each { |k, v| obj.send "#{k}=", v } if overrides
|
17
|
+
|
18
|
+
obj
|
19
|
+
end
|
20
|
+
|
21
|
+
def create name, overrides = nil, &block
|
22
|
+
obj = build name, overrides, &block
|
23
|
+
|
24
|
+
obj.save!
|
18
25
|
|
19
|
-
|
20
|
-
k.split("::").inject(Object) { |a, b| a.const_get b } rescue nil
|
26
|
+
obj
|
21
27
|
end
|
22
28
|
|
23
|
-
|
24
|
-
|
29
|
+
def use name
|
30
|
+
model, id = Modelizer.ids[name]
|
31
|
+
raise "Can't find the \"#{name}\" fixture." unless model
|
25
32
|
|
26
|
-
|
27
|
-
target.extend ClassMethods
|
28
|
-
target.extend Modelizer::Validations
|
33
|
+
model.find id
|
29
34
|
end
|
30
35
|
|
31
|
-
|
32
|
-
|
36
|
+
class Context < Struct.new(:instances)
|
37
|
+
def identify name
|
38
|
+
Modelizer.identify name
|
39
|
+
end
|
40
|
+
|
41
|
+
def use name
|
42
|
+
instances[name] or raise "Can't find the \"#{name}\" fixture."
|
43
|
+
end
|
33
44
|
end
|
34
45
|
|
35
|
-
def self.
|
36
|
-
|
46
|
+
def self.included klass
|
47
|
+
Dir[glob].sort.each { |f| instance_eval File.read(f), f, 1 }
|
48
|
+
|
49
|
+
instances = {}
|
50
|
+
context = Context.new instances
|
51
|
+
|
52
|
+
fixtures.each do |name, value|
|
53
|
+
instances[name] = value.first.new
|
54
|
+
end
|
55
|
+
|
56
|
+
instances.each do |name, obj|
|
57
|
+
_, *initializers = fixtures[name]
|
58
|
+
initializers.each { |i| context.instance_exec obj, &i }
|
59
|
+
|
60
|
+
obj.id = identify name
|
61
|
+
ids[name] = [obj.class, obj.id]
|
62
|
+
end
|
63
|
+
|
64
|
+
ActiveRecord::Base.transaction do
|
65
|
+
instances.each { |_, obj| obj.save! }
|
66
|
+
end
|
37
67
|
end
|
38
68
|
|
39
|
-
|
40
|
-
|
41
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
42
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
43
|
-
tr("-", "_").
|
44
|
-
downcase
|
69
|
+
class << self
|
70
|
+
attr_accessor :glob
|
45
71
|
end
|
46
72
|
|
47
|
-
|
48
|
-
|
49
|
-
|
73
|
+
self.glob = "test/{factories,fixtures}/**/*.rb"
|
74
|
+
|
75
|
+
def self.cache
|
76
|
+
@cache ||= {}
|
50
77
|
end
|
51
78
|
|
52
|
-
def
|
53
|
-
|
54
|
-
lazy = block && instance_eval(&block)
|
55
|
-
[defaults, lazy, extras].compact.inject { |t, s| t.merge s }
|
79
|
+
def self.factory name, model, &initializer
|
80
|
+
factories[name] = [model, initializer]
|
56
81
|
end
|
57
82
|
|
58
|
-
def
|
59
|
-
|
60
|
-
excluded.include? k
|
61
|
-
end
|
83
|
+
def self.factories
|
84
|
+
@factories ||= {}
|
62
85
|
end
|
63
86
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
def valid_#{model}_attributes_without *excluded
|
81
|
-
valid_model_template_attributes_without #{klass}, excluded
|
82
|
-
end
|
83
|
-
|
84
|
-
def new_#{model} extras = {}
|
85
|
-
assign_model_template_attributes #{klass}.new,
|
86
|
-
valid_model_template_attributes(#{klass}, extras)
|
87
|
-
end
|
88
|
-
|
89
|
-
def new_#{model}_without *excluded
|
90
|
-
assign_model_template_attributes #{klass}.new,
|
91
|
-
valid_model_template_attributes_without(#{klass}, excluded)
|
92
|
-
end
|
93
|
-
|
94
|
-
def create_#{model} extras = {}
|
95
|
-
(m = new_#{model}(extras)).save; m
|
96
|
-
end
|
97
|
-
|
98
|
-
def create_#{model}! extras = {}
|
99
|
-
(m = new_#{model}(extras)).save!; m
|
100
|
-
end
|
101
|
-
|
102
|
-
def create_#{model}_without *excluded
|
103
|
-
(m = new_#{model}_without(*excluded)).save; m
|
104
|
-
end
|
105
|
-
|
106
|
-
def create_#{model}_without! *excluded
|
107
|
-
(m = new_#{model}_without(*excluded)).save!; m
|
108
|
-
end
|
109
|
-
END
|
110
|
-
|
111
|
-
# Install a test that ensures the model template is valid. If
|
112
|
-
# the template is defined in one of the abstract test
|
113
|
-
# superclasses, generate a whole new testcase. If it's in a
|
114
|
-
# concrete test, just generate a method.
|
115
|
-
|
116
|
-
file, line = caller.first.split ":"
|
117
|
-
line = line.to_i
|
118
|
-
|
119
|
-
test = <<-END
|
120
|
-
def test_model_template_for_#{model}
|
121
|
-
assert (m = new_#{model}).valid?,
|
122
|
-
"#{klass} template is invalid: " +
|
123
|
-
m.errors.full_messages.to_sentence
|
124
|
-
end
|
125
|
-
END
|
126
|
-
|
127
|
-
if TEST_CLASSES.include? self
|
128
|
-
eval <<-END, nil, file, line - 2
|
129
|
-
class ::ModelTemplateFor#{klass}Test < ActiveSupport::TestCase
|
130
|
-
#{test}
|
131
|
-
end
|
132
|
-
END
|
133
|
-
else
|
134
|
-
module_eval test, file, line - 1
|
135
|
-
end
|
136
|
-
end
|
87
|
+
def self.fixture name, model, &initializer
|
88
|
+
fixtures[name] = [model, initializer]
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.fixtures
|
92
|
+
@fixtures ||= {}
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.identify name
|
96
|
+
Zlib.crc32(name.to_s) % (2 ** 30 - 1)
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.ids
|
100
|
+
@ids ||= {}
|
137
101
|
end
|
138
102
|
end
|
data/lib/modelizer/assertions.rb
CHANGED
@@ -1,36 +1,23 @@
|
|
1
1
|
module Modelizer
|
2
2
|
module Validations
|
3
|
-
def
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
unless instance_methods.collect { |m| m.to_s }.include? "new_#{@model}"
|
8
|
-
raise "no model template for #{@klass.name}"
|
9
|
-
end
|
10
|
-
|
11
|
-
# FIX: location in original test file
|
12
|
-
|
13
|
-
validations.each do |v|
|
14
|
-
test = send "validation_lambda_for_#{v}", @klass, @model, attribute
|
15
|
-
define_method "test_#{attribute}_#{v}", &test
|
3
|
+
def test_presence_for plan, attribute
|
4
|
+
define_method "test_#{attribute}_presence" do
|
5
|
+
bad = build plan, attribute => nil
|
6
|
+
assert_invalid attribute, bad
|
16
7
|
end
|
17
8
|
end
|
18
9
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
assert_invalid attribute,
|
10
|
+
def test_uniqueness_for plan, attribute
|
11
|
+
define_method "test_#{attribute}_uniqueness" do
|
12
|
+
good = create plan
|
13
|
+
bad = build(plan) { |o| o.send("#{attribute}=", good.send(attribute)) }
|
14
|
+
assert_invalid attribute, bad
|
24
15
|
end
|
25
16
|
end
|
26
17
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
assert existing, "There's at least one #{model} fixture."
|
31
|
-
|
32
|
-
assert_invalid attribute,
|
33
|
-
send("new_#{model}", attribute => existing.send(attribute))
|
18
|
+
def test_validations_for plan, attribute, *validations
|
19
|
+
validations.each do |validation|
|
20
|
+
send "test_#{validation}_for", plan, attribute
|
34
21
|
end
|
35
22
|
end
|
36
23
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: modelizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,23 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
13
|
-
default_executable:
|
12
|
+
date: 2011-09-11 00:00:00.000000000Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: hoe
|
17
|
-
requirement: &
|
16
|
+
requirement: &70235549949760 !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
18
|
requirements:
|
20
|
-
- -
|
19
|
+
- - ~>
|
21
20
|
- !ruby/object:Gem::Version
|
22
|
-
version: 2.
|
21
|
+
version: '2.12'
|
23
22
|
type: :development
|
24
23
|
prerelease: false
|
25
|
-
version_requirements: *
|
24
|
+
version_requirements: *70235549949760
|
26
25
|
description: ! 'Need a simple, consistent way to create model instances and check
|
27
26
|
|
28
|
-
validations in your ActiveRecord 3.1+ tests? Use the Modelizer.
|
27
|
+
validations in your ActiveRecord 3.1+ tests? Use the Modelizer. Just
|
28
|
+
|
29
|
+
don''t trust the docs, since lots changed in 5.x and I got lazy.'
|
29
30
|
email:
|
30
31
|
- code@jbarnette.com
|
31
32
|
executables: []
|
@@ -41,12 +42,11 @@ files:
|
|
41
42
|
- README.rdoc
|
42
43
|
- Rakefile
|
43
44
|
- lib/modelizer.rb
|
45
|
+
- lib/modelizer/all.rb
|
44
46
|
- lib/modelizer/assertions.rb
|
45
47
|
- lib/modelizer/validations.rb
|
46
48
|
- test/test_assertions.rb
|
47
|
-
- test/test_modelizer.rb
|
48
49
|
- .gemtest
|
49
|
-
has_rdoc: true
|
50
50
|
homepage: http://github.com/jbarnette/modelizer
|
51
51
|
licenses: []
|
52
52
|
post_install_message:
|
@@ -60,7 +60,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
60
60
|
requirements:
|
61
61
|
- - ! '>='
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
63
|
+
version: 1.9.2
|
64
64
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
@@ -69,11 +69,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
69
|
version: '0'
|
70
70
|
requirements: []
|
71
71
|
rubyforge_project: modelizer
|
72
|
-
rubygems_version: 1.
|
72
|
+
rubygems_version: 1.8.7
|
73
73
|
signing_key:
|
74
74
|
specification_version: 3
|
75
75
|
summary: Need a simple, consistent way to create model instances and check validations
|
76
|
-
in your ActiveRecord 3.1+ tests? Use the Modelizer
|
76
|
+
in your ActiveRecord 3.1+ tests? Use the Modelizer
|
77
77
|
test_files:
|
78
78
|
- test/test_assertions.rb
|
79
|
-
- test/test_modelizer.rb
|
data/test/test_modelizer.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require "minitest/autorun"
|
2
|
-
require "modelizer"
|
3
|
-
|
4
|
-
class TestModelizer < MiniTest::Unit::TestCase
|
5
|
-
def setup
|
6
|
-
@klass = Class.new
|
7
|
-
@klass.send :include, Modelizer
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_adds_model_template_for_class_method
|
11
|
-
assert_includes @klass.singleton_methods.collect { |m| m.to_s },
|
12
|
-
"model_template_for"
|
13
|
-
end
|
14
|
-
end
|