katapult 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +1 -0
  3. data/.ruby-version +1 -1
  4. data/Gemfile +9 -0
  5. data/README.md +122 -94
  6. data/Rakefile +13 -0
  7. data/bin/katapult +59 -25
  8. data/features/application_model.feature +55 -0
  9. data/features/authenticate.feature +88 -62
  10. data/features/basics.feature +64 -402
  11. data/features/binary.feature +56 -42
  12. data/features/configuration.feature +4 -4
  13. data/features/model.feature +21 -30
  14. data/features/navigation.feature +35 -48
  15. data/features/step_definitions/aruba_steps.rb +3 -0
  16. data/features/step_definitions/katapult_steps.rb +307 -8
  17. data/features/step_definitions/rails_steps.rb +74 -14
  18. data/features/step_definitions/test_steps.rb +5 -5
  19. data/features/step_definitions/version_steps.rb +22 -0
  20. data/features/support/env.rb +11 -3
  21. data/features/{wui.feature → web_ui.feature} +175 -148
  22. data/katapult.gemspec +8 -13
  23. data/lib/generators/katapult/app_model/app_model_generator.rb +12 -0
  24. data/lib/generators/katapult/app_model/templates/lib/katapult/application_model.rb +40 -0
  25. data/lib/generators/katapult/basics/basics_generator.rb +186 -51
  26. data/lib/generators/katapult/basics/templates/.browserslistrc +1 -0
  27. data/lib/generators/katapult/basics/templates/.gitignore +20 -21
  28. data/lib/generators/katapult/basics/templates/.rspec_parallel +3 -0
  29. data/lib/generators/katapult/basics/templates/Capfile +5 -1
  30. data/lib/generators/katapult/basics/templates/Gemfile +23 -34
  31. data/lib/generators/katapult/basics/templates/Guardfile +0 -12
  32. data/lib/generators/katapult/basics/templates/app/controllers/errors_controller.rb +9 -0
  33. data/lib/generators/katapult/basics/templates/app/helpers/unpoly_helper.rb +13 -0
  34. data/lib/generators/katapult/{haml → basics}/templates/app/views/layouts/_flashes.html.haml +1 -1
  35. data/lib/generators/katapult/basics/templates/app/views/layouts/_menu_bar.html.haml.tt +12 -0
  36. data/lib/generators/katapult/basics/templates/app/views/layouts/application.html.haml.tt +25 -0
  37. data/lib/generators/katapult/basics/templates/app/webpack/assets/images/.keep +0 -0
  38. data/lib/generators/katapult/basics/templates/app/webpack/assets/index.js +16 -0
  39. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/application.js +0 -0
  40. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/bootstrap.js +12 -0
  41. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/compilers/.keep +0 -0
  42. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/macros/content_link.js +17 -0
  43. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/macros/modal_link.js +17 -0
  44. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/unpoly.js +9 -0
  45. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/_definitions.sass +25 -0
  46. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/_environment.sass +2 -0
  47. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/_mixins.sass +3 -0
  48. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/blocks/.keep +0 -0
  49. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/custom_bootstrap.sass +50 -0
  50. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/ext/.keep +0 -0
  51. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/ext/bootstrap/navbar.sass +83 -0
  52. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/theme.sass +11 -0
  53. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/unpoly.sass +2 -0
  54. data/lib/generators/katapult/basics/templates/app/webpack/packs/application.js +13 -0
  55. data/lib/generators/katapult/basics/templates/config/database.sample.yml +1 -1
  56. data/lib/generators/katapult/basics/templates/config/deploy.rb +3 -4
  57. data/lib/generators/katapult/basics/templates/config/environments/staging.rb +5 -0
  58. data/lib/generators/katapult/basics/templates/config/initializers/better_errors.rb +23 -0
  59. data/lib/generators/katapult/basics/templates/config/initializers/exception_notification.rb.tt +1 -1
  60. data/lib/generators/katapult/basics/templates/config/initializers/ext.rb +1 -1
  61. data/lib/generators/katapult/basics/templates/config/webpack/loaders/unpoly.js +4 -0
  62. data/lib/generators/katapult/basics/templates/features/support/capybara_screenshot.rb +7 -0
  63. data/lib/generators/katapult/basics/templates/features/support/factory_bot.rb +1 -0
  64. data/lib/generators/katapult/basics/templates/features/support/paths.rb +7 -2
  65. data/lib/generators/katapult/basics/templates/features/support/rspec_doubles.rb +1 -0
  66. data/lib/generators/katapult/basics/templates/features/support/selectors.rb +3 -3
  67. data/lib/generators/katapult/basics/templates/features/support/selenium.rb +13 -0
  68. data/lib/generators/katapult/basics/templates/features/support/{env-custom.rb → spreewald.rb} +0 -0
  69. data/lib/generators/katapult/basics/templates/features/support/webpacker.rb +35 -0
  70. data/lib/generators/katapult/basics/templates/lib/ext/action_view/form_for_with_development_errors.rb +31 -31
  71. data/lib/generators/katapult/basics/templates/lib/ext/active_record/find_by_anything.rb +4 -3
  72. data/lib/generators/katapult/basics/templates/public/robots.txt +5 -0
  73. data/lib/generators/katapult/basics/templates/spec/assets/sample.pdf +0 -0
  74. data/lib/generators/katapult/basics/templates/spec/factories/factories.rb +1 -1
  75. data/lib/generators/katapult/basics/templates/spec/support/database_cleaner.rb +20 -0
  76. data/lib/generators/katapult/basics/templates/spec/support/factory_bot.rb +3 -0
  77. data/lib/generators/katapult/basics/templates/spec/support/fixture_file.rb +6 -0
  78. data/lib/generators/katapult/basics/templates/spec/support/postgresql_sequences.rb +15 -0
  79. data/lib/generators/katapult/basics/templates/spec/support/timecop.rb +3 -0
  80. data/lib/generators/katapult/clearance/clearance_generator.rb +14 -2
  81. data/lib/generators/katapult/clearance/templates/app/views/layouts/_current_user.html.haml +11 -0
  82. data/lib/generators/katapult/clearance/templates/app/views/passwords/create.html.haml +10 -4
  83. data/lib/generators/katapult/clearance/templates/app/views/passwords/edit.html.haml +12 -12
  84. data/lib/generators/katapult/clearance/templates/app/views/passwords/new.html.haml +14 -11
  85. data/lib/generators/katapult/clearance/templates/app/views/sessions/new.html.haml +16 -15
  86. data/lib/generators/katapult/clearance/templates/features/authentication.feature +3 -3
  87. data/lib/generators/katapult/cucumber_features/templates/feature.feature +1 -1
  88. data/lib/generators/katapult/model_specs/templates/model_spec.rb +3 -5
  89. data/lib/generators/katapult/navigation/navigation_generator.rb +7 -1
  90. data/lib/generators/katapult/navigation/templates/app/views/layouts/_navigation.html.haml +15 -0
  91. data/lib/generators/katapult/transform/transform_generator.rb +12 -17
  92. data/lib/generators/katapult/views/templates/_form.html.haml +48 -0
  93. data/lib/generators/katapult/views/templates/app/helpers/table_helper.rb +14 -0
  94. data/lib/generators/katapult/views/templates/app/webpack/assets/stylesheets/blocks/action_bar.sass +22 -0
  95. data/lib/generators/katapult/views/templates/app/webpack/assets/stylesheets/blocks/title.sass +11 -0
  96. data/lib/generators/katapult/views/templates/custom_action.html.haml +5 -0
  97. data/lib/generators/katapult/views/templates/edit.html.haml +4 -0
  98. data/lib/generators/katapult/views/templates/index.html.haml +26 -0
  99. data/lib/generators/katapult/{haml → views}/templates/new.html.haml +1 -1
  100. data/lib/generators/katapult/views/templates/show.html.haml +39 -0
  101. data/lib/generators/katapult/{haml/haml_generator.rb → views/views_generator.rb} +19 -25
  102. data/lib/generators/katapult/{w_u_i → web_ui}/templates/_route.rb +3 -3
  103. data/lib/generators/katapult/{w_u_i → web_ui}/templates/controller.rb +21 -23
  104. data/lib/generators/katapult/{w_u_i/w_u_i_generator.rb → web_ui/web_ui_generator.rb} +7 -12
  105. data/lib/katapult/action.rb +1 -1
  106. data/lib/katapult/application_model.rb +8 -8
  107. data/lib/katapult/binary_util.rb +48 -10
  108. data/lib/katapult/generator.rb +2 -10
  109. data/lib/katapult/generator_goodies.rb +23 -0
  110. data/lib/katapult/navigation.rb +10 -5
  111. data/lib/katapult/parser.rb +15 -8
  112. data/lib/katapult/version.rb +5 -1
  113. data/lib/katapult/{wui.rb → web_ui.rb} +19 -4
  114. data/lib/katapult.rb +0 -5
  115. data/script/console +5 -2
  116. data/script/kta +8 -0
  117. data/script/update +80 -0
  118. data/spec/action_spec.rb +0 -1
  119. data/spec/attribute_spec.rb +0 -1
  120. data/spec/element_spec.rb +0 -1
  121. data/spec/model_spec.rb +0 -1
  122. data/spec/parser_spec.rb +26 -0
  123. data/spec/util_spec.rb +0 -1
  124. data/spec/{wui_spec.rb → web_ui_spec.rb} +24 -12
  125. metadata +86 -124
  126. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_all.sass +0 -4
  127. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_items.sass +0 -11
  128. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_layout.sass +0 -26
  129. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_navigation.sass +0 -11
  130. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_tools.sass +0 -12
  131. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application.sass +0 -6
  132. data/lib/generators/katapult/basics/templates/config/spring.rb +0 -3
  133. data/lib/generators/katapult/basics/templates/features/support/factory_girl.rb +0 -1
  134. data/lib/generators/katapult/basics/templates/spec/support/factory_girl.rb +0 -3
  135. data/lib/generators/katapult/haml/templates/_form.html.haml +0 -38
  136. data/lib/generators/katapult/haml/templates/app/views/layouts/application.html.haml +0 -33
  137. data/lib/generators/katapult/haml/templates/custom_action.html.haml +0 -5
  138. data/lib/generators/katapult/haml/templates/edit.html.haml +0 -4
  139. data/lib/generators/katapult/haml/templates/index.html.haml +0 -29
  140. data/lib/generators/katapult/haml/templates/show.html.haml +0 -39
  141. data/lib/generators/katapult/install/install_generator.rb +0 -14
  142. data/lib/generators/katapult/install/templates/lib/katapult/application_model.rb +0 -20
  143. data/lib/generators/katapult/navigation/templates/app/models/navigation.rb +0 -12
