katapult 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +121 -30
- data/bin/katapult +59 -21
- data/features/binary.feature +29 -16
- data/features/katapult.feature +91 -21
- data/features/model.feature +46 -2
- data/features/step_definitions/file_steps.rb +13 -2
- data/features/step_definitions/katapult_steps.rb +9 -3
- data/features/step_definitions/rails_steps.rb +5 -4
- data/features/step_definitions/test_steps.rb +8 -4
- data/features/support/env.rb +6 -4
- data/features/wui.feature +16 -1
- data/katapult.gemspec +3 -3
- data/lib/generators/katapult/basics/basics_generator.rb +51 -26
- data/lib/generators/katapult/basics/templates/.gitignore +27 -0
- data/lib/generators/katapult/basics/templates/Gemfile +3 -2
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/{_all.css.sass → _all.sass} +0 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/{_items.css.sass → _items.sass} +0 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/{_layout.css.sass → _layout.sass} +0 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/{_navigation.css.sass → _navigation.sass} +0 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/{_tools.css.sass → _tools.sass} +0 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/{application.css.sass → application.sass} +0 -0
- data/lib/generators/katapult/basics/templates/config/cucumber.yml +10 -0
- data/lib/generators/katapult/basics/templates/config/database.sample.yml +1 -4
- data/lib/generators/katapult/basics/templates/config/database.yml +2 -2
- data/lib/generators/katapult/basics/templates/config/initializers/exception_notification.rb.tt +16 -0
- data/lib/generators/katapult/basics/templates/config/initializers/find_by_anything.rb +19 -0
- data/lib/generators/katapult/basics/templates/config/initializers/form_for_with_development_errors.rb +45 -0
- data/lib/generators/katapult/basics/templates/features/support/capybara_screenshot.rb +4 -0
- data/lib/generators/katapult/basics/templates/features/support/cucumber_factory.rb +1 -0
- data/lib/generators/katapult/basics/templates/features/support/database_cleaner.rb +3 -0
- data/lib/generators/katapult/basics/templates/features/support/selectors.rb +56 -0
- data/lib/generators/katapult/basics/templates/spec/support/shoulda_matchers.rb +8 -0
- data/lib/generators/katapult/haml/templates/app/views/layouts/application.html.haml +2 -0
- data/lib/generators/katapult/transform/transform_generator.rb +13 -18
- data/lib/generators/katapult/w_u_i/w_u_i_generator.rb +14 -1
- data/lib/katapult/version.rb +1 -1
- metadata +28 -18
data/features/model.feature
CHANGED
@@ -131,7 +131,9 @@ Feature: Generate Models
|
|
131
131
|
end
|
132
132
|
|
133
133
|
"""
|
134
|
-
|
134
|
+
|
135
|
+
When I run rspec
|
136
|
+
Then the specs should pass
|
135
137
|
|
136
138
|
|
137
139
|
Scenario: Get a helpful error message when an attribute has an unknown option
|
@@ -200,4 +202,46 @@ Feature: Generate Models
|
|
200
202
|
end
|
201
203
|
|
202
204
|
"""
|
203
|
-
|
205
|
+
|
206
|
+
When I run rspec
|
207
|
+
Then the specs should pass
|
208
|
+
|
209
|
+
|
210
|
+
Scenario: Transform the application model multiple times
|
211
|
+
|
212
|
+
Do not add routes twice.
|
213
|
+
|
214
|
+
When I overwrite "lib/katapult/application_model.rb" with:
|
215
|
+
"""
|
216
|
+
model 'Car'
|
217
|
+
wui 'Car' do |wui|
|
218
|
+
wui.crud
|
219
|
+
end
|
220
|
+
"""
|
221
|
+
And I successfully transform the application model
|
222
|
+
Then the file named "config/routes.rb" should contain:
|
223
|
+
"""
|
224
|
+
Rails.application.routes.draw do
|
225
|
+
root 'cars#index'
|
226
|
+
resources :cars, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
|
227
|
+
member do
|
228
|
+
end
|
229
|
+
collection do
|
230
|
+
end
|
231
|
+
end
|
232
|
+
"""
|
233
|
+
And I successfully transform the application model
|
234
|
+
Then the file named "config/routes.rb" should contain:
|
235
|
+
"""
|
236
|
+
Rails.application.routes.draw do
|
237
|
+
root 'cars#index'
|
238
|
+
resources :cars, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
|
239
|
+
member do
|
240
|
+
end
|
241
|
+
collection do
|
242
|
+
end
|
243
|
+
end
|
244
|
+
"""
|
245
|
+
And the file named "config/routes.rb" should contain "root 'cars#index'" exactly once
|
246
|
+
And the file named "config/routes.rb" should contain "resources :cars" exactly once
|
247
|
+
And the output should contain "Routes for :cars already exist! Not updated."
|
@@ -1,5 +1,5 @@
|
|
1
1
|
When /^I replace "(.*?)" with "(.*?)" inside "(.*?)"$/ do |a, b, path|
|
2
|
-
|
2
|
+
cd '.' do
|
3
3
|
content = File.read(path)
|
4
4
|
content.gsub! a, b
|
5
5
|
File.open(path, 'w') { |file| file.puts(content) }
|
@@ -7,8 +7,19 @@ When /^I replace "(.*?)" with "(.*?)" inside "(.*?)"$/ do |a, b, path|
|
|
7
7
|
end
|
8
8
|
|
9
9
|
Then /^there should be a migration with:$/ do |migration|
|
10
|
-
migrations_path = File.join(
|
10
|
+
migrations_path = File.join(expand_path('.'), 'db', 'migrate', '*.rb')
|
11
11
|
|
12
12
|
all_migrations = Dir.glob(migrations_path).map(&File.method(:read)).join
|
13
13
|
expect(all_migrations).to include(migration)
|
14
14
|
end
|
15
|
+
|
16
|
+
Then /^the file named "(.+?)" should contain "(.+?)" exactly once$/ do |file_name, content|
|
17
|
+
cd '.' do
|
18
|
+
occurrences = File.read(file_name).scan(content)
|
19
|
+
|
20
|
+
expect( occurrences.count ).to eq(1), <<-ERROR_MESSAGE
|
21
|
+
Expected file "#{ file_name }" to contain "#{ content }"
|
22
|
+
once, but had it #{ occurrences.count } times.
|
23
|
+
ERROR_MESSAGE
|
24
|
+
end
|
25
|
+
end
|
@@ -1,14 +1,20 @@
|
|
1
|
+
# Note: Aruba adds the project's bin/ directory to the path
|
2
|
+
|
1
3
|
When /^I install katapult$/ do
|
2
4
|
append_to_file 'Gemfile', "gem 'katapult', path: '../../..'"
|
3
|
-
run_simple
|
5
|
+
run_simple 'rails generate katapult:install'
|
4
6
|
end
|
5
7
|
|
6
8
|
# This step is required for any feature because it generates config/database.yml
|
7
9
|
When /^I generate katapult basics$/ do
|
8
|
-
|
10
|
+
with_aruba_timeout 45 do
|
11
|
+
run_simple 'rails generate katapult:basics --db-user=katapult --db-password=secret'
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
When /^I( successfully)? transform the application model$/ do |require_success|
|
12
16
|
# the second parameter would be true when not specified
|
13
|
-
|
17
|
+
with_aruba_timeout 45 do
|
18
|
+
run_simple 'rails generate katapult:transform lib/katapult/application_model.rb', !!require_success
|
19
|
+
end
|
14
20
|
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module KatapultRailsHelper
|
2
2
|
|
3
3
|
def with_aruba_timeout(timeout, &block)
|
4
|
-
original_aruba_timeout =
|
5
|
-
|
4
|
+
original_aruba_timeout = aruba.config.exit_timeout
|
5
|
+
aruba.config.exit_timeout = timeout.to_i
|
6
|
+
# print "(timeout: #{ timeout })"
|
6
7
|
|
7
8
|
block.call
|
8
9
|
ensure
|
9
|
-
|
10
|
+
aruba.config.exit_timeout = original_aruba_timeout
|
10
11
|
end
|
11
12
|
|
12
13
|
def create_cached_app(name)
|
@@ -38,7 +39,7 @@ Given /^a pristine Rails application$/ do
|
|
38
39
|
end
|
39
40
|
|
40
41
|
# copy cached app to aruba directory
|
41
|
-
FileUtils.cp_r
|
42
|
+
FileUtils.cp_r 'tmp/cached_test_app', File.join(expand_path('.'), 'katapult_test_app')
|
42
43
|
cd 'katapult_test_app' # Aruba::Api method
|
43
44
|
end
|
44
45
|
end
|
@@ -1,7 +1,11 @@
|
|
1
|
-
|
2
|
-
run_simple
|
1
|
+
When /^I run rspec/ do
|
2
|
+
run_simple 'rspec'
|
3
3
|
end
|
4
4
|
|
5
|
-
|
6
|
-
|
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'
|
9
|
+
|
10
|
+
run_simple 'bundle exec cucumber'
|
7
11
|
end
|
data/features/support/env.rb
CHANGED
@@ -4,11 +4,13 @@ require 'pry'
|
|
4
4
|
# Make sure tests use the correct katapult gem
|
5
5
|
ENV['KATAPULT_GEMFILE_OPTIONS'] = ", path: '../../..'"
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
Aruba.configure do |config|
|
8
|
+
config.exit_timeout = 30 # Todo: decrease to ~5
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
Before do
|
12
|
+
unset_bundler_env_vars # Don't use katapult's Bundler environment inside tests
|
13
|
+
run_simple 'spring stop # Ensure Spring is not running'
|
12
14
|
end
|
13
15
|
|
14
16
|
After do
|
data/features/wui.feature
CHANGED
@@ -316,4 +316,19 @@ Feature: Web User Interface
|
|
316
316
|
But I should not see "name-string"
|
317
317
|
|
318
318
|
"""
|
319
|
-
|
319
|
+
|
320
|
+
When I run cucumber
|
321
|
+
Then the features should pass
|
322
|
+
|
323
|
+
|
324
|
+
Scenario: Generate layout file with query diet widget
|
325
|
+
When I overwrite "lib/katapult/application_model.rb" with:
|
326
|
+
"""
|
327
|
+
model 'Car'
|
328
|
+
wui 'Car'
|
329
|
+
"""
|
330
|
+
And I successfully transform the application model
|
331
|
+
Then the file "app/views/layouts/application.html.haml" should contain:
|
332
|
+
"""
|
333
|
+
= query_diet_widget(bad_count: 15) if Rails.env.development?
|
334
|
+
"""
|
data/katapult.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.required_ruby_version = '
|
21
|
+
spec.required_ruby_version = '~> 2.0'
|
22
22
|
|
23
23
|
spec.add_runtime_dependency 'rails'
|
24
24
|
spec.add_runtime_dependency 'spring' # speed-up
|
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_development_dependency 'pry'
|
30
30
|
|
31
31
|
# Testing
|
32
|
-
spec.add_development_dependency 'aruba'
|
32
|
+
spec.add_development_dependency 'aruba', '~> 0.10.2'
|
33
33
|
spec.add_development_dependency 'guard-cucumber'
|
34
|
-
spec.add_development_dependency 'rspec'
|
34
|
+
spec.add_development_dependency 'rspec', '~> 3.4.0'
|
35
35
|
end
|
@@ -4,17 +4,29 @@ module Katapult
|
|
4
4
|
module Generators
|
5
5
|
class BasicsGenerator < Rails::Generators::Base
|
6
6
|
|
7
|
-
SKIP_GEMS = %w(sass-rails coffee-rails turbolinks sdoc uglifier)
|
7
|
+
SKIP_GEMS = %w(sass-rails coffee-rails turbolinks sdoc uglifier mysql2)
|
8
8
|
|
9
9
|
desc 'Generate basics like test directories and gems'
|
10
10
|
source_root File.expand_path('../templates', __FILE__)
|
11
11
|
|
12
|
+
class_option :db_user, type: :string,
|
13
|
+
description: 'The user to set in config/database.yml'
|
14
|
+
class_option :db_password, type: :string,
|
15
|
+
description: 'The password to set in config/database.yml'
|
16
|
+
|
17
|
+
|
18
|
+
def add_gitignore
|
19
|
+
template '.gitignore', force: true
|
20
|
+
end
|
12
21
|
|
13
22
|
def write_ruby_version
|
14
23
|
template '.ruby-version'
|
15
24
|
end
|
16
25
|
|
17
26
|
def write_database_ymls
|
27
|
+
@db_user = options.db_user || 'root'
|
28
|
+
@db_password = options.db_password || ''
|
29
|
+
|
18
30
|
template 'config/database.yml', force: true
|
19
31
|
template 'config/database.sample.yml'
|
20
32
|
end
|
@@ -31,13 +43,13 @@ module Katapult
|
|
31
43
|
end
|
32
44
|
|
33
45
|
def bundle_install
|
34
|
-
bundle
|
46
|
+
run 'bundle install'
|
35
47
|
|
36
48
|
# There is a bug in the current version of Compass, so we use an older
|
37
49
|
# one in our Gemfile template. Since its dependencies "sprockets" and
|
38
50
|
# "sass-rails" are already in the Gemfile.lock (from installing Rails),
|
39
51
|
# we need to explicitly update them.
|
40
|
-
bundle
|
52
|
+
run 'bundle update sprockets sass-rails'
|
41
53
|
end
|
42
54
|
|
43
55
|
def remove_turbolinks_js
|
@@ -45,13 +57,35 @@ module Katapult
|
|
45
57
|
end
|
46
58
|
|
47
59
|
def setup_spring
|
48
|
-
|
49
|
-
|
50
|
-
|
60
|
+
# run 'spring binstub --all'
|
61
|
+
# # remove_file 'bin/bundle' # Won't play together with parallel_tests
|
62
|
+
# template 'config/spring.rb'
|
63
|
+
# template 'bin/rake'
|
64
|
+
run 'spring stop' # Reload (just in case)
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_databases
|
68
|
+
run 'rake db:create:all parallel:create'
|
69
|
+
end
|
70
|
+
|
71
|
+
def set_timezone
|
72
|
+
gsub_file 'config/application.rb',
|
73
|
+
/# config\.time_zone =.*$/,
|
74
|
+
"config.time_zone = 'Berlin'"
|
75
|
+
end
|
76
|
+
|
77
|
+
def make_assets_debuggable
|
78
|
+
gsub_file 'config/application.rb',
|
79
|
+
/config\.assets\.debug =.*$/,
|
80
|
+
'config.assets.debug = false'
|
81
|
+
end
|
82
|
+
|
83
|
+
def install_initializers
|
84
|
+
directory 'config/initializers'
|
51
85
|
end
|
52
86
|
|
53
87
|
def add_modularity_load_paths
|
54
|
-
# This results in correct
|
88
|
+
# This results in correct indentation :)
|
55
89
|
application <<-'LOAD_PATHS'
|
56
90
|
config.autoload_paths << "#{Rails.root}/app/controllers/shared"
|
57
91
|
config.autoload_paths << "#{Rails.root}/app/models/shared"
|
@@ -62,20 +96,19 @@ config.autoload_paths << "#{Rails.root}/app/controllers/shared"
|
|
62
96
|
|
63
97
|
def install_cucumber
|
64
98
|
generate 'cucumber:install'
|
99
|
+
directory 'features/support'
|
100
|
+
template 'config/cucumber.yml', force: true
|
65
101
|
|
66
|
-
|
67
|
-
|
102
|
+
# Remove cucumber section from database.yml. Don't need this.
|
103
|
+
gsub_file 'config/database.yml', /^cucumber.*\z/m, ''
|
68
104
|
end
|
69
105
|
|
70
106
|
def install_rspec
|
71
107
|
generate 'rspec:install'
|
72
108
|
|
73
|
-
#
|
74
|
-
|
75
|
-
|
76
|
-
inject_into_file 'spec/rails_helper.rb', after: "require 'rspec/rails'\n" do
|
77
|
-
"require 'shoulda/matchers'\n"
|
78
|
-
end
|
109
|
+
gsub_file '.rspec', "--warnings\n", '' # Don't show Ruby warnings
|
110
|
+
uncomment_lines 'spec/rails_helper.rb', /Dir.Rails.root.join.+spec.support/
|
111
|
+
template 'spec/support/shoulda_matchers.rb'
|
79
112
|
end
|
80
113
|
|
81
114
|
def install_styles
|
@@ -88,23 +121,15 @@ config.autoload_paths << "#{Rails.root}/app/controllers/shared"
|
|
88
121
|
# template 'config/deploy.rb'
|
89
122
|
# end
|
90
123
|
|
91
|
-
|
92
|
-
puts <<-INSTRUCTIONS.strip_heredoc
|
93
|
-
|
94
|
-
Next step: Model your application in lib/katapult/application_model.rb and
|
95
|
-
trigger the code generation by running `katapult fire`.
|
96
|
-
INSTRUCTIONS
|
97
|
-
end
|
98
|
-
|
99
|
-
private
|
124
|
+
private
|
100
125
|
|
101
126
|
def app_name
|
102
127
|
File.basename(Dir.pwd)
|
103
128
|
end
|
104
129
|
|
105
|
-
def
|
130
|
+
def run(*)
|
106
131
|
Bundler.with_clean_env do
|
107
|
-
|
132
|
+
super
|
108
133
|
end
|
109
134
|
end
|
110
135
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
log/*
|
2
|
+
tmp/*
|
3
|
+
storage/*
|
4
|
+
db/*.sqlite3
|
5
|
+
db/schema.rb
|
6
|
+
db/structure.sql
|
7
|
+
public/system
|
8
|
+
public/storage
|
9
|
+
public/uploads
|
10
|
+
.project
|
11
|
+
.idea/
|
12
|
+
public/javascripts/all*
|
13
|
+
public/stylesheets/all*
|
14
|
+
public/stylesheets/*.css
|
15
|
+
config/database.yml
|
16
|
+
*~
|
17
|
+
*#*
|
18
|
+
.#*
|
19
|
+
.DS_Store
|
20
|
+
webrat-*.html
|
21
|
+
capybara-*.html
|
22
|
+
rerun.txt
|
23
|
+
coverage.data
|
24
|
+
coverage/*
|
25
|
+
dump_for_download.dump
|
26
|
+
.~lock.*
|
27
|
+
.*.swp
|
@@ -5,6 +5,7 @@ source 'https://rubygems.org'
|
|
5
5
|
|
6
6
|
# engines
|
7
7
|
gem 'haml-rails'
|
8
|
+
gem 'mysql2', '~> 0.3.18' # Work around require-error in Rails 4.2
|
8
9
|
|
9
10
|
# internal
|
10
11
|
gem 'exception_notification'
|
@@ -46,6 +47,7 @@ group :development do
|
|
46
47
|
gem 'binding_of_caller'
|
47
48
|
gem 'thin'
|
48
49
|
|
50
|
+
gem 'parallel_tests'
|
49
51
|
gem 'guard-livereload', require: false
|
50
52
|
gem 'rack-livereload'
|
51
53
|
gem 'spring-commands-rspec'
|
@@ -60,15 +62,14 @@ group :development, :test do
|
|
60
62
|
end
|
61
63
|
|
62
64
|
group :test do
|
63
|
-
gem 'parallel_tests'
|
64
65
|
gem 'database_cleaner'
|
65
66
|
gem 'timecop'
|
66
67
|
gem 'launchy'
|
67
68
|
|
68
69
|
gem 'capybara'
|
70
|
+
gem 'capybara-screenshot'
|
69
71
|
gem 'cucumber-rails', require: false
|
70
72
|
gem 'cucumber_factory'
|
71
|
-
gem 'cucumber_spinner'
|
72
73
|
gem 'selenium-webdriver'
|
73
74
|
gem 'spreewald'
|
74
75
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%%
|
2
|
+
rerun_log = 'tmp/parallel_cucumber_failures.log'
|
3
|
+
rerun_failures = File.file?(rerun_log) ? File.read(rerun_log).gsub("\n", ' ') : ''
|
4
|
+
std_opts = "-r features --format #{ ENV['CUCUMBER_FORMAT'] || 'progress' } --strict --tags ~@wip"
|
5
|
+
log_failures = "--format ParallelTests::Cucumber::FailuresLogger --out #{ rerun_log }"
|
6
|
+
%>
|
7
|
+
default: <%%= std_opts %> features
|
8
|
+
wip: --tags @wip:3 --wip features
|
9
|
+
parallel: <%%= std_opts %> features <%%= log_failures %>
|
10
|
+
rerun: -r features --format pretty --strict <%%= rerun_failures %> <%%= log_failures %>
|
data/lib/generators/katapult/basics/templates/config/initializers/exception_notification.rb.tt
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'exception_notification/rails'
|
2
|
+
|
3
|
+
ExceptionNotification.configure do |config|
|
4
|
+
|
5
|
+
config.add_notifier :email, {
|
6
|
+
email_prefix: '[<%= app_name %>] ',
|
7
|
+
exception_recipients: %w[fail@makandra.de],
|
8
|
+
sender_address: 'fail@makandra.de',
|
9
|
+
sections: %w[request backtrace],
|
10
|
+
background_sections: %w[backtrace],
|
11
|
+
}
|
12
|
+
|
13
|
+
# Regularly occurs when users have multiple tabs open
|
14
|
+
config.ignored_exceptions += %w[ActionController::InvalidAuthenticityToken]
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
ActiveRecord::Base.class_eval do
|
2
|
+
|
3
|
+
def self.find_by_anything(identifier)
|
4
|
+
matchable_columns = columns.reject { |column| [:binary, :boolean].include?(column.type) }
|
5
|
+
query_clauses = matchable_columns.collect do |column|
|
6
|
+
qualified_column_name = "#{table_name}.#{column.name}"
|
7
|
+
column_as_string = "CAST(#{qualified_column_name} AS CHAR)"
|
8
|
+
"#{column_as_string} = ?"
|
9
|
+
end
|
10
|
+
bindings = [identifier] * query_clauses.size
|
11
|
+
where([query_clauses.join(' OR '), *bindings]).first
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.find_by_anything!(identifier)
|
15
|
+
find_by_anything(identifier) or raise ActiveRecord::RecordNotFound, "No column equals \"#{identifier}\""
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
if Rails.env == 'development'
|
2
|
+
|
3
|
+
ActionView::Helpers::FormHelper.class_eval do
|
4
|
+
|
5
|
+
def form_for_with_development_errors(*args, &block)
|
6
|
+
form_for_without_development_errors(*args) do |form|
|
7
|
+
html = ''.html_safe
|
8
|
+
if form.object && form.object.respond_to?(:errors) && form.object.errors.any?
|
9
|
+
html << content_tag(:div, form.object.errors.full_messages.collect { |m| h m }.join('<br />').html_safe, :class => 'development_errors', :onclick => 'this.parentNode.removeChild(this);')
|
10
|
+
html << '<style type="text/css"><!--'.html_safe
|
11
|
+
css = <<-EOF
|
12
|
+
.development_errors {
|
13
|
+
position: fixed;
|
14
|
+
bottom: 0;
|
15
|
+
right: 0;
|
16
|
+
z-index: 999999;
|
17
|
+
font-size: 11px;
|
18
|
+
line-height: 15px;
|
19
|
+
background-color: #fed;
|
20
|
+
border-top: 1px solid #cba;
|
21
|
+
border-left: 1px solid #cba;
|
22
|
+
color: #821;
|
23
|
+
padding: 10px;
|
24
|
+
cursor: pointer;
|
25
|
+
filter:alpha(opacity=80);
|
26
|
+
-moz-opacity:0.8;
|
27
|
+
-khtml-opacity: 0.8;
|
28
|
+
opacity: 0.8;
|
29
|
+
|
30
|
+
}
|
31
|
+
EOF
|
32
|
+
html << css.html_safe
|
33
|
+
html << '</style>'.html_safe
|
34
|
+
end
|
35
|
+
html << capture(form, &block)
|
36
|
+
Rails.version.to_i < 3 ? concat(html) : html
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method_chain :form_for, :development_errors
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
Cucumber::Factory.add_steps(self)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module HtmlSelectorsHelpers
|
2
|
+
# Maps a name to a selector. Used primarily by the
|
3
|
+
#
|
4
|
+
# When /^(.+) within (.+)$/ do |step, scope|
|
5
|
+
#
|
6
|
+
# step definitions in web_steps.rb
|
7
|
+
#
|
8
|
+
def selector_for(locator)
|
9
|
+
case locator
|
10
|
+
|
11
|
+
# Auto-mapper for BEM classes
|
12
|
+
#
|
13
|
+
# Usage examples:
|
14
|
+
# the main menu -> '.main-menu'
|
15
|
+
# the item box's header -> '.item-box--header'
|
16
|
+
# the slider's item that is current -> '.slider--item.is-current'
|
17
|
+
when /^the (.+?)(?:'s (.+?))?(?: that (.+))?$/
|
18
|
+
selector = '.'
|
19
|
+
selector << selectorify($1)
|
20
|
+
selector << '--' << selectorify($2) if $2
|
21
|
+
selector << '.' << selectorify($3) if $3
|
22
|
+
selector
|
23
|
+
|
24
|
+
# Add more mappings here.
|
25
|
+
# Here is an example that pulls values out of the Regexp:
|
26
|
+
#
|
27
|
+
# when /^the (notice|error|info) flash$/
|
28
|
+
# ".flash.#{$1}"
|
29
|
+
|
30
|
+
# You can also return an array to use a different selector
|
31
|
+
# type, like:
|
32
|
+
#
|
33
|
+
# when /the header/
|
34
|
+
# [:xpath, "//header"]
|
35
|
+
|
36
|
+
# This allows you to provide a quoted selector as the scope
|
37
|
+
# for "within" steps as was previously the default for the
|
38
|
+
# web steps:
|
39
|
+
when /^"(.+)"$/
|
40
|
+
$1
|
41
|
+
|
42
|
+
else
|
43
|
+
raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
|
44
|
+
"Now, go and add a mapping in #{__FILE__}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def selectorify(string)
|
51
|
+
string.gsub(/ /, '-')
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
World(HtmlSelectorsHelpers)
|