katapult 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.ruby-version +1 -1
  4. data/README.md +61 -35
  5. data/bin/katapult +24 -34
  6. data/features/authenticate.feature +344 -0
  7. data/features/basics.feature +590 -0
  8. data/features/binary.feature +33 -1
  9. data/features/model.feature +9 -13
  10. data/features/step_definitions/rails_steps.rb +3 -2
  11. data/features/wui.feature +49 -4
  12. data/lib/generators/katapult/basics/basics_generator.rb +63 -17
  13. data/lib/generators/katapult/basics/templates/.gitignore +1 -0
  14. data/lib/generators/katapult/basics/templates/.ruby-version +1 -1
  15. data/lib/generators/katapult/basics/templates/Capfile +25 -0
  16. data/lib/generators/katapult/basics/templates/Gemfile +14 -6
  17. data/lib/generators/katapult/basics/templates/Guardfile +44 -0
  18. data/lib/generators/katapult/basics/templates/config/database.sample.yml +3 -2
  19. data/lib/generators/katapult/basics/templates/config/database.yml +3 -2
  20. data/lib/generators/katapult/basics/templates/config/deploy/production.rb +8 -0
  21. data/lib/generators/katapult/basics/templates/config/deploy/staging.rb +7 -0
  22. data/lib/generators/katapult/basics/templates/config/deploy.rb +37 -0
  23. data/lib/generators/katapult/basics/templates/config/initializers/ext.rb +3 -0
  24. data/lib/generators/katapult/basics/templates/features/support/factory_girl.rb +1 -0
  25. data/lib/generators/katapult/basics/templates/features/support/paths.rb +6 -0
  26. data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/db.rake +28 -0
  27. data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/deploy.rake +15 -0
  28. data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/passenger.rake +8 -0
  29. data/lib/generators/katapult/basics/templates/{config/initializers → lib/ext/action_view}/form_for_with_development_errors.rb +0 -2
  30. data/lib/generators/katapult/basics/templates/lib/ext/action_view/spec_label.rb +46 -0
  31. data/lib/generators/katapult/basics/templates/{config/initializers → lib/ext/active_record}/find_by_anything.rb +0 -0
  32. data/lib/generators/katapult/basics/templates/lib/ext/active_record/these.rb +7 -0
  33. data/lib/generators/katapult/basics/templates/lib/ext/array/xss_aware_join.rb +10 -0
  34. data/lib/generators/katapult/basics/templates/lib/ext/enumerable/natural_sort.rb +15 -0
  35. data/lib/generators/katapult/basics/templates/lib/ext/hash/infinite.rb +7 -0
  36. data/lib/generators/katapult/basics/templates/lib/ext/string/html_entities.rb +11 -0
  37. data/lib/generators/katapult/basics/templates/lib/ext/string/to_sort_atoms.rb +52 -0
  38. data/lib/generators/katapult/basics/templates/lib/tasks/pending_migrations.rake +24 -0
  39. data/lib/generators/katapult/basics/templates/spec/factories/factories.rb +9 -0
  40. data/lib/generators/katapult/basics/templates/spec/support/factory_girl.rb +3 -0
  41. data/lib/generators/katapult/clearance/clearance_generator.rb +125 -0
  42. data/lib/generators/katapult/clearance/templates/app/controllers/passwords_controller.rb +16 -0
  43. data/lib/generators/katapult/clearance/templates/app/views/clearance_mailer/change_password.html.haml +6 -0
  44. data/lib/generators/katapult/clearance/templates/app/views/clearance_mailer/change_password.text.erb +3 -0
  45. data/lib/generators/katapult/clearance/templates/app/views/passwords/create.html.haml +5 -0
  46. data/lib/generators/katapult/clearance/templates/app/views/passwords/edit.html.haml +16 -0
  47. data/lib/generators/katapult/clearance/templates/app/views/passwords/new.html.haml +14 -0
  48. data/lib/generators/katapult/clearance/templates/app/views/sessions/new.html.haml +19 -0
  49. data/lib/generators/katapult/clearance/templates/config/initializers/clearance.rb +15 -0
  50. data/lib/generators/katapult/clearance/templates/config/locales/clearance.en.yml +59 -0
  51. data/lib/generators/katapult/clearance/templates/features/authentication.feature +94 -0
  52. data/lib/generators/katapult/clearance/templates/features/step_definitions/authentication_steps.rb +4 -0
  53. data/lib/generators/katapult/cucumber_features/templates/feature.feature +11 -7
  54. data/lib/generators/katapult/haml/haml_generator.rb +5 -0
  55. data/lib/generators/katapult/haml/templates/_form.html.haml +4 -4
  56. data/lib/generators/katapult/haml/templates/app/views/layouts/_flashes.html.haml +3 -0
  57. data/lib/generators/katapult/haml/templates/app/views/layouts/application.html.haml +9 -3
  58. data/lib/generators/katapult/haml/templates/index.html.haml +1 -1
  59. data/lib/generators/katapult/haml/templates/show.html.haml +2 -4
  60. data/lib/generators/katapult/install/templates/lib/katapult/application_model.rb +9 -7
  61. data/lib/generators/katapult/model/model_generator.rb +1 -1
  62. data/lib/generators/katapult/w_u_i/templates/controller.rb +1 -1
  63. data/lib/generators/katapult/w_u_i/w_u_i_generator.rb +4 -2
  64. data/lib/katapult/application_model.rb +8 -1
  65. data/lib/katapult/attribute.rb +10 -11
  66. data/lib/katapult/authentication.rb +25 -0
  67. data/lib/katapult/binary_util.rb +37 -0
  68. data/lib/katapult/element.rb +1 -1
  69. data/lib/katapult/generator.rb +6 -0
  70. data/lib/katapult/model.rb +13 -1
  71. data/lib/katapult/parser.rb +7 -0
  72. data/lib/katapult/version.rb +1 -1
  73. data/lib/katapult/wui.rb +4 -0
  74. data/lib/katapult.rb +2 -0
  75. data/spec/attribute_spec.rb +13 -0
  76. data/spec/element_spec.rb +5 -0
  77. data/spec/model_spec.rb +5 -4
  78. data/spec/util_spec.rb +8 -8
  79. data/spec/wui_spec.rb +19 -0
  80. metadata +44 -8
  81. data/features/katapult.feature +0 -271
  82. data/lib/katapult/util.rb +0 -16
