katapult 0.2.0 → 0.3.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.
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