config_scripts 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +2 -0
  4. data/.yardopts +1 -0
  5. data/CHANGELOG.md +17 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +124 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +55 -0
  10. data/Rakefile +1 -0
  11. data/TODO.md +8 -0
  12. data/config_scripts.gemspec +31 -0
  13. data/lib/config_scripts/generators/config_script.rb +24 -0
  14. data/lib/config_scripts/generators/migrations.rb +36 -0
  15. data/lib/config_scripts/generators.rb +2 -0
  16. data/lib/config_scripts/scripts/script.rb +135 -0
  17. data/lib/config_scripts/scripts/script_history.rb +39 -0
  18. data/lib/config_scripts/scripts.rb +9 -0
  19. data/lib/config_scripts/seeds/seed_set.rb +321 -0
  20. data/lib/config_scripts/seeds/seed_type.rb +361 -0
  21. data/lib/config_scripts/seeds.rb +8 -0
  22. data/lib/config_scripts/tasks/pending_migrations.rake +11 -0
  23. data/lib/config_scripts/tasks/seeds.rake +18 -0
  24. data/lib/config_scripts/tasks.rb +12 -0
  25. data/lib/config_scripts/version.rb +4 -0
  26. data/lib/config_scripts.rb +9 -0
  27. data/spec/dummy/README.rdoc +28 -0
  28. data/spec/dummy/Rakefile +6 -0
  29. data/spec/dummy/app/assets/images/.keep +0 -0
  30. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  31. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  32. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  33. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  34. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  35. data/spec/dummy/app/mailers/.keep +0 -0
  36. data/spec/dummy/app/models/.keep +0 -0
  37. data/spec/dummy/app/models/concerns/.keep +0 -0
  38. data/spec/dummy/app/models/hair_color.rb +2 -0
  39. data/spec/dummy/app/models/person.rb +4 -0
  40. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  41. data/spec/dummy/bin/bundle +3 -0
  42. data/spec/dummy/bin/rails +4 -0
  43. data/spec/dummy/bin/rake +4 -0
  44. data/spec/dummy/config/application.rb +23 -0
  45. data/spec/dummy/config/boot.rb +5 -0
  46. data/spec/dummy/config/database.yml +25 -0
  47. data/spec/dummy/config/environment.rb +5 -0
  48. data/spec/dummy/config/environments/development.rb +29 -0
  49. data/spec/dummy/config/environments/production.rb +80 -0
  50. data/spec/dummy/config/environments/test.rb +36 -0
  51. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  52. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  53. data/spec/dummy/config/initializers/inflections.rb +16 -0
  54. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  55. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  56. data/spec/dummy/config/initializers/session_store.rb +3 -0
  57. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  58. data/spec/dummy/config/locales/en.yml +23 -0
  59. data/spec/dummy/config/routes.rb +56 -0
  60. data/spec/dummy/config.ru +4 -0
  61. data/spec/dummy/db/migrate/20140208014550_create_config_scripts.rb +7 -0
  62. data/spec/dummy/db/migrate/20140208161829_create_people.rb +9 -0
  63. data/spec/dummy/db/migrate/20140208182050_create_hair_colors.rb +9 -0
  64. data/spec/dummy/db/migrate/20140208182101_add_hair_color_to_person.rb +6 -0
  65. data/spec/dummy/db/migrate/20140208225801_add_scope_to_people.rb +6 -0
  66. data/spec/dummy/db/migrate/20140209132911_add_hex_value_to_hair_color.rb +5 -0
  67. data/spec/dummy/db/schema.rb +38 -0
  68. data/spec/dummy/lib/assets/.keep +0 -0
  69. data/spec/dummy/log/.keep +0 -0
  70. data/spec/dummy/public/404.html +58 -0
  71. data/spec/dummy/public/422.html +58 -0
  72. data/spec/dummy/public/500.html +57 -0
  73. data/spec/dummy/public/favicon.ico +0 -0
  74. data/spec/generators/config_script_spec.rb +23 -0
  75. data/spec/generators/migrations_spec.rb +23 -0
  76. data/spec/scripts/script_history_spec.rb +53 -0
  77. data/spec/scripts/script_spec.rb +282 -0
  78. data/spec/seeds/seed_set_spec.rb +371 -0
  79. data/spec/seeds/seed_type_spec.rb +439 -0
  80. data/spec/spec_helper.rb +38 -0
  81. data/templates/config_script.rb +9 -0
  82. data/templates/create_config_scripts_migration.rb +7 -0
  83. metadata +321 -0