@@ -0,0 +1,590 @@
1
+ Feature: Katapult in general
2
+
3
+ Background:
4
+ Given a pristine Rails application
5
+
6
+
7
+ Scenario: Install katapult
8
+ When I install katapult
9
+ Then the file "lib/katapult/application_model.rb" should contain exactly:
10
+ """
11
+ # Here you define the fundamentals of your application.
12
+ #
13
+ # Add a model:
14
+ # model 'user' do |user|
15
+ # user.attr :name
16
+ # user.attr :birth, type: :datetime
17
+ # user.attr :email
18
+ # end
19
+ #
20
+ # Add a web user interface:
21
+ # wui 'user' do |wui|
22
+ # wui.crud # Creates all CRUD actions: index, new, show, etc.
23
+ # wui.action :lock, scope: :member, method: :post
24
+ # end
25
+ #
26
+ # Add navigation
27
+ # navigation :main
28
+ #
29
+ # Add authentication
30
+ # authenticate 'user', system_email: 'system@example.com'
31
+
32
+ """
33
+
34
+
35
+ Scenario: Generate basic files and settings
36
+ Given I install katapult
37
+
38
+ When I generate katapult basics
39
+ Then the file ".ruby-version" should contain "2.3.0"
40
+
41
+
42
+ And the file "config/cucumber.yml" should contain:
43
+ """
44
+ default: <%= std_opts %> features
45
+ wip: --tags @wip:3 --wip features
46
+ parallel: <%= std_opts %> features <%= log_failures %>
47
+ rerun: -r features --format pretty --strict <%= rerun_failures %> <%= log_failures %>
48
+ """
49
+
50
+
51
+ And the file ".gitignore" should contain "config/database.yml"
52
+ And the file ".bundle/config" should match /NOKOGIRI.*--use-system-libraries/
53
+ And the file "Guardfile" should contain:
54
+ """
55
+ guard 'livereload' do
56
+ watch %r{app/views/.+\.(erb|haml)$}
57
+ watch 'app/models/navigation.rb' # Navy
58
+ watch 'app/models/power.rb' # Consul
59
+ watch %r{app/helpers/.+\.rb}
60
+ watch %r{public/.+\.(css|js|html)}
61
+ watch %r{config/locales/.+\.yml}
62
+ watch %r{spec/javascripts/} # Jasmine
63
+
64
+ # Rails Assets Pipeline
65
+ watch(%r{(app|vendor)(/assets/\w+/(.+\.(css|sass|js|coffee|html|png|jpg))).*}) do |m|
66
+ filename = m[3]
67
+ # When a .sass (or .css.sass) file was changed, tell the client to load the .css version.
68
+ # Similarly, for .coffee / .js.coffee files we ask the client to reload the .js file.
69
+ filename.gsub! /(\.css)?\.sass$/, '.css'
70
+ filename.gsub! /(\.js)?\.coffee$/, '.js'
71
+ "/assets/#{filename}"
72
+ end
73
+ end
74
+ """
75
+ And the file "Capfile" should contain:
76
+ """
77
+ # Load DSL and set up stages
78
+ require 'capistrano/setup'
79
+
80
+ # Include default deployment tasks
81
+ require 'capistrano/deploy'
82
+
83
+ # Include tasks from other gems included in your Gemfile
84
+ require 'capistrano/bundler'
85
+ require 'capistrano/maintenance'
86
+ require 'capistrano/rails/assets'
87
+ require 'capistrano/rails/migrations'
88
+ require 'whenever/capistrano'
89
+
90
+ Dir.glob('lib/capistrano/tasks/*.rake').each do |r|
91
+ # `import r` calls Rake.application.add_import(r), which imports the file only
92
+ # *after* this file has been processed, so the imported tasks would not be
93
+ # available to the hooks below.
94
+ Rake.load_rakefile r
95
+ end
96
+
97
+ before 'deploy:updating', 'db:dump'
98
+ after 'deploy:published', 'deploy:restart'
99
+ after 'deploy:published', 'db:warn_if_pending_migrations'
100
+ after 'deploy:published', 'db:show_dump_usage'
101
+ after 'deploy:finished', 'deploy:cleanup' # https://makandracards.com/makandra/1432
102
+ """
103
+ And the file "Gemfile" should contain "gem 'rails', '4.2.6'"
104
+ And the file "Gemfile" should contain exactly:
105
+ """
106
+ source 'https://rubygems.org'
107
+
108
+ gem 'rails', '4.2.6'
109
+ gem 'pg', '~> 0.15'
110
+ gem 'jquery-rails'
111
+ gem 'jbuilder', '~> 2.0'
112
+ gem 'katapult', path: '../../..'
113
+
114
+ # internal
115
+ gem 'exception_notification'
116
+ # gem 'admin_cleaner', git: 'git@code.makandra.de:makandra/admin_cleaner.git'
117
+
118
+ # security
119
+ gem 'breach-mitigation-rails'
120
+ gem 'safe_cookies'
121
+
122
+ # better coding
123
+ gem 'modularity'
124
+ gem 'edge_rider'
125
+ gem 'andand'
126
+
127
+ # models
128
+ gem 'has_defaults'
129
+ gem 'assignable_values'
130
+
131
+ # gem 'carrierwave'
132
+ # gem 'mini_magick'
133
+
134
+ # gem 'spreadsheet'
135
+ # gem 'vcard'
136
+
137
+ # views
138
+ # gem 'simple_form'
139
+ # gem 'nested_form'
140
+ gem 'will_paginate'
141
+ gem 'makandra-navy', require: 'navy'
142
+
143
+ # assets
144
+ gem 'haml-rails'
145
+ gem 'bootstrap-sass'
146
+ gem 'sass-rails'
147
+ gem 'autoprefixer-rails'
148
+ gem 'coffee-rails'
149
+ gem 'therubyracer', platform: :ruby
150
+ gem 'uglifier'
151
+ gem 'compass-rails'
152
+ gem 'compass-rgbapng'
153
+
154
+ group :development do
155
+ gem 'query_diet'
156
+ gem 'better_errors'
157
+ gem 'binding_of_caller'
158
+ gem 'thin'
159
+
160
+ gem 'parallel_tests'
161
+ gem 'guard-livereload', require: false
162
+ gem 'rack-livereload'
163
+ gem 'spring-commands-rspec'
164
+ gem 'spring-commands-cucumber'
165
+ end
166
+
167
+ group :development, :test do
168
+ gem 'byebug'
169
+ gem 'factory_girl_rails'
170
+ gem 'rspec-rails'
171
+ gem 'spring'
172
+ end
173
+
174
+ group :test do
175
+ gem 'database_cleaner'
176
+ gem 'timecop'
177
+ gem 'launchy'
178
+
179
+ gem 'capybara'
180
+ gem 'capybara-screenshot'
181
+ gem 'cucumber', '< 2' # Incompatible with Cucumber Factory
182
+ gem 'cucumber-rails', require: false
183
+ gem 'cucumber_factory'
184
+ gem 'selenium-webdriver'
185
+ gem 'spreewald'
186
+
187
+ gem 'rspec'
188
+ gem 'shoulda-matchers', require: false
189
+ end
190
+
191
+ group :deploy do
192
+ gem 'capistrano-rails', require: false
193
+ gem 'capistrano-bundler', require: false
194
+ gem 'capistrano-maintenance'
195
+ end
196
+ """
197
+
198
+ And the file "app/controllers/application_controller.rb" should contain:
199
+ """
200
+ before_filter :make_action_mailer_use_request_host_and_protocol
201
+
202
+ private
203
+
204
+ def make_action_mailer_use_request_host_and_protocol
205
+ ActionMailer::Base.default_url_options[:protocol] = request.protocol
206
+ ActionMailer::Base.default_url_options[:host] = request.host_with_port
207
+ end
208
+ """
209
+
210
+ # Just checking turbolinks was properly removed
211
+ And the file "app/views/layouts/application.html.erb" should not contain "turbolinks"
212
+ But the file "app/views/layouts/application.html.erb" should contain:
213
+ """
214
+ <%= stylesheet_link_tag 'application', media: 'all' %>
215
+ <%= javascript_include_tag 'application' %>
216
+ """
217
+
218
+
219
+
220
+ # Config
221
+ And the file "config/application.rb" should contain "config.time_zone = 'Berlin'"
222
+ And the file "config/environments/development.rb" should contain "config.assets.debug = false"
223
+ And the file "config/environments/development.rb" should contain:
224
+ """
225
+ config.middleware.use Rack::LiveReload
226
+ """
227
+ And a file named "config/environments/staging.rb" should exist
228
+ And the file "config/database.yml" should contain exactly:
229
+ """
230
+ common: &common
231
+ adapter: postgresql
232
+ encoding: unicode
233
+ host: localhost
234
+ username: katapult
235
+ password: secret
236
+
237
+ development:
238
+ <<: *common
239
+ database: katapult_test_app_development
240
+
241
+ test: &test
242
+ <<: *common
243
+ database: katapult_test_app_test<%= ENV['TEST_ENV_NUMBER'] %>
244
+ """
245
+
246
+ And the file "config/database.sample.yml" should contain exactly:
247
+ """
248
+ common: &common
249
+ adapter: postgresql
250
+ encoding: unicode
251
+ host: localhost
252
+ username: root
253
+ password:
254
+
255
+ development:
256
+ <<: *common
257
+ database: katapult_test_app_development
258
+
259
+ test:
260
+ <<: *common
261
+ database: katapult_test_app_test<%= ENV['TEST_ENV_NUMBER'] %>
262
+ """
263
+
264
+ And the file "config/cucumber.yml" should contain:
265
+ """
266
+ default: <%= std_opts %> features
267
+ wip: --tags @wip:3 --wip features
268
+ parallel: <%= std_opts %> features <%= log_failures %>
269
+ rerun: -r features --format pretty --strict <%= rerun_failures %> <%= log_failures %>
270
+ """
271
+ And the file "config/deploy.rb" should contain:
272
+ """
273
+ abort 'You must run this using "bundle exec ..."' unless ENV['BUNDLE_BIN_PATH'] || ENV['BUNDLE_GEMFILE']
274
+
275
+ # config valid only for current version of Capistrano
276
+ lock '3.4.0'
277
+
278
+ # Default value for :format is :pretty
279
+ # set :format, :pretty
280
+
281
+ set :log_level, :info # %i(debug info error), default: :debug
282
+
283
+ # Default value for :pty is false
284
+ # set :pty, true
285
+
286
+ # Default value for :linked_files is []
287
+ # set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
288
+ set :linked_files, %w(config/database.yml)
289
+
290
+ # Default value for linked_dirs is []
291
+ # set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
292
+ set :linked_dirs, %w(log public/system)
293
+
294
+ # Default value for default_env is {}
295
+ # set :default_env, { path: "/opt/ruby/bin:$PATH" }
296
+
297
+ set :application, 'katapult_test_app'
298
+ set :keep_releases, 10
299
+ set :ssh_options, {
300
+ forward_agent: true
301
+ }
302
+ set :scm, :git
303
+ set :repo_url, 'git@code.makandra.de:makandra/katapult_test_app.git'
304
+
305
+ # set :whenever_roles, :cron
306
+ # set :whenever_environment, defer { stage }
307
+ # set :whenever_command, 'bundle exec whenever'
308
+
309
+ set :maintenance_template_path, 'public/maintenance.html.erb'
310
+ """
311
+ And the file "config/deploy/staging.rb" should contain:
312
+ """
313
+ set :stage, :staging
314
+
315
+ set :deploy_to, '/var/www/katapult_test_app-staging'
316
+ set :rails_env, 'staging'
317
+ set :branch, ENV['DEPLOY_BRANCH'] || 'master'
318
+
319
+ # server 'example.com', user: 'deploy-user', roles: %w(app web cron db)
320
+ """
321
+ And the file "config/deploy/production.rb" should contain exactly:
322
+ """
323
+ set :stage, :production
324
+
325
+ set :deploy_to, '/var/www/katapult_test_app'
326
+ set :rails_env, 'production'
327
+ set :branch, 'production'
328
+
329
+ # server 'one.example.com', user: 'deploy-user', roles: %w(app web cron db)
330
+ # server 'two.example.com', user: 'deploy-user', roles: %w(app web)
331
+ """
332
+ And the file "config/initializers/ext.rb" should contain exactly:
333
+ """
334
+ Dir.glob(Rails.root.join('lib/ext/**/*.rb')).each do |filename|
335
+ require filename
336
+ end
337
+ """
338
+ And the file "config/initializers/exception_notification.rb" should contain:
339
+ """
340
+ ExceptionNotification.configure do |config|
341
+
342
+ config.add_notifier :email, {
343
+ email_prefix: '[katapult_test_app] ',
344
+ exception_recipients: %w[fail@makandra.de],
345
+ """
346
+ And the file "config/secrets.yml" should contain:
347
+ """
348
+ staging:
349
+ secret_key_base:
350
+
351
+ """
352
+
353
+
354
+ # Lib
355
+ And the file "lib/capistrano/tasks/db.rake" should contain:
356
+ """
357
+ namespace :db do
358
+ desc 'Warn about pending migrations'
359
+ task :warn_if_pending_migrations do
360
+ on primary :db do
361
+ within current_path do
362
+ with rails_env: fetch(:rails_env, 'production') do
363
+ rake 'db:warn_if_pending_migrations'
364
+ end
365
+ end
366
+ end
367
+ end
368
+
369
+ desc 'Do a dump of the DB on the remote machine using dumple'
370
+ task :dump do
371
+ on primary :db do
372
+ within current_path do
373
+ execute :dumple, '--fail-gently', fetch(:rails_env, 'production')
374
+ end
375
+ end
376
+ end
377
+
378
+ desc 'Show usage of ~/dumps/ on remote host'
379
+ task :show_dump_usage do
380
+ on primary :db do
381
+ info capture :dumple, '-i'
382
+ end
383
+ end
384
+ end
385
+ """
386
+ And the file "lib/capistrano/tasks/deploy.rake" should contain:
387
+ """
388
+ namespace :deploy do
389
+ desc 'Restart application'
390
+ task :restart do
391
+ invoke 'passenger:restart'
392
+ end
393
+
394
+ desc 'Show deployed revision'
395
+ task :revision do
396
+ on roles :app do
397
+ within current_path do
398
+ info "Revision: #{ capture :cat, 'REVISION' }"
399
+ end
400
+ end
401
+ end
402
+ end
403
+ """
404
+ And the file "lib/capistrano/tasks/passenger.rake" should contain:
405
+ """
406
+ namespace :passenger do
407
+ desc 'Restart Application'
408
+ task :restart do
409
+ on roles :app do
410
+ execute "sudo passenger-config restart-app --ignore-app-not-running #{ fetch(:deploy_to) }"
411
+ end
412
+ end
413
+ end
414
+ """
415
+ And the file "lib/ext/active_record/find_by_anything.rb" should contain:
416
+ """
417
+ ActiveRecord::Base.class_eval do
418
+
419
+ def self.find_by_anything(identifier)
420
+ """
421
+ And the file "lib/ext/action_view/spec_label.rb" should contain:
422
+ """
423
+ ActionView::Helpers::FormBuilder.class_eval do
424
+
425
+ def spec_label(field, text = nil, options = {})
426
+ """
427
+ And the file "lib/ext/action_view/form_for_with_development_errors.rb" should contain:
428
+ """
429
+ if Rails.env == 'development'
430
+
431
+ ActionView::Helpers::FormHelper.class_eval do
432
+
433
+ def form_for_with_development_errors(*args, &block)
434
+ """
435
+ And the file "lib/ext/active_record/these.rb" should contain:
436
+ """
437
+ ActiveRecord::Base.class_eval do
438
+
439
+ def self.these(arg)
440
+ where(id: arg.collect_ids)
441
+ end
442
+
443
+ end
444
+ """
445
+ And the file "lib/ext/array/xss_aware_join.rb" should contain:
446
+ """
447
+ Array.class_eval do
448
+ def xss_aware_join(delimiter = '')
449
+ ''.html_safe.tap do |str|
450
+ each_with_index do |element, i|
451
+ str << delimiter if i > 0
452
+ str << element
453
+ end
454
+ end
455
+ end
456
+ end
457
+ """
458
+ And the file "lib/ext/enumerable/natural_sort.rb" should contain:
459
+ """
460
+ module Enumerable
461
+
462
+ def natural_sort
463
+ """
464
+ And the file "lib/ext/hash/infinite.rb" should contain:
465
+ """
466
+ class Hash
467
+
468
+ def self.infinite
469
+ new { |h, k| h[k] = new(&h.default_proc) }
470
+ end
471
+
472
+ end
473
+ """
474
+ And the file "lib/ext/string/html_entities.rb" should contain:
475
+ """
476
+ class String
477
+
478
+ def self.nbsp
479
+ ' '
480
+ end
481
+
482
+ def self.ndash
483
+ '–'
484
+ end
485
+
486
+ end
487
+ """
488
+ And the file "lib/ext/string/to_sort_atoms.rb" should contain:
489
+ """
490
+ String.class_eval do
491
+
492
+ def to_sort_atoms
493
+ SmartSortAtom.parse(self)
494
+ end
495
+
496
+ end
497
+ """
498
+ And the file "lib/tasks/pending_migrations.rake" should contain:
499
+ """
500
+ pending_migrations = ActiveRecord::Migrator.new(:up, all_migrations).pending_migrations
501
+
502
+ if pending_migrations.any?
503
+ puts ''
504
+ puts '======================================================='
505
+ puts "You have #{ pending_migrations.size } pending migrations:"
506
+ """
507
+
508
+
509
+ # Tests
510
+ And the file "features/support/env-custom.rb" should contain:
511
+ """
512
+ require 'spreewald/all_steps'
513
+ """
514
+ And the file "features/support/cucumber_factory.rb" should contain:
515
+ """
516
+ Cucumber::Factory.add_steps(self)
517
+ """
518
+ And the file "features/support/capybara_screenshot.rb" should contain:
519
+ """
520
+ require 'capybara-screenshot/cucumber'
521
+
522
+ # Keep up to the number of screenshots specified in the hash
523
+ Capybara::Screenshot.prune_strategy = { keep: 10 }
524
+ """
525
+ And the file "features/support/database_cleaner.rb" should contain:
526
+ """
527
+ DatabaseCleaner.clean_with(:deletion) # clean once, now
528
+ DatabaseCleaner.strategy = :transaction
529
+ Cucumber::Rails::Database.javascript_strategy = :deletion
530
+ """
531
+ And the file "features/support/factory_girl.rb" should contain:
532
+ """
533
+ World(FactoryGirl::Syntax::Methods)
534
+ """
535
+ And a file named "features/support/paths.rb" should exist
536
+ And a file named "features/support/selectors.rb" should exist
537
+ And the file "spec/rails_helper.rb" should match /^Dir.Rails.root.join.+spec.support/
538
+ And the file "spec/support/shoulda_matchers.rb" should contain:
539
+ """
540
+ require 'shoulda/matchers'
541
+
542
+ Shoulda::Matchers.configure do |config|
543
+ config.integrate do |with|
544
+ with.test_framework :rspec
545
+ with.library :rails
546
+ end
547
+ end
548
+ """
549
+ And the file "spec/support/factory_girl.rb" should contain:
550
+ """
551
+ RSpec.configure do |config|
552
+ config.include FactoryGirl::Syntax::Methods
553
+ end
554
+ """
555
+ And the file "spec/factories/factories.rb" should contain:
556
+ """
557
+ FactoryGirl.define do
558
+
559
+ factory :EXAMPLE do
560
+ status 'pending'
561
+ uuid { SecureRandom.uuid }
562
+ sequence(:title) { |i| "Titel #{ i }"}
563
+ end
564
+
565
+ end
566
+ """
567
+
568
+
569
+
570
+ # styles
571
+ And the file "app/assets/stylesheets/application.sass" should contain:
572
+ """
573
+ @import compass
574
+ @import bootstrap
575
+
576
+ @import application/blocks/all
577
+
578
+ """
579
+ And the file "app/assets/stylesheets/application/blocks/_all.sass" should contain exactly:
580
+ """
581
+ @import items
582
+ @import layout
583
+ @import navigation
584
+ @import tools
585
+
586
+ """
587
+ And a file named "app/assets/stylesheets/application/blocks/_items.sass" should exist
588
+ And a file named "app/assets/stylesheets/application/blocks/_layout.sass" should exist
589
+ And a file named "app/assets/stylesheets/application/blocks/_navigation.sass" should exist
590
+ And a file named "app/assets/stylesheets/application/blocks/_tools.sass" should exist
@@ -9,6 +9,7 @@ Feature: Katapult binary `katapult`
9
9
  Then the output should contain "Creating new Rails application"