@@ -1,20 +1,319 @@
1
1
  # Note: Aruba adds the project's bin/ directory to the path
2
2
 
3
- When /^I install katapult$/ do
3
+ When 'I install katapult' do
4
+ next if @no_clobber
4
5
  append_to_file 'Gemfile', "gem 'katapult', path: '../../..'"
5
- run_simple 'rails generate katapult:install'
6
6
  end
7
7
 
8
- # This step is required for any feature because it generates config/database.yml
8
+ When 'I generate the application model' do
9
+ next if @no_clobber
10
+ with_aruba_timeout 10 do
11
+ run_simple 'rails generate katapult:app_model'
12
+ end
13
+ end
14
+
9
15
  When /^I generate katapult basics$/ do
10
- with_aruba_timeout 45 do
11
- run_simple 'rails generate katapult:basics --db-user=katapult --db-password=secret'
16
+ next if @no_clobber
17
+
18
+ with_aruba_timeout 60 do
19
+ run_simple 'rails generate katapult:basics --db-user katapult --db-password secret'
12
20
  end
13
21
  end
14
22
 
15
- When /^I( successfully)? transform the application model$/ do |require_success|
16
- # the second parameter would be true when not specified
17
- with_aruba_timeout 45 do
23
+ # By default, transforming the application model will not recreate and migrate
24
+ # the test app database (massive test suite speedup).
25
+ # If a scenario relies on the database being set up (e.g. running Cucumber), be
26
+ # sure to use this step with trailing "including migrations".
27
+ When /^I( successfully)? transform the application model( including migrations)?$/ do |require_success, run_migrations|
28
+ next if @no_clobber
29
+
30
+ ENV['SKIP_MIGRATIONS'] = 'true' unless run_migrations # Speedup
31
+
32
+ with_aruba_timeout 60 do
33
+ # The second argument of #run_simple defaults to `true`
18
34
  run_simple 'rails generate katapult:transform lib/katapult/application_model.rb', !!require_success