@@ -0,0 +1,371 @@
1
+ describe ConfigScripts::Seeds::SeedSet do
2
+ let(:klass) { ConfigScripts::Seeds::SeedSet }
3
+ describe "loading" do
4
+ describe "register_seed_set" do
5
+ before do
6
+ klass.clear_registered_sets
7
+ end
8
+
9
+ it "adds the seed set to the class list" do
10
+ seed_set = double(set_number: 1)
11
+ klass.register_seed_set(seed_set)
12
+ expect(klass.registered_sets).to eq 1 => seed_set
13
+ end
14
+
15
+ context "with a duplicate set number" do
16
+ it "increments the number until it has a unique one" do
17
+ seed_set_1 = klass.new 'set_1', 1
18
+ seed_set_2 = klass.new 'set_2', 1
19
+ expect(seed_set_2.set_number).to eq 2
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "load_seed_sets" do
25
+ it "requires all the files in the seed definitions folder" do
26
+ definitions_path = Rails.root.join('db', 'seeds', 'definitions', '*')
27
+ seed_files = ['/tmp/file1', '/tmp/file2']
28
+ Dir.stub(:[]).with(definitions_path).and_return(seed_files)
29
+ klass.stub :require
30
+ klass.load_seed_sets
31
+ expect(Dir).to have_received(:[]).with(definitions_path)
32
+ seed_files.each do |file|
33
+ expect(klass).to have_received(:require).with(file)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "batch operations" do
40
+ let(:seed_sets) { [double, double] }
41
+ before do
42
+ klass.clear_registered_sets
43
+ klass.stub :puts
44
+ seed_sets.each_with_index do |set, index|
45
+ set.stub(
46
+ write: true,
47
+ read: true,
48
+ set_number: (index + 1) * 2,
49
+ name: "Seed Set #{index + 1}",
50
+ reset_records: true
51
+ )
52
+ klass.register_seed_set(set)
53
+ end
54
+ end
55
+
56
+ describe "write" do
57
+ context "with no argument" do
58
+ it "calls the write method on each seed set" do
59
+ klass.write
60
+ seed_sets.each { |set| expect(set).to have_received(:write) }
61
+ end
62
+ end
63
+
64
+ context "with an argument" do
65
+ it "calls the write method on the set whose number is given" do
66
+ klass.write(2)
67
+ expect(seed_sets.first).to have_received(:write)
68
+ expect(seed_sets.last).not_to have_received(:write)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "read" do
74
+ context "with no argument" do
75
+ it "calls the read method on each seed set, telling it not to reset" do
76
+ klass.read
77
+ seed_sets.each { |set| expect(set).to have_received(:read).with(false) }
78
+ end
79
+ end
80
+
81
+ context "with an argument" do
82
+ it "calls the read method on the set whose number is given, telling it to reset" do
83
+ klass.read(4)
84
+ expect(seed_sets.last).to have_received(:read).with(true)
85
+ expect(seed_sets.first).not_to have_received(:read)
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "list" do
91
+ it "prints the set number and name for each seed set" do
92
+ klass.list
93
+ expect(klass).to have_received(:puts).with("2: Seed Set 1")
94
+ expect(klass).to have_received(:puts).with("4: Seed Set 2")
95
+ end
96
+ end
97
+ end
98
+
99
+ describe "instance reading and writing" do
100
+ let(:set) { klass.new('test_seeds', 1, 'my_seeds') }
101
+ let!(:seed_type) { double }
102
+ let(:seed_folder) { Rails.root.join('db', 'seeds', 'data', 'my_seeds') }
103
+
104
+ before do
105
+ FileUtils.stub :mkdir_p
106
+ set.stub :seed_types => {Person: seed_type}
107
+ seed_type.stub write_to_folder: nil, read_from_folder: true
108
+ set.stub :puts
109
+ end
110
+
111
+ describe "write" do
112
+ before do
113
+ set.write
114
+ end
115
+
116
+ it "creates the seed folder" do
117
+ expect(FileUtils).to have_received(:mkdir_p).with(seed_folder)
118
+ end
119
+
120
+ it "writes all of the seed types to the folder" do
121
+ expect(seed_type).to have_received(:write_to_folder).with(seed_folder)
122
+ end
123
+
124
+ it "says where it's writing the seeds to" do
125
+ expect(set).to have_received(:puts).with("Writing seeds for test_seeds to #{seed_folder}")
126
+ end
127
+ end
128
+
129
+ describe "read" do
130
+ before do
131
+ set.stub :reset_records
132
+ end
133
+
134
+ context do
135
+ before do
136
+ set.read
137
+ end
138
+
139
+ it "creates the seed folder" do
140
+ expect(FileUtils).to have_received(:mkdir_p).with(seed_folder)
141
+ end
142
+
143
+ it "says where it's reading the seeds from" do
144
+ expect(set).to have_received(:puts).with("Reading seeds for test_seeds from #{seed_folder}")
145
+ end
146
+
147
+ it "reads all of the seed types from the folder" do
148
+ expect(seed_type).to have_received(:read_from_folder).with(seed_folder)
149
+ end
150
+ end
151
+
152
+ context "when resetting" do
153
+ it "resets the records" do
154
+ set.read(true)
155
+ expect(set).to have_received(:reset_records)
156
+ end
157
+ end
158
+
159
+ context "when not resetting" do
160
+ it "does not reset the records" do
161
+ set.read(false)
162
+ expect(set).not_to have_received(:reset_records)
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ describe "DSL" do
169
+ describe "creation" do
170
+ before do
171
+ klass.clear_registered_sets
172
+ end
173
+
174
+ subject { klass.new('test_seeds', 5, 'my_seeds', setting: 'value') { @val = true } }
175
+
176
+ it "sets the name" do
177
+ expect(subject.name).to eq 'test_seeds'
178
+ end
179
+
180
+ it "sets the set number" do
181
+ expect(subject.set_number).to eq 5
182
+ end
183
+
184
+ it "sets the folder" do
185
+ expect(subject.folder).to eq 'my_seeds'
186
+ end
187
+
188
+ it "sets the options" do
189
+ expect(subject.options).to eq(setting: 'value')
190
+ end
191
+
192
+ it "runs the block on the instance" do
193
+ expect(subject.instance_eval{@val}).to eq true
194
+ end
195
+
196
+ it "gives it an empty hash of seed types" do
197
+ expect(subject.seed_types).to eq({})
198
+ end
199
+
200
+ it "registers the set with the klass" do
201
+ expect(klass.registered_sets[subject.set_number]).to eq subject
202
+ end
203
+ end
204
+
205
+ describe "seeds_for" do
206
+ let(:set) { ConfigScripts::Seeds::SeedSet.new('test_seeds', 1) }
207
+
208
+ subject { set.seeds_for(Person, 'people_seeds') { @val = true } }
209
+
210
+ it "constructs a seed type with the arguments" do
211
+ expect(subject).to be_a ConfigScripts::Seeds::SeedType
212
+ expect(subject.klass).to eq Person
213
+ expect(subject.filename).to eq 'people_seeds'
214
+ expect(subject.instance_eval {@val}).to eq true
215
+ end
216
+
217
+ it "maps the seed type to the class in the seed type list" do
218
+ subject
219
+ expect(set.seed_types[Person]).to eq subject
220
+ end
221
+
222
+ it "has a default filename based on the class name" do
223
+ seeds = set.seeds_for(Person)
224
+ expect(seeds.filename).to eq 'people'
225
+ end
226
+ end
227
+
228
+ describe "when_resetting" do
229
+ let(:set) { ConfigScripts::Seeds::SeedSet.new('test_seeds', 1) }
230
+
231
+ it "sets the reset_block value" do
232
+ value = 0
233
+ set.when_resetting do
234
+ value = 1
235
+ end
236
+ expect(value).to eq 0
237
+ set.reset_records
238
+ expect(value).to eq 1
239
+ end
240
+ end
241
+ end
242
+
243
+ describe "seed identifiers" do
244
+ let(:set) { ConfigScripts::Seeds::SeedSet.new('test_seeds', 1) }
245
+ let(:seed_type) { set.seeds_for(Person) }
246
+ let(:identifier) { double }
247
+
248
+ class AdultPerson < Person
249
+ end
250
+
251
+ describe "seed_identifier_for_record" do
252
+
253
+ subject { set.seed_identifier_for_record(record) }
254
+
255
+ before do
256
+ seed_type.stub :seed_identifier_for_record => identifier
257
+ end
258
+
259
+ context "with a record it has a seed type for" do
260
+ let(:record) { Person.new }
261
+
262
+ it "gets the identifier from the seed types" do
263
+ expect(subject).to eq identifier
264
+ expect(seed_type).to have_received(:seed_identifier_for_record).with(record)
265
+ end
266
+ end
267
+
268
+ context "with a record where it has a seed type for a superclass" do
269
+ let(:record) { AdultPerson.new }
270
+
271
+ it "gets the identifier from the seed types" do
272
+ expect(subject).to eq identifier
273
+ expect(seed_type).to have_received(:seed_identifier_for_record).with(record)
274
+ end
275
+ end
276
+
277
+ context "with a record it does not have a seed type for" do
278
+ let(:record) { ConfigScripts::Scripts::ScriptHistory.new(id: 5) }
279
+
280
+ it "is the record's id" do
281
+ expect(subject).to eq 5
282
+ end
283
+ end
284
+
285
+ context "with a record that is not a subclass of ActiveRecord" do
286
+ let(:record) { "Hello" }
287
+
288
+ it "is nil" do
289
+ expect(subject).to be_nil
290
+ end
291
+ end
292
+ end
293
+
294
+ describe "record_for_seed_identifier" do
295
+ let(:record) { Person.create }
296
+ let(:identifier) { ['red', 'John'] }
297
+ subject { set.record_for_seed_identifier(klass, identifier) }
298
+
299
+ before do
300
+ seed_type.stub :record_for_seed_identifier do |identifier|
301
+ identifier.shift
302
+ identifier.shift
303
+ record
304
+ end
305
+ seed_type.has_identifier_attributes :hair_color, :name
306
+ end
307
+
308
+ context "for a class it has seed types for" do
309
+ let(:klass) { Person }
310
+ it "gets the record from the seed type" do
311
+ expect(subject).to eq record
312
+ expect(seed_type).to have_received(:record_for_seed_identifier).with(identifier)
313
+ end
314
+
315
+ it "caches the result" do
316
+ identifier2 = identifier.dup
317
+ subject
318
+ set.record_for_seed_identifier(klass, identifier2)
319
+ expect(seed_type).to have_received(:record_for_seed_identifier).once
320
+ end
321
+ end
322
+
323
+ context "for a class where it has seed types for a parent class" do
324
+ let(:klass) { AdultPerson }
325
+ it "gets the record from the seed type" do
326
+ expect(subject).to eq record
327
+ expect(seed_type).to have_received(:record_for_seed_identifier).with(identifier)
328
+ end
329
+
330
+ it "caches the result" do
331
+ identifier2 = identifier.dup
332
+ subject
333
+ set.record_for_seed_identifier(klass, identifier2)
334
+ expect(seed_type).to have_received(:record_for_seed_identifier).once
335
+ end
336
+ end
337
+
338
+ context "with an identifier that has more keys than needed" do
339
+ let(:klass) { Person }
340
+ let(:identifier) { ['red', 'John', 'Smith'] }
341
+
342
+ it "only caches it with the keys needed" do
343
+ subject
344
+ set.record_for_seed_identifier(klass, ['red', 'John'])
345
+ expect(seed_type).to have_received(:record_for_seed_identifier).once
346
+ end
347
+
348
+ it "removes the keys it needs from the identifier" do
349
+ subject
350
+ expect(identifier).to eq ['Smith']
351
+ end
352
+
353
+ it "removes the keys it needs even on a cache hit" do
354
+ identifier2 = identifier.dup
355
+ subject
356
+ set.record_for_seed_identifier(klass, identifier2)
357
+ expect(seed_type).to have_received(:record_for_seed_identifier).once
358
+ expect(identifier2).to eq ['Smith']
359
+ end
360
+ end
361
+
362
+ context "for class where it does not have a seed type" do
363
+ let(:klass) { ConfigScripts::Scripts::ScriptHistory }
364
+
365
+ it "is nil" do
366
+ expect(subject).to be_nil
367
+ end
368
+ end
369
+ end
370
+ end
371
+ end