10
10
  And the output should contain "Installing katapult"
11
11
  And the output should contain "Generating katapult basics"
12
+ And the output should contain "Using rails 4.2.6"
12
13
  And the output should contain:
13
14
  """
14
15
  Application initialization done.
@@ -47,7 +48,7 @@ Feature: Katapult binary `katapult`
47
48
 
48
49
  Scenario: Run without arguments
49
50
  When I run `katapult # without arguments`
50
- Then the output should contain "Usage: katapult [new APP_NAME | fire]"
51
+ Then the output should contain "Usage: katapult [new APP_NAME | fire [path/to/model] ]"
51
52
 
52
53
 
53
54
  Scenario: Transform the application model
@@ -71,3 +72,34 @@ Feature: Katapult binary `katapult`
71
72
  When I run `git log`
72
73
  Then the output should contain "rails generate katapult:transform lib/katapult/application_model.rb"
73
74
  And the output should contain "Author: katapult <katapult@makandra.com>"
75
+
76
+
77
+ Scenario: Transform a custom application model
78
+ Given a pristine Rails application
79
+ And I install katapult
80
+ And I generate katapult basics
81
+
82
+ When I write to "lib/katapult/custom_model.rb" with:
83
+ """
84
+ model 'custom'
85
+ """
86
+ And I run `katapult fire lib/katapult/custom_model.rb`
87
+ Then the output should contain "Loading katapult"
88
+ And the output should contain "parse lib/katapult/custom_model"
89
+ And a file named "app/models/custom.rb" should exist
90
+
91
+
92
+ Scenario: When the transformation fails, an error message is printed
93
+ Given a pristine Rails application
94
+ And I install katapult
95
+ And I generate katapult basics
96
+
97
+ When I overwrite "lib/katapult/application_model.rb" with:
98
+ """
99
+ model 'failing example' do |ex|
100
+ ex.attr :fail, type: :nonexistent
101
+ end
102
+ """
103
+ And I run `katapult fire`
104
+ Then the output should not contain "Model transformation done"
105
+ But the output should contain "x Something went wrong"
@@ -63,10 +63,13 @@ Feature: Generate Models
63
63
  person.attr :hobby # string is default
64
64
 
65
65
  # Special types
66
- person.attr :email # type is detected as email
66
+ person.attr :email # type is auto-detected as email
67
67
  person.attr :income, type: :money
68
68
  person.attr :homepage, type: :url, default: 'http://www.makandra.de'
69
69
  person.attr :locked, type: :flag, default: false
70
+ person.attr :hobbies, type: :text
71
+ person.attr :indexable_json, type: :json
72
+ person.attr :plain_json, type: :plain_json
70
73
  end
71
74
  """
72
75
  And I successfully transform the application model
@@ -94,6 +97,9 @@ Feature: Generate Models
94
97
  t.decimal :income, precision: 10, scale: 2
95
98
  t.string :homepage
96
99
  t.boolean :locked
100
+ t.text :hobbies
101
+ t.jsonb :indexable_json
102
+ t.json :plain_json
97
103
 
98
104
  t.timestamps null: false
99
105
  end
@@ -223,24 +229,14 @@ Feature: Generate Models
223
229
  """
224
230
  Rails.application.routes.draw do
225
231
  root 'cars#index'
226
- resources :cars, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
227
- member do
228
- end
229
- collection do
230
- end
231
- end
232
+ resources :cars
232
233
  """
233
234
  And I successfully transform the application model
234
235
  Then the file named "config/routes.rb" should contain:
235
236
  """
236
237
  Rails.application.routes.draw do
237
238
  root 'cars#index'
238
- resources :cars, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
239
- member do
240
- end
241
- collection do
242
- end
243
- end
239
+ resources :cars
244
240
  """
245
241
  And the file named "config/routes.rb" should contain "root 'cars#index'" exactly once
246
242
  And the file named "config/routes.rb" should contain "resources :cars" exactly once