katapult 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/README.md +61 -35
- data/bin/katapult +24 -34
- data/features/authenticate.feature +344 -0
- data/features/basics.feature +590 -0
- data/features/binary.feature +33 -1
- data/features/model.feature +9 -13
- data/features/step_definitions/rails_steps.rb +3 -2
- data/features/wui.feature +49 -4
- data/lib/generators/katapult/basics/basics_generator.rb +63 -17
- data/lib/generators/katapult/basics/templates/.gitignore +1 -0
- data/lib/generators/katapult/basics/templates/.ruby-version +1 -1
- data/lib/generators/katapult/basics/templates/Capfile +25 -0
- data/lib/generators/katapult/basics/templates/Gemfile +14 -6
- data/lib/generators/katapult/basics/templates/Guardfile +44 -0
- data/lib/generators/katapult/basics/templates/config/database.sample.yml +3 -2
- data/lib/generators/katapult/basics/templates/config/database.yml +3 -2
- data/lib/generators/katapult/basics/templates/config/deploy/production.rb +8 -0
- data/lib/generators/katapult/basics/templates/config/deploy/staging.rb +7 -0
- data/lib/generators/katapult/basics/templates/config/deploy.rb +37 -0
- data/lib/generators/katapult/basics/templates/config/initializers/ext.rb +3 -0
- data/lib/generators/katapult/basics/templates/features/support/factory_girl.rb +1 -0
- data/lib/generators/katapult/basics/templates/features/support/paths.rb +6 -0
- data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/db.rake +28 -0
- data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/deploy.rake +15 -0
- data/lib/generators/katapult/basics/templates/lib/capistrano/tasks/passenger.rake +8 -0
- data/lib/generators/katapult/basics/templates/{config/initializers → lib/ext/action_view}/form_for_with_development_errors.rb +0 -2
- data/lib/generators/katapult/basics/templates/lib/ext/action_view/spec_label.rb +46 -0
- data/lib/generators/katapult/basics/templates/{config/initializers → lib/ext/active_record}/find_by_anything.rb +0 -0
- data/lib/generators/katapult/basics/templates/lib/ext/active_record/these.rb +7 -0
- data/lib/generators/katapult/basics/templates/lib/ext/array/xss_aware_join.rb +10 -0
- data/lib/generators/katapult/basics/templates/lib/ext/enumerable/natural_sort.rb +15 -0
- data/lib/generators/katapult/basics/templates/lib/ext/hash/infinite.rb +7 -0
- data/lib/generators/katapult/basics/templates/lib/ext/string/html_entities.rb +11 -0
- data/lib/generators/katapult/basics/templates/lib/ext/string/to_sort_atoms.rb +52 -0
- data/lib/generators/katapult/basics/templates/lib/tasks/pending_migrations.rake +24 -0
- data/lib/generators/katapult/basics/templates/spec/factories/factories.rb +9 -0
- data/lib/generators/katapult/basics/templates/spec/support/factory_girl.rb +3 -0
- data/lib/generators/katapult/clearance/clearance_generator.rb +125 -0
- data/lib/generators/katapult/clearance/templates/app/controllers/passwords_controller.rb +16 -0
- data/lib/generators/katapult/clearance/templates/app/views/clearance_mailer/change_password.html.haml +6 -0
- data/lib/generators/katapult/clearance/templates/app/views/clearance_mailer/change_password.text.erb +3 -0
- data/lib/generators/katapult/clearance/templates/app/views/passwords/create.html.haml +5 -0
- data/lib/generators/katapult/clearance/templates/app/views/passwords/edit.html.haml +16 -0
- data/lib/generators/katapult/clearance/templates/app/views/passwords/new.html.haml +14 -0
- data/lib/generators/katapult/clearance/templates/app/views/sessions/new.html.haml +19 -0
- data/lib/generators/katapult/clearance/templates/config/initializers/clearance.rb +15 -0
- data/lib/generators/katapult/clearance/templates/config/locales/clearance.en.yml +59 -0
- data/lib/generators/katapult/clearance/templates/features/authentication.feature +94 -0
- data/lib/generators/katapult/clearance/templates/features/step_definitions/authentication_steps.rb +4 -0
- data/lib/generators/katapult/cucumber_features/templates/feature.feature +11 -7
- data/lib/generators/katapult/haml/haml_generator.rb +5 -0
- data/lib/generators/katapult/haml/templates/_form.html.haml +4 -4
- data/lib/generators/katapult/haml/templates/app/views/layouts/_flashes.html.haml +3 -0
- data/lib/generators/katapult/haml/templates/app/views/layouts/application.html.haml +9 -3
- data/lib/generators/katapult/haml/templates/index.html.haml +1 -1
- data/lib/generators/katapult/haml/templates/show.html.haml +2 -4
- data/lib/generators/katapult/install/templates/lib/katapult/application_model.rb +9 -7
- data/lib/generators/katapult/model/model_generator.rb +1 -1
- data/lib/generators/katapult/w_u_i/templates/controller.rb +1 -1
- data/lib/generators/katapult/w_u_i/w_u_i_generator.rb +4 -2
- data/lib/katapult/application_model.rb +8 -1
- data/lib/katapult/attribute.rb +10 -11
- data/lib/katapult/authentication.rb +25 -0
- data/lib/katapult/binary_util.rb +37 -0
- data/lib/katapult/element.rb +1 -1
- data/lib/katapult/generator.rb +6 -0
- data/lib/katapult/model.rb +13 -1
- data/lib/katapult/parser.rb +7 -0
- data/lib/katapult/version.rb +1 -1
- data/lib/katapult/wui.rb +4 -0
- data/lib/katapult.rb +2 -0
- data/spec/attribute_spec.rb +13 -0
- data/spec/element_spec.rb +5 -0
- data/spec/model_spec.rb +5 -4
- data/spec/util_spec.rb +8 -8
- data/spec/wui_spec.rb +19 -0
- metadata +44 -8
- data/features/katapult.feature +0 -271
- 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
|
data/features/binary.feature
CHANGED
@@ -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"
|
data/features/model.feature
CHANGED
@@ -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
|
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
|
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
|