machinist_redux 3.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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +17 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/.rubocop.yml +60 -0
- data/.rubocop_todo.yml +92 -0
- data/.travis.yml +23 -0
- data/Appraisals +11 -0
- data/Gemfile +32 -0
- data/LICENSE.txt +21 -0
- data/README.md +307 -0
- data/Rakefile +20 -0
- data/gemfiles/rails_4.2.gemfile +38 -0
- data/gemfiles/rails_4.2.gemfile.lock +232 -0
- data/gemfiles/rails_5.0.gemfile +38 -0
- data/gemfiles/rails_5.0.gemfile.lock +232 -0
- data/gemfiles/rails_5.1.gemfile +34 -0
- data/gemfiles/rails_5.1.gemfile.lock +231 -0
- data/lib/generators/machinist/install/USAGE +2 -0
- data/lib/generators/machinist/install/install_generator.rb +46 -0
- data/lib/generators/machinist/install/templates/blueprints.rb +9 -0
- data/lib/generators/machinist/install/templates/machinist.rb.erb +7 -0
- data/lib/generators/machinist/model/model_generator.rb +11 -0
- data/lib/machinist.rb +5 -0
- data/lib/machinist/active_record.rb +14 -0
- data/lib/machinist/active_record/blueprint.rb +14 -0
- data/lib/machinist/active_record/lathe.rb +21 -0
- data/lib/machinist/blueprint.rb +84 -0
- data/lib/machinist/exceptions.rb +30 -0
- data/lib/machinist/lathe.rb +65 -0
- data/lib/machinist/machinable.rb +100 -0
- data/lib/machinist/version.rb +3 -0
- data/machinist.gemspec +23 -0
- data/spec/machinist/active_record_spec.rb +106 -0
- data/spec/machinist/blueprint_inheritance_spec.rb +101 -0
- data/spec/machinist/blueprint_spec.rb +76 -0
- data/spec/machinist/exceptions_spec.rb +16 -0
- data/spec/machinist/machinable_spec.rb +91 -0
- data/spec/spec_helper.rb +110 -0
- data/spec/support/active_record_environment.rb +62 -0
- metadata +94 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "http://rubygems.org"
|
4
|
+
|
5
|
+
ruby RUBY_VERSION
|
6
|
+
|
7
|
+
gem "activerecord", "~> 5.1.1", group: :test, require: false
|
8
|
+
|
9
|
+
group :development do
|
10
|
+
gem 'appraisal', require: false
|
11
|
+
gem 'gem-release', require: false
|
12
|
+
gem 'github_changelog_generator', require: false
|
13
|
+
gem 'guard', require: false
|
14
|
+
gem 'guard-rspec', require: false
|
15
|
+
gem 'guard-rubocop', require: false
|
16
|
+
gem 'guard-rubycritic', require: false
|
17
|
+
gem 'rdoc', require: false
|
18
|
+
gem 'rubocop-rspec', require: false
|
19
|
+
end
|
20
|
+
|
21
|
+
group :test do
|
22
|
+
gem "codeclimate-test-reporter", require: false
|
23
|
+
gem "coveralls", require: false
|
24
|
+
gem "fuubar", require: false
|
25
|
+
gem "rspec", require: false
|
26
|
+
gem "rspec_junit_formatter", require: false
|
27
|
+
gem "simplecov", "~> 0.14", require: false
|
28
|
+
end
|
29
|
+
|
30
|
+
platforms :ruby do
|
31
|
+
gem "sqlite3"
|
32
|
+
end
|
33
|
+
|
34
|
+
gemspec path: "../"
|
@@ -0,0 +1,231 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ..
|
3
|
+
specs:
|
4
|
+
machinist_redux (3.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
activemodel (5.1.1)
|
10
|
+
activesupport (= 5.1.1)
|
11
|
+
activerecord (5.1.1)
|
12
|
+
activemodel (= 5.1.1)
|
13
|
+
activesupport (= 5.1.1)
|
14
|
+
arel (~> 8.0)
|
15
|
+
activesupport (5.1.1)
|
16
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
17
|
+
i18n (~> 0.7)
|
18
|
+
minitest (~> 5.1)
|
19
|
+
tzinfo (~> 1.1)
|
20
|
+
addressable (2.5.1)
|
21
|
+
public_suffix (~> 2.0, >= 2.0.2)
|
22
|
+
appraisal (2.2.0)
|
23
|
+
bundler
|
24
|
+
rake
|
25
|
+
thor (>= 0.14.0)
|
26
|
+
arel (8.0.0)
|
27
|
+
ast (2.3.0)
|
28
|
+
axiom-types (0.1.1)
|
29
|
+
descendants_tracker (~> 0.0.4)
|
30
|
+
ice_nine (~> 0.11.0)
|
31
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
32
|
+
builder (3.2.3)
|
33
|
+
codeclimate-engine-rb (0.4.0)
|
34
|
+
virtus (~> 1.0)
|
35
|
+
codeclimate-test-reporter (1.0.7)
|
36
|
+
simplecov
|
37
|
+
coderay (1.1.1)
|
38
|
+
coercible (1.0.0)
|
39
|
+
descendants_tracker (~> 0.0.1)
|
40
|
+
concurrent-ruby (1.0.5)
|
41
|
+
coveralls (0.8.21)
|
42
|
+
json (>= 1.8, < 3)
|
43
|
+
simplecov (~> 0.14.1)
|
44
|
+
term-ansicolor (~> 1.3)
|
45
|
+
thor (~> 0.19.4)
|
46
|
+
tins (~> 1.6)
|
47
|
+
descendants_tracker (0.0.4)
|
48
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
49
|
+
diff-lcs (1.3)
|
50
|
+
docile (1.1.5)
|
51
|
+
equalizer (0.0.11)
|
52
|
+
erubis (2.7.0)
|
53
|
+
faraday (0.12.1)
|
54
|
+
multipart-post (>= 1.2, < 3)
|
55
|
+
faraday-http-cache (2.0.0)
|
56
|
+
faraday (~> 0.8)
|
57
|
+
ffi (1.9.18)
|
58
|
+
flay (2.9.0)
|
59
|
+
erubis (~> 2.7.0)
|
60
|
+
path_expander (~> 1.0)
|
61
|
+
ruby_parser (~> 3.0)
|
62
|
+
sexp_processor (~> 4.0)
|
63
|
+
flog (4.6.1)
|
64
|
+
path_expander (~> 1.0)
|
65
|
+
ruby_parser (~> 3.1, > 3.1.0)
|
66
|
+
sexp_processor (~> 4.8)
|
67
|
+
formatador (0.2.5)
|
68
|
+
fuubar (2.2.0)
|
69
|
+
rspec-core (~> 3.0)
|
70
|
+
ruby-progressbar (~> 1.4)
|
71
|
+
gem-release (1.0.0)
|
72
|
+
github_changelog_generator (1.14.3)
|
73
|
+
activesupport
|
74
|
+
faraday-http-cache
|
75
|
+
multi_json
|
76
|
+
octokit (~> 4.6)
|
77
|
+
rainbow (>= 2.1)
|
78
|
+
rake (>= 10.0)
|
79
|
+
retriable (~> 2.1)
|
80
|
+
guard (2.14.1)
|
81
|
+
formatador (>= 0.2.4)
|
82
|
+
listen (>= 2.7, < 4.0)
|
83
|
+
lumberjack (~> 1.0)
|
84
|
+
nenv (~> 0.1)
|
85
|
+
notiffany (~> 0.0)
|
86
|
+
pry (>= 0.9.12)
|
87
|
+
shellany (~> 0.0)
|
88
|
+
thor (>= 0.18.1)
|
89
|
+
guard-compat (1.2.1)
|
90
|
+
guard-rspec (4.7.3)
|
91
|
+
guard (~> 2.1)
|
92
|
+
guard-compat (~> 1.1)
|
93
|
+
rspec (>= 2.99.0, < 4.0)
|
94
|
+
guard-rubocop (1.2.0)
|
95
|
+
guard (~> 2.0)
|
96
|
+
rubocop (~> 0.20)
|
97
|
+
guard-rubycritic (2.9.3)
|
98
|
+
guard (~> 2.6)
|
99
|
+
rubycritic (>= 2.9.3)
|
100
|
+
i18n (0.8.1)
|
101
|
+
ice_nine (0.11.2)
|
102
|
+
json (2.1.0)
|
103
|
+
launchy (2.4.3)
|
104
|
+
addressable (~> 2.3)
|
105
|
+
listen (3.1.5)
|
106
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
107
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
108
|
+
ruby_dep (~> 1.2)
|
109
|
+
lumberjack (1.0.12)
|
110
|
+
method_source (0.8.2)
|
111
|
+
minitest (5.10.2)
|
112
|
+
multi_json (1.12.1)
|
113
|
+
multipart-post (2.0.0)
|
114
|
+
nenv (0.3.0)
|
115
|
+
notiffany (0.1.1)
|
116
|
+
nenv (~> 0.1)
|
117
|
+
shellany (~> 0.0)
|
118
|
+
octokit (4.7.0)
|
119
|
+
sawyer (~> 0.8.0, >= 0.5.3)
|
120
|
+
parser (2.4.0.0)
|
121
|
+
ast (~> 2.2)
|
122
|
+
path_expander (1.0.2)
|
123
|
+
powerpack (0.1.1)
|
124
|
+
pry (0.10.4)
|
125
|
+
coderay (~> 1.1.0)
|
126
|
+
method_source (~> 0.8.1)
|
127
|
+
slop (~> 3.4)
|
128
|
+
public_suffix (2.0.5)
|
129
|
+
rainbow (2.2.2)
|
130
|
+
rake
|
131
|
+
rake (12.0.0)
|
132
|
+
rb-fsevent (0.9.8)
|
133
|
+
rb-inotify (0.9.8)
|
134
|
+
ffi (>= 0.5.0)
|
135
|
+
rdoc (5.1.0)
|
136
|
+
reek (4.6.2)
|
137
|
+
codeclimate-engine-rb (~> 0.4.0)
|
138
|
+
parser (>= 2.4.0.0, < 2.5)
|
139
|
+
rainbow (~> 2.0)
|
140
|
+
retriable (2.1.0)
|
141
|
+
rspec (3.6.0)
|
142
|
+
rspec-core (~> 3.6.0)
|
143
|
+
rspec-expectations (~> 3.6.0)
|
144
|
+
rspec-mocks (~> 3.6.0)
|
145
|
+
rspec-core (3.6.0)
|
146
|
+
rspec-support (~> 3.6.0)
|
147
|
+
rspec-expectations (3.6.0)
|
148
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
149
|
+
rspec-support (~> 3.6.0)
|
150
|
+
rspec-mocks (3.6.0)
|
151
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
152
|
+
rspec-support (~> 3.6.0)
|
153
|
+
rspec-support (3.6.0)
|
154
|
+
rspec_junit_formatter (0.2.3)
|
155
|
+
builder (< 4)
|
156
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
157
|
+
rubocop (0.48.1)
|
158
|
+
parser (>= 2.3.3.1, < 3.0)
|
159
|
+
powerpack (~> 0.1)
|
160
|
+
rainbow (>= 1.99.1, < 3.0)
|
161
|
+
ruby-progressbar (~> 1.7)
|
162
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
163
|
+
rubocop-rspec (1.15.1)
|
164
|
+
rubocop (>= 0.42.0)
|
165
|
+
ruby-progressbar (1.8.1)
|
166
|
+
ruby_dep (1.5.0)
|
167
|
+
ruby_parser (3.9.0)
|
168
|
+
sexp_processor (~> 4.1)
|
169
|
+
rubycritic (3.2.1)
|
170
|
+
flay (~> 2.8)
|
171
|
+
flog (~> 4.4)
|
172
|
+
launchy (= 2.4.3)
|
173
|
+
parser (= 2.4.0)
|
174
|
+
rainbow (~> 2.1)
|
175
|
+
reek (~> 4.4)
|
176
|
+
ruby_parser (~> 3.8)
|
177
|
+
virtus (~> 1.0)
|
178
|
+
sawyer (0.8.1)
|
179
|
+
addressable (>= 2.3.5, < 2.6)
|
180
|
+
faraday (~> 0.8, < 1.0)
|
181
|
+
sexp_processor (4.9.0)
|
182
|
+
shellany (0.0.1)
|
183
|
+
simplecov (0.14.1)
|
184
|
+
docile (~> 1.1.0)
|
185
|
+
json (>= 1.8, < 3)
|
186
|
+
simplecov-html (~> 0.10.0)
|
187
|
+
simplecov-html (0.10.0)
|
188
|
+
slop (3.6.0)
|
189
|
+
sqlite3 (1.3.13)
|
190
|
+
term-ansicolor (1.6.0)
|
191
|
+
tins (~> 1.0)
|
192
|
+
thor (0.19.4)
|
193
|
+
thread_safe (0.3.6)
|
194
|
+
tins (1.14.0)
|
195
|
+
tzinfo (1.2.3)
|
196
|
+
thread_safe (~> 0.1)
|
197
|
+
unicode-display_width (1.2.1)
|
198
|
+
virtus (1.0.5)
|
199
|
+
axiom-types (~> 0.1)
|
200
|
+
coercible (~> 1.0)
|
201
|
+
descendants_tracker (~> 0.0, >= 0.0.3)
|
202
|
+
equalizer (~> 0.0, >= 0.0.9)
|
203
|
+
|
204
|
+
PLATFORMS
|
205
|
+
ruby
|
206
|
+
|
207
|
+
DEPENDENCIES
|
208
|
+
activerecord (~> 5.1.1)
|
209
|
+
appraisal
|
210
|
+
codeclimate-test-reporter
|
211
|
+
coveralls
|
212
|
+
fuubar
|
213
|
+
gem-release
|
214
|
+
github_changelog_generator
|
215
|
+
guard
|
216
|
+
guard-rspec
|
217
|
+
guard-rubocop
|
218
|
+
guard-rubycritic
|
219
|
+
machinist_redux!
|
220
|
+
rdoc
|
221
|
+
rspec
|
222
|
+
rspec_junit_formatter
|
223
|
+
rubocop-rspec
|
224
|
+
simplecov (~> 0.14)
|
225
|
+
sqlite3
|
226
|
+
|
227
|
+
RUBY VERSION
|
228
|
+
ruby 2.3.4p301
|
229
|
+
|
230
|
+
BUNDLED WITH
|
231
|
+
1.14.6
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Machinist
|
2
|
+
module Generators #:nodoc:
|
3
|
+
class InstallGenerator < Rails::Generators::Base #:nodoc:
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
class_option :test_framework, type: :string, aliases: '-t', desc: 'Test framework to use Machinist with'
|
7
|
+
class_option :cucumber, type: :boolean, desc: 'Set up access to Machinist from Cucumber'
|
8
|
+
|
9
|
+
def blueprints_file
|
10
|
+
if rspec?
|
11
|
+
copy_file 'blueprints.rb', 'spec/support/blueprints.rb'
|
12
|
+
else
|
13
|
+
copy_file 'blueprints.rb', 'test/blueprints.rb'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_helper
|
18
|
+
if test_unit?
|
19
|
+
inject_into_file('test/test_helper.rb', after: "require 'rails/test_help'\n") do
|
20
|
+
"require File.expand_path(File.dirname(__FILE__) + '/blueprints')\n"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def cucumber_support
|
26
|
+
if cucumber?
|
27
|
+
template 'machinist.rb.erb', 'features/support/machinist.rb'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def rspec?
|
34
|
+
options[:test_framework].to_sym == :rspec
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_unit?
|
38
|
+
options[:test_framework].to_sym == :test_unit
|
39
|
+
end
|
40
|
+
|
41
|
+
def cucumber?
|
42
|
+
options[:cucumber]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Machinist
|
2
|
+
module Generators #:nodoc:
|
3
|
+
class ModelGenerator < Rails::Generators::NamedBase #:nodoc:
|
4
|
+
argument :attributes, type: :array, default: [], banner: 'field:type field:type'
|
5
|
+
|
6
|
+
def create_blueprint
|
7
|
+
append_file 'spec/support/blueprints.rb', "\n#{class_name}.blueprint do\n # Attributes here\nend\n"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/machinist.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'machinist'
|
3
|
+
require 'machinist/active_record/blueprint'
|
4
|
+
require 'machinist/active_record/lathe'
|
5
|
+
|
6
|
+
module ActiveRecord #:nodoc:
|
7
|
+
class Base #:nodoc:
|
8
|
+
extend Machinist::Machinable
|
9
|
+
|
10
|
+
def self.blueprint_class
|
11
|
+
Machinist::ActiveRecord::Blueprint
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Machinist::ActiveRecord
|
2
|
+
class Blueprint < Machinist::Blueprint
|
3
|
+
# Make and save an object.
|
4
|
+
def make!(attributes = {})
|
5
|
+
object = make(attributes)
|
6
|
+
object.save!
|
7
|
+
object.reload
|
8
|
+
end
|
9
|
+
|
10
|
+
def lathe_class #:nodoc:
|
11
|
+
Machinist::ActiveRecord::Lathe
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Machinist::ActiveRecord
|
2
|
+
class Lathe < Machinist::Lathe
|
3
|
+
def make_one_value(attribute, args) #:nodoc:
|
4
|
+
if block_given?
|
5
|
+
raise_argument_error(attribute) unless args.empty?
|
6
|
+
yield
|
7
|
+
else
|
8
|
+
make_association(attribute, args)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def make_association(attribute, args) #:nodoc:
|
13
|
+
association = @klass.reflect_on_association(attribute)
|
14
|
+
if association
|
15
|
+
association.klass.make(*args)
|
16
|
+
else
|
17
|
+
raise_argument_error(attribute)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Machinist
|
2
|
+
# A Blueprint defines a method of constructing objects of a particular class.
|
3
|
+
class Blueprint
|
4
|
+
# Construct a blueprint for the given +klass+.
|
5
|
+
#
|
6
|
+
# Pass in the +:parent+ option to define a parent blueprint to apply after
|
7
|
+
# this one. You can supply another blueprint, or a class in which to look
|
8
|
+
# for a blueprint. In the latter case, make will walk up the superclass
|
9
|
+
# chain looking for blueprints to apply.
|
10
|
+
def initialize(klass, options = {}, &block)
|
11
|
+
@klass = klass
|
12
|
+
@parent = options[:parent]
|
13
|
+
@block = block
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :klass, :parent, :block
|
17
|
+
|
18
|
+
# Generate an object from this blueprint.
|
19
|
+
#
|
20
|
+
# Pass in attributes to override values defined in the blueprint.
|
21
|
+
def make(attributes = {})
|
22
|
+
lathe = lathe_class.new(@klass, new_serial_number, attributes)
|
23
|
+
|
24
|
+
lathe.instance_eval(&@block)
|
25
|
+
each_ancestor { |blueprint| lathe.instance_eval(&blueprint.block) }
|
26
|
+
|
27
|
+
lathe.object
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the Lathe class used to make objects for this blueprint.
|
31
|
+
#
|
32
|
+
# Subclasses can override this to substitute a custom lathe class.
|
33
|
+
def lathe_class
|
34
|
+
Lathe
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the parent blueprint for this blueprint.
|
38
|
+
def parent_blueprint
|
39
|
+
case @parent
|
40
|
+
when nil
|
41
|
+
nil
|
42
|
+
when Blueprint
|
43
|
+
# @parent references the parent blueprint directly.
|
44
|
+
@parent
|
45
|
+
else
|
46
|
+
# @parent is a class in which we should look for a blueprint.
|
47
|
+
find_blueprint_in_superclass_chain(@parent)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Yields the parent blueprint, its parent blueprint, etc.
|
52
|
+
def each_ancestor
|
53
|
+
ancestor = parent_blueprint
|
54
|
+
while ancestor
|
55
|
+
yield ancestor
|
56
|
+
ancestor = ancestor.parent_blueprint
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
|
62
|
+
def new_serial_number #:nodoc:
|
63
|
+
parent_blueprint = self.parent_blueprint # Cache this for speed.
|
64
|
+
if parent_blueprint
|
65
|
+
parent_blueprint.new_serial_number
|
66
|
+
else
|
67
|
+
@serial_number ||= 0
|
68
|
+
@serial_number += 1
|
69
|
+
sprintf('%04d', @serial_number)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def find_blueprint_in_superclass_chain(klass)
|
76
|
+
klass = klass.superclass until has_blueprint?(klass) || klass.nil?
|
77
|
+
klass && klass.blueprint
|
78
|
+
end
|
79
|
+
|
80
|
+
def has_blueprint?(klass)
|
81
|
+
klass.respond_to?(:blueprint) && !klass.blueprint.nil?
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|