whiteprint 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,70 @@
1
+ require 'test_helper'
2
+
3
+ if ActiveSupport::TestCase.respond_to?(:test_order=)
4
+ # TODO: remove check once ActiveSupport dependency is at least 4.2
5
+ ActiveSupport::TestCase.test_order = :random
6
+ end
7
+
8
+ class MigratorTest < ActiveSupport::TestCase
9
+ def setup
10
+ Whiteprint.config do |c|
11
+ c.eager_load = true
12
+ c.eager_load_paths += ['models/**/*.rb']
13
+ c.migration_path = File.expand_path('../../db/migrate', __FILE__)
14
+ end
15
+ end
16
+
17
+ test 'models can be eager loaded by whiteprint' do
18
+ Object.send :remove_const, :Car
19
+ Object.send :remove_const, :User
20
+
21
+ Whiteprint.models = []
22
+
23
+ assert_raises(NameError) { Car }
24
+ assert_raises(NameError) { User }
25
+
26
+ Whiteprint::Migrator.eager_load!
27
+
28
+ assert_includes Whiteprint.models, Car
29
+ assert_includes Whiteprint.models, User
30
+ end
31
+
32
+ test 'whiteprint can write all changes to migration' do
33
+ expected_migration = <<-RUBY
34
+ class TestMigration < ActiveRecord::Migration
35
+ def change
36
+ create_table :cars do |t|
37
+ t.string :brand, {:default=>"BMW"}
38
+ t.decimal :price, {:precision=>5, :scale=>10}
39
+ t.timestamps
40
+ end
41
+
42
+ change_table :users do |t|
43
+ t.change :name, :string, {:default=>"Joe"}
44
+ t.change :age, :integer, {:default=>10}
45
+ t.remove :date_of_birth
46
+ end
47
+ end
48
+ end
49
+ RUBY
50
+
51
+ input = StringIO.new
52
+ input << '1' << "\n"
53
+ input.rewind
54
+
55
+ migrate_input = StringIO.new
56
+ migrate_input << 'test migration' << "\n"
57
+ migrate_input.rewind
58
+
59
+ Whiteprint::Migrator.interactive input: input, migrate_input: migrate_input
60
+
61
+ migration = File.read(Dir.glob('test/db/migrate/*_test_migration.rb').first)
62
+
63
+ assert_equal expected_migration, migration
64
+ end
65
+
66
+ def teardown
67
+ path = Dir.glob('test/db/migrate/*_test_migration.rb').first
68
+ File.delete(path) if path
69
+ end
70
+ end
@@ -0,0 +1,8 @@
1
+ class Car < ActiveRecord::Base
2
+ has_whiteprint
3
+
4
+ whiteprint do
5
+ string :brand, default: 'BMW'
6
+ decimal :price, precision: 5, scale: 10
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ class User < ActiveRecord::Base
2
+ include Whiteprint::Model
3
+
4
+ whiteprint do
5
+ string :name, default: 'Joe'
6
+ integer :age, default: 10
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ ActiveRecord::Schema.define do
2
+ self.verbose = false
3
+
4
+ create_table :users, force: true do |t|
5
+ t.string :name, default: 'John'
6
+ t.integer :age, default: 0
7
+ t.date :date_of_birth
8
+
9
+ t.timestamps null: true
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ # $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ # require 'minitest/autorun'
4
+ require 'simplecov'
5
+ require 'bundler/setup'
6
+ require 'active_support'
7
+ require 'active_support/testing/autorun'
8
+
9
+ require 'active_record'
10
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
11
+ require 'schema'
12
+
13
+ require 'whiteprint'
14
+
15
+ require 'models/user'
16
+ require 'models/car'
17
+
18
+ if ActiveSupport::TestCase.respond_to?(:test_order=)
19
+ # TODO: remove check once ActiveSupport dependency is at least 4.2
20
+ ActiveSupport::TestCase.test_order = :random
21
+ end
@@ -0,0 +1,142 @@
1
+ module ActiveSupport
2
+ # A typical module looks like this:
3
+ #
4
+ # module M
5
+ # def self.included(base)
6
+ # base.extend ClassMethods
7
+ # base.class_eval do
8
+ # scope :disabled, -> { where(disabled: true) }
9
+ # end
10
+ # end
11
+ #
12
+ # module ClassMethods
13
+ # ...
14
+ # end
15
+ # end
16
+ #
17
+ # By using <tt>ActiveSupport::Concern</tt> the above module could instead be
18
+ # written as:
19
+ #
20
+ # require 'active_support/concern'
21
+ #
22
+ # module M
23
+ # extend ActiveSupport::Concern
24
+ #
25
+ # included do
26
+ # scope :disabled, -> { where(disabled: true) }
27
+ # end
28
+ #
29
+ # class_methods do
30
+ # ...
31
+ # end
32
+ # end
33
+ #
34
+ # Moreover, it gracefully handles module dependencies. Given a +Foo+ module
35
+ # and a +Bar+ module which depends on the former, we would typically write the
36
+ # following:
37
+ #
38
+ # module Foo
39
+ # def self.included(base)
40
+ # base.class_eval do
41
+ # def self.method_injected_by_foo
42
+ # ...
43
+ # end
44
+ # end
45
+ # end
46
+ # end
47
+ #
48
+ # module Bar
49
+ # def self.included(base)
50
+ # base.method_injected_by_foo
51
+ # end
52
+ # end
53
+ #
54
+ # class Host
55
+ # include Foo # We need to include this dependency for Bar
56
+ # include Bar # Bar is the module that Host really needs
57
+ # end
58
+ #
59
+ # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We
60
+ # could try to hide these from +Host+ directly including +Foo+ in +Bar+:
61
+ #
62
+ # module Bar
63
+ # include Foo
64
+ # def self.included(base)
65
+ # base.method_injected_by_foo
66
+ # end
67
+ # end
68
+ #
69
+ # class Host
70
+ # include Bar
71
+ # end
72
+ #
73
+ # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
74
+ # is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
75
+ # module dependencies are properly resolved:
76
+ #
77
+ # require 'active_support/concern'
78
+ #
79
+ # module Foo
80
+ # extend ActiveSupport::Concern
81
+ # included do
82
+ # def self.method_injected_by_foo
83
+ # ...
84
+ # end
85
+ # end
86
+ # end
87
+ #
88
+ # module Bar
89
+ # extend ActiveSupport::Concern
90
+ # include Foo
91
+ #
92
+ # included do
93
+ # self.method_injected_by_foo
94
+ # end
95
+ # end
96
+ #
97
+ # class Host
98
+ # include Bar # It works, now Bar takes care of its dependencies
99
+ # end
100
+ module Concern
101
+ class MultipleIncludedBlocks < StandardError #:nodoc:
102
+ def initialize
103
+ super "Cannot define multiple 'included' blocks for a Concern"
104
+ end
105
+ end
106
+
107
+ def self.extended(base) #:nodoc:
108
+ base.instance_variable_set(:@_dependencies, [])
109
+ end
110
+
111
+ def append_features(base)
112
+ if base.instance_variable_defined?(:@_dependencies)
113
+ base.instance_variable_get(:@_dependencies) << self
114
+ return false
115
+ else
116
+ return false if base < self
117
+ @_dependencies.each { |dep| base.send(:include, dep) }
118
+ super
119
+ base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods)
120
+ base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block)
121
+ end
122
+ end
123
+
124
+ def included(base = nil, &block)
125
+ if base.nil?
126
+ raise MultipleIncludedBlocks if instance_variable_defined?(:@_included_block)
127
+
128
+ @_included_block = block
129
+ else
130
+ super
131
+ end
132
+ end
133
+
134
+ def class_methods(&class_methods_module_definition)
135
+ mod = const_defined?(:ClassMethods, false) ?
136
+ const_get(:ClassMethods) :
137
+ const_set(:ClassMethods, Module.new)
138
+
139
+ mod.module_eval(&class_methods_module_definition)
140
+ end
141
+ end
142
+ end
metadata ADDED
@@ -0,0 +1,270 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: whiteprint
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ewout Kleinsmann
8
+ - Roland Boon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-09-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: parslet
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.7'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.7'
28
+ - !ruby/object:Gem::Dependency
29
+ name: terminal-table
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.4'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.4'
42
+ - !ruby/object:Gem::Dependency
43
+ name: highline
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.7'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.7'
56
+ - !ruby/object:Gem::Dependency
57
+ name: bundler
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '1.9'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.9'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rake
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '10.0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '10.0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: activesupport
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '4.2'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '4.2'
98
+ - !ruby/object:Gem::Dependency
99
+ name: activerecord
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '4.2'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '4.2'
112
+ - !ruby/object:Gem::Dependency
113
+ name: sqlite3
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: flay
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: flog
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: brakeman
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ - !ruby/object:Gem::Dependency
169
+ name: rubocop
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ type: :development
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ - !ruby/object:Gem::Dependency
183
+ name: simplecov
184
+ requirement: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ type: :development
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ description: |2
197
+ Whiteprint allows you to define attributes within your models. This definition allows for
198
+ automatic migration generation. You can also use whiteprint for inheritance and composition
199
+ of your model's attributes.
200
+ email: info@10kb.nl
201
+ executables: []
202
+ extensions: []
203
+ extra_rdoc_files: []
204
+ files:
205
+ - README.md
206
+ - Rakefile
207
+ - lib/tasks/blueprint.rake
208
+ - lib/whiteprint.rb
209
+ - lib/whiteprint/adapters/active_record.rb
210
+ - lib/whiteprint/adapters/active_record/has_and_belongs_to_many.rb
211
+ - lib/whiteprint/adapters/active_record/migration.rb
212
+ - lib/whiteprint/adapters/test.rb
213
+ - lib/whiteprint/attributes.rb
214
+ - lib/whiteprint/base.rb
215
+ - lib/whiteprint/config.rb
216
+ - lib/whiteprint/explanation.rb
217
+ - lib/whiteprint/has_whiteprint.rb
218
+ - lib/whiteprint/migrator.rb
219
+ - lib/whiteprint/model.rb
220
+ - lib/whiteprint/railtie.rb
221
+ - lib/whiteprint/transform.rb
222
+ - lib/whiteprint/version.rb
223
+ - test/cases/active_record_test.rb
224
+ - test/cases/attributes_test.rb
225
+ - test/cases/blueprint_test.rb
226
+ - test/cases/changes_tree_test.rb
227
+ - test/cases/explanation_test.rb
228
+ - test/cases/migrator_test.rb
229
+ - test/models/car.rb
230
+ - test/models/user.rb
231
+ - test/schema.rb
232
+ - test/test_helper.rb
233
+ - vendor/active_support/concern.rb
234
+ homepage: http://10kb.nl/
235
+ licenses:
236
+ - MIT
237
+ metadata: {}
238
+ post_install_message:
239
+ rdoc_options: []
240
+ require_paths:
241
+ - lib
242
+ - vendor
243
+ required_ruby_version: !ruby/object:Gem::Requirement
244
+ requirements:
245
+ - - ">="
246
+ - !ruby/object:Gem::Version
247
+ version: '0'
248
+ required_rubygems_version: !ruby/object:Gem::Requirement
249
+ requirements:
250
+ - - ">="
251
+ - !ruby/object:Gem::Version
252
+ version: '0'
253
+ requirements: []
254
+ rubyforge_project:
255
+ rubygems_version: 2.4.5
256
+ signing_key:
257
+ specification_version: 4
258
+ summary: Define attributes within models for automatic migration generators, schema
259
+ composition and more
260
+ test_files:
261
+ - test/cases/attributes_test.rb
262
+ - test/cases/blueprint_test.rb
263
+ - test/cases/explanation_test.rb
264
+ - test/cases/active_record_test.rb
265
+ - test/cases/migrator_test.rb
266
+ - test/cases/changes_tree_test.rb
267
+ - test/test_helper.rb
268
+ - test/models/user.rb
269
+ - test/models/car.rb
270
+ - test/schema.rb