19
35
  end
20
36
  end
37
+ After { ENV.delete 'SKIP_MIGRATIONS' }
38
+
39
+ Then 'Capistrano should be configured' do
40
+ step 'the file "Capfile" should contain:', <<-CONTENT
41
+ # Load DSL and set up stages
42
+ require 'capistrano/setup'
43
+
44
+ # Include default deployment tasks
45
+ require 'capistrano/deploy'
46
+
47
+ # Use Git
48
+ require 'capistrano/scm/git'
49
+ install_plugin Capistrano::SCM::Git
50
+
51
+ # Include tasks from other gems included in your Gemfile
52
+ require 'capistrano/bundler'
53
+ require 'capistrano/maintenance'
54
+ require 'capistrano/rails/assets'
55
+ require 'capistrano/rails/migrations'
56
+ require 'whenever/capistrano'
57
+
58
+ Dir.glob('lib/capistrano/tasks/*.rake').sort.each do |r|
59
+ # `import r` calls Rake.application.add_import(r), which imports the file only
60
+ # *after* this file has been processed, so the imported tasks would not be
61
+ # available to the hooks below.
62
+ Rake.load_rakefile r
63
+ end
64
+
65
+ before 'deploy:updating', 'db:dump'
66
+ after 'deploy:published', 'deploy:restart'
67
+ after 'deploy:published', 'db:warn_if_pending_migrations'
68
+ after 'deploy:published', 'db:show_dump_usage'
69
+ after 'deploy:finished', 'deploy:cleanup' # https://makandracards.com/makandra/1432
70
+ CONTENT
71
+
72
+ step 'the file "config/deploy.rb" should contain:', <<-CONTENT
73
+ # Default value for :format is :pretty
74
+ # set :format, :pretty
75
+
76
+ set :log_level, :info # %i(debug info error), default: :debug
77
+
78
+ # Default value for :pty is false
79
+ # set :pty, true
80
+
81
+ # Default value for :linked_files is []
82
+ # set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
83
+ set :linked_files, %w(config/database.yml config/secrets.yml)
84
+
85
+ # Default value for linked_dirs is []
86
+ # set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
87
+ set :linked_dirs, %w(log public/system tmp/pids)
88
+
89
+ # Default value for default_env is {}
90
+ # set :default_env, { path: "/opt/ruby/bin:$PATH" }
91
+
92
+ set :application, 'katapult_test_app'
93
+ set :keep_releases, 10
94
+ set :ssh_options, {
95
+ forward_agent: true
96
+ }
97
+ set :repo_url, 'git@code.makandra.de:makandra/katapult_test_app.git'
98
+
99
+ # set :whenever_roles, :cron
100
+ # set :whenever_environment, defer { stage }
101
+ # set :whenever_command, 'bundle exec whenever'
102
+
103
+ set :maintenance_template_path, 'public/maintenance.html.erb'
104
+ CONTENT
105
+
106
+ step 'the file "config/deploy/staging.rb" should contain:', <<-CONTENT
107
+ set :stage, :staging
108
+
109
+ set :deploy_to, '/var/www/katapult_test_app-staging'
110
+ set :rails_env, 'staging'
111
+ set :branch, ENV['DEPLOY_BRANCH'] || 'master'
112
+
113
+ # server 'example.com', user: 'deploy-user', roles: %w(app web cron db)
114
+ CONTENT
115
+
116
+ step 'the file "config/deploy/production.rb" should contain exactly:', <<-CONTENT
117
+ set :stage, :production
118
+
119
+ set :deploy_to, '/var/www/katapult_test_app'
120
+ set :rails_env, 'production'
121
+ set :branch, 'production'
122
+
123
+ # server 'one.example.com', user: 'deploy-user', roles: %w(app web cron db)
124
+ # server 'two.example.com', user: 'deploy-user', roles: %w(app web)
125
+ CONTENT
126
+
127
+ step 'the file "lib/capistrano/tasks/db.rake" should contain ":warn_if_pending_migrations"'
128
+ step 'the file "lib/capistrano/tasks/deploy.rake" should contain "Show deployed revision"'
129
+ step 'the file "lib/capistrano/tasks/passenger.rake" should contain "Restart Application"'
130
+
131
+ end
132
+
133
+ Then 'Turbolinks should be removed' do
134
+ step 'the file "Gemfile" should not contain "turbolinks"'
135
+ step 'the file "app/views/layouts/application.html.haml" should not contain "turbolinks"'
136
+ end
137
+
138
+ Then 'the Asset Pipeline should be removed' do
139
+ step 'the directory "app/assets" should not exist'
140
+
141
+ step 'the file "Gemfile" should not contain "sass-rails"'
142
+ step 'the file "Gemfile" should not contain "therubyracer"'
143
+ end
144
+
145
+ Then 'Webpacker should be employed' do
146
+ step 'the file "app/webpack/packs/application.js" should contain "window.$ = jQuery"'
147
+ step %(the file "app/webpack/assets/index.js" should contain "import './stylesheets/theme'")
148
+
149
+ step 'the file "config/webpacker.yml" should contain "source_path: app/webpack"'
150
+ step 'the file "config/webpack/environment.js" should contain:', <<-CONTENT
151
+ environment.plugins.set('Provide', new webpack.ProvidePlugin({
152
+ $: 'jquery',
153
+ CONTENT
154
+
155
+ step 'the file "features/support/webpacker.rb" should contain "def compile_once"'
156
+ step 'the file "package.json" should contain "jquery"'
157
+ step 'the file "package.json" should contain "bootstrap-sass"'
158
+
159
+ step 'the file ".gitignore" should contain "node_modules"'
160
+ end
161
+
162
+ Then 'the application layout should be set up' do
163
+ step 'the file "app/views/layouts/application.html.haml" should contain "= query_diet_widget"'
164
+ step %(the file "app/views/layouts/application.html.haml" should contain "render 'layouts/menu_bar'")
165
+ step %(the file "app/views/layouts/application.html.haml" should contain "render 'layouts/flashes'")
166
+ step %(the file "app/views/layouts/application.html.haml" should contain "%body{ data: {env: Rails.env} }")
167
+ step %(the file "app/views/layouts/application.html.haml" should contain "%html{ lang: I18n.locale }")
168
+ step %(the file "app/views/layouts/application.html.haml" should contain "width=device-width, initial-scale=1")
169
+ step %(the file "app/views/layouts/application.html.haml" should contain "%meta(charset='utf-8')")
170
+
171
+ step 'the file "app/views/layouts/_flashes.html.haml" should contain:', <<~CONTENT
172
+ - flash.each do |_level, message|
173
+ .flash.alert.alert-info
174
+ = message
175
+ CONTENT
176
+ end
177
+
178
+ Then 'Unpoly should be installed' do
179
+ step 'the file "package.json" should contain "unpoly"'
180
+ step 'a file named "config/webpack/loaders/unpoly.js" should exist'
181
+
182
+ step %(the file "app/webpack/packs/application.js" should contain "import 'unpoly/dist/unpoly'")
183
+ step %(the file "app/webpack/packs/application.js" should contain "import 'unpoly/dist/unpoly-bootstrap3'")
184
+ step %(the file "app/webpack/assets/index.js" should contain "import './stylesheets/unpoly'")
185
+ step 'the file "app/webpack/assets/javascripts/unpoly.js" should contain "up.motion.config.enabled = false"'
186
+ step 'the file "app/webpack/assets/stylesheets/unpoly.sass" should contain "@import ~unpoly/dist/unpoly"'
187
+ step 'the file "app/webpack/assets/stylesheets/unpoly.sass" should contain "@import ~unpoly/dist/unpoly-bootstrap3"'
188
+
189
+ step 'the file "app/helpers/unpoly_helper.rb" should contain "def content_link_to"'
190
+ step 'the file "app/helpers/unpoly_helper.rb" should contain "def modal_link_to"'
191
+ step 'a file named "app/webpack/assets/javascripts/macros/content_link.js" should exist'
192
+ step 'a file named "app/webpack/assets/javascripts/macros/modal_link.js" should exist'
193
+ step 'a directory named "app/webpack/assets/javascripts/compilers" should exist'
194
+ end
195
+
196
+ Then 'styles should be prepared' do
197
+ step 'the file "app/webpack/assets/stylesheets/theme.sass" should contain "body"'
198
+ step 'the file "app/webpack/assets/stylesheets/custom_bootstrap.sass" should contain "@import ~bootstrap-sass/assets/stylesheets/bootstrap/normalize"'
199
+ step 'the file "app/webpack/assets/stylesheets/_environment.sass" should contain:', <<-CONTENT
200
+ @import definitions
201
+ @import mixins
202
+
203
+ CONTENT
204
+ step 'a file named "app/webpack/assets/stylesheets/_mixins.sass" should exist'
205
+ step 'a file named "app/webpack/assets/stylesheets/_definitions.sass" should exist'
206
+
207
+ step 'a directory named "app/webpack/assets/stylesheets/blocks" should exist'
208
+ step 'a directory named "app/webpack/assets/stylesheets/ext" should exist'
209
+
210
+ # JS support for Bootstrap dropdowns
211
+ step %(the file "app/webpack/assets/javascripts/bootstrap.js" should contain "import 'bootstrap-sass/assets/javascripts/bootstrap/dropdown'")
212
+ end
213
+
214
+ Then 'binstubs should be set up' do
215
+ binaries = %w[rails rake rspec cucumber]
216
+
217
+ binaries.each do |binary|
218
+ step %(the file "bin/#{binary}" should contain:), <<-CONTENT
219
+ #!/usr/bin/env ruby
220
+ running_in_parallel = ENV.has_key?('TEST_ENV_NUMBER') || ARGV.any? { |arg| arg =~ /^parallel:/ }
221
+
222
+ begin
223
+ load File.expand_path('../spring', __FILE__) unless running_in_parallel
224
+ rescue LoadError => e
225
+ CONTENT
226
+ end
227
+ end
228
+
229
+ Then 'the test environment should be configured' do
230
+ step 'the file "config/environments/test.rb" should contain "config.eager_load = true"'
231
+ step 'the file "config/environments/test.rb" should contain "config.consider_all_requests_local = false"'
232
+ step 'the file "config/environments/test.rb" should contain "config.action_controller.perform_caching = true"'
233
+ # Default is "true"
234
+ step 'the file "config/environments/test.rb" should not contain "config.action_controller.allow_forgery_protection"'
235
+ end
236
+
237
+ Then 'features/support should be prepared' do
238
+ step 'the file "features/support/cucumber_factory.rb" should contain "Cucumber::Factory.add_steps(self)"'
239
+ step 'the file "features/support/factory_bot.rb" should contain "World(FactoryBot::Syntax::Methods)"'
240
+ step %(the file "features/support/rspec_doubles.rb" should contain "require 'cucumber/rspec/doubles'")
241
+ step %(the file "features/support/spreewald.rb" should contain "require 'spreewald/all_steps'")
242
+
243
+ step 'a file named "features/support/paths.rb" should exist'
244
+ step 'a file named "features/support/selectors.rb" should exist'
245
+ step 'the file "spec/spec_helper.rb" should match /^Dir.Rails.root.join.+spec.support/'
246
+ step 'the file ".rspec" should contain "--require spec_helper"'
247
+ step 'the file ".rspec_parallel" should contain "--require spec_helper"'
248
+
249
+ step 'the file "features/support/selenium.rb" should contain "--mute-audio"'
250
+ step 'the file "features/support/selenium.rb" should contain "--disable-infobars"'
251
+ step 'the file "features/support/selenium.rb" should contain:', <<-CONTENT
252
+ Capybara.register_driver :selenium do |app|
253
+ Capybara::Selenium::Driver.new(app,
254
+ browser: :chrome,
255
+ args: chrome_args,
256
+ prefs: no_password_bubble
257
+ )
258
+ end
259
+ CONTENT
260
+
261
+ step 'the file "features/support/capybara_screenshot.rb" should contain:', <<-CONTENT
262
+ require 'capybara-screenshot/cucumber'
263
+
264
+ # Keep up to the number of screenshots specified in the hash
265
+ Capybara::Screenshot.prune_strategy = { keep: 10 }
266
+ CONTENT
267
+
268
+ step 'the file "features/support/database_cleaner.rb" should contain:', <<-CONTENT
269
+ DatabaseCleaner.clean_with(:deletion) # clean once, now
270
+ DatabaseCleaner.strategy = :transaction
271
+ Cucumber::Rails::Database.javascript_strategy = :deletion
272
+ CONTENT
273
+ end
274
+
275
+ Then 'spec/support should be prepared' do
276
+ step 'a file named "spec/support/postgresql_sequences.rb" should exist'
277
+ step 'the file "spec/support/fixture_file.rb" should contain "def fixture_file"'
278
+ step 'the file "spec/support/database_cleaner.rb" should contain "DatabaseCleaner.clean_with"'
279
+
280
+ step 'the file "spec/support/shoulda_matchers.rb" should contain:', <<-CONTENT
281
+ require 'shoulda/matchers'
282
+
283
+ Shoulda::Matchers.configure do |config|
284
+ config.integrate do |with|
285
+ with.test_framework :rspec
286
+ with.library :rails
287
+ end
288
+ end
289
+ CONTENT
290
+
291
+ step 'the file "spec/support/factory_bot.rb" should contain:', <<-CONTENT
292
+ RSpec.configure do |config|
293
+ config.include FactoryBot::Syntax::Methods
294
+ end
295
+ CONTENT
296
+
297
+ step 'the file "spec/support/timecop.rb" should contain:', <<-CONTENT
298
+ RSpec.configure do |config|
299
+ config.after { Timecop.return }
300
+ end
301
+ CONTENT
302
+ end
303
+
304
+ Then 'initializers should be installed' do
305
+ step 'the file "config/initializers/better_errors.rb" should contain "BetterErrors::ErrorPage.prepend(BetterErrorsHugeInspectWarning)"'
306
+
307
+ step 'the file "config/initializers/exception_notification.rb" should contain:', <<-CONTENT
308
+ ExceptionNotification.configure do |config|
309
+
310
+ config.add_notifier :email, {
311
+ email_prefix: '[katapult_test_app] ',
312
+ exception_recipients: %w[fail@makandra.de],
313
+ CONTENT
314
+ end
315
+
316
+ Then 'the errors controller should be installed' do
317
+ step 'a file named "app/controllers/errors_controller.rb" should exist'
318
+ step 'the file "config/routes.rb" should contain "resources :errors, only: :new"'
319
+ end
@@ -1,6 +1,11 @@
1
1
  require 'katapult/binary_util'
2
2
 
3
- module KatapultRailsHelper
3
+ module RailsHelper
4
+
5
+ # Directory names
6
+ TEST_APP = 'katapult_test_app'
7
+ APP_WITH_BASICS = 'cached_test_app_with_basics'
8
+ PRISTINE_APP = 'cached_pristine_test_app'
4
9
 
5
10
  def with_aruba_timeout(timeout, &block)
6
11
  original_aruba_timeout = aruba.config.exit_timeout
@@ -12,12 +17,13 @@ module KatapultRailsHelper
12
17
  aruba.config.exit_timeout = original_aruba_timeout
13
18
  end
14
19
 
15
- def create_cached_app(name)
16
- job = 'Cached Rails app generation'
17
-
18
- puts "#{job} started (in #{Dir.pwd})"
20
+ def create_app(name)
19
21
  Katapult::BinaryUtil.create_rails_app(name)
20
- puts "#{job} done."
22
+ puts 'Done generating rails app.'
23
+ end
24
+
25
+ def test_app_path
26
+ File.join expand_path('.'), TEST_APP
21
27
  end
22
28
 
23
29
  def ensure_bundled(path)
@@ -28,19 +34,73 @@ module KatapultRailsHelper
28
34
  end
29
35
  end
30
36
 
37
+ def recreate_databases(path)
38
+ Dir.chdir(path) do
39
+ # Katapult doesn't run test app tests in parallel
40
+ Katapult::BinaryUtil.run 'bundle exec rake db:drop db:create > /dev/null'
41
+ end
42
+ end
43
+
31
44
  end
32
- World(KatapultRailsHelper)
45
+ World(RailsHelper)
33
46
 
47
+ # In these steps, cached Rails apps are created to speed up test runs.
48
+ #
49
+ # Note: The current Ruby process and Aruba have *different* opinions about the
50
+ # current working directory:
51
+ # - Ruby knows the "real" Dir.pwd
52
+ # - Aruba is scoped to its test directory "tmp/aruba"
34
53
 
35
54
  Given /^a pristine Rails application$/ do
36
- with_aruba_timeout(120) do
37
- Dir.chdir('tmp') do
38
- create_cached_app('cached_test_app') unless File.directory?('cached_test_app')
39
- ensure_bundled('cached_test_app')
55
+ unless @no_clobber
56
+ with_aruba_timeout(80) do
57
+ # Change Ruby cwd
58
+ Dir.chdir('tmp') do
59
+ if File.directory?(RailsHelper::PRISTINE_APP)
60
+ puts "Using a cached Rails app from tmp/#{RailsHelper::PRISTINE_APP}"
61
+ else
62
+ create_app(RailsHelper::PRISTINE_APP)
63
+ end
64
+
65
+ ensure_bundled(RailsHelper::PRISTINE_APP)
66
+ FileUtils.cp_r RailsHelper::PRISTINE_APP, test_app_path
67
+ end
40
68
  end
69
+ end
70
+
71
+ cd RailsHelper::TEST_APP # Change Aruba cwd
72
+ end
73
+
74
+ Given 'a new Rails application with Katapult basics installed' do
75
+ unless @no_clobber
76
+ with_aruba_timeout(120) do
77
+ # Change Ruby cwd
78
+ Dir.chdir('tmp') do
79
+ if File.directory?(RailsHelper::APP_WITH_BASICS)
80
+ puts <<-NOTE
81
+ Using a cached Rails app with basics installed. Remember to
82
+ rm -rf tmp/#{RailsHelper::APP_WITH_BASICS}
83
+ when modifying the basics generator.
84
+ NOTE
85
+ else
86
+ create_app(RailsHelper::APP_WITH_BASICS)
41
87
 
42
- # copy cached app to aruba directory
43
- FileUtils.cp_r 'tmp/cached_test_app', File.join(expand_path('.'), 'katapult_test_app')
44
- cd 'katapult_test_app' # Aruba::Api method
88
+ Dir.chdir(RailsHelper::APP_WITH_BASICS) do
89
+ # :path will be correct when copied to the TEST_APP path
90
+ Katapult::BinaryUtil.run %(echo "gem 'katapult', path: '../../..'" >> Gemfile)
91
+ Katapult::BinaryUtil.run 'bin/rails generate katapult:basics --db-user katapult --db-password secret'
92
+ # Spring running in the cache dir is of no further use, but would
93
+ # break things when the cache dir is removed
94
+ Katapult::BinaryUtil.run 'spring stop'
95
+ end
96
+ end
97
+
98
+ ensure_bundled(RailsHelper::APP_WITH_BASICS)
99
+ recreate_databases(RailsHelper::APP_WITH_BASICS)
100
+ FileUtils.cp_r RailsHelper::APP_WITH_BASICS, test_app_path
101
+ end
102
+ end
45
103
  end
104
+
105
+ cd RailsHelper::TEST_APP # Change Aruba cwd
46
106
  end
@@ -1,11 +1,11 @@
1
1
  When /^I run rspec/ do
2
- run_simple 'rspec'
2
+ run_simple 'rspec', exit_timeout: 10
3
3
  end
4
4
 
5
5
  When /^I run cucumber/ do
6
- # The test application's Bundler sees an empty BUNDLE_GEMFILE variable and
7
- # infers the wrong Gemfile location. Fixed by removing the var altogether.
8
- delete_environment_variable 'BUNDLE_GEMFILE'
6
+ run_simple 'bundle exec cucumber', exit_timeout: 15
7
+ end
9
8
 
10
- run_simple 'bundle exec cucumber'
9
+ When 'debugger' do
10
+ binding.pry
11
11
  end
@@ -0,0 +1,22 @@
1
+ Then 'the ruby-version file should be up-to-date' do
2
+ configured_ruby = File.read('.ruby-version').strip
3
+ expect(configured_ruby).to eq Katapult::RUBY_VERSION
4
+ end
5
+
6
+ Then 'the configured Rails version should be listed in the Gemfile.lock' do
7
+ rails_version = Katapult::RAILS_VERSION
8
+ step %(the file "Gemfile.lock" should contain " rails (#{rails_version})")
9
+ end
10
+
11
+ Then 'the output should contain the configured Rails version' do
12
+ step %(the output should contain "Using rails #{Katapult::RAILS_VERSION}")
13
+ end
14
+
15
+ Then 'Capistrano should be locked to the installed version' do
16
+ cd '.' do
17
+ gemfile = File.read('Gemfile.lock')
18
+ version = gemfile[/^ capistrano \((.*)\)$/, 1]
19
+
20
+ step %(the file "config/deploy.rb" should contain "lock '#{version}'")
21
+ end
22
+ end
@@ -5,14 +5,22 @@ require 'pry'
5
5
  ENV['KATAPULT_GEMFILE_OPTIONS'] = ", path: '../../..'"
6
6
 
7
7
  Aruba.configure do |config|
8
- config.exit_timeout = 30 # Todo: decrease to ~5
8
+ config.exit_timeout = 5
9
9
  end
10
10
 
11
- Before do
12
- unset_bundler_env_vars # Don't use katapult's Bundler environment inside tests
11
+ Before do |scenario|
12
+ # Don't reuse the Bundler environment of *katapult* during tests
13
+ bundler_env_keys = aruba.environment.keys.grep /^BUNDLE/
14
+ bundler_env_keys.each &method(:delete_environment_variable)
15
+
13
16
  run_simple 'spring stop # Ensure Spring is not running'
17
+
18
+ scenario_tags = scenario.source_tag_names
19
+ @no_clobber = scenario_tags.include? '@no-clobber'
14
20
  end
15
21
 
16
22
  After do
23
+ # Spring doesn't like loosing its working directory. Since the test app
24
+ # directory is clobbered between runs, we stop Spring after each run.
17
25
  run_simple 'spring stop'
18
26
  end