katapult 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/Guardfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +122 -0
- data/Rakefile +14 -0
- data/bin/katapult +44 -0
- data/features/binary.feature +48 -0
- data/features/configuration.feature +24 -0
- data/features/katapult.feature +201 -0
- data/features/model.feature +203 -0
- data/features/navigation.feature +80 -0
- data/features/step_definitions/db_steps.rb +8 -0
- data/features/step_definitions/file_steps.rb +14 -0
- data/features/step_definitions/katapult_steps.rb +14 -0
- data/features/step_definitions/rails_steps.rb +44 -0
- data/features/step_definitions/test_steps.rb +7 -0
- data/features/support/env.rb +16 -0
- data/features/wui.feature +319 -0
- data/katapult.gemspec +35 -0
- data/katapult.png +0 -0
- data/lib/generators/katapult/basics/basics_generator.rb +95 -0
- data/lib/generators/katapult/basics/templates/Gemfile +76 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application.css.sass +6 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_all.css.sass +4 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_items.css.sass +11 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_layout.css.sass +26 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_navigation.css.sass +11 -0
- data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_tools.css.sass +12 -0
- data/lib/generators/katapult/basics/templates/config/database.sample.yml +16 -0
- data/lib/generators/katapult/basics/templates/config/database.yml +13 -0
- data/lib/generators/katapult/basics/templates/config/spring.rb +3 -0
- data/lib/generators/katapult/basics/templates/features/support/env-custom.rb +3 -0
- data/lib/generators/katapult/basics/templates/features/support/paths.rb +47 -0
- data/lib/generators/katapult/cucumber_features/cucumber_features_generator.rb +23 -0
- data/lib/generators/katapult/cucumber_features/templates/feature.feature +59 -0
- data/lib/generators/katapult/haml/haml_generator.rb +90 -0
- data/lib/generators/katapult/haml/templates/_form.html.haml +38 -0
- data/lib/generators/katapult/haml/templates/app/views/layouts/application.html.haml +25 -0
- data/lib/generators/katapult/haml/templates/custom_action.html.haml +5 -0
- data/lib/generators/katapult/haml/templates/edit.html.haml +4 -0
- data/lib/generators/katapult/haml/templates/index.html.haml +29 -0
- data/lib/generators/katapult/haml/templates/new.html.haml +4 -0
- data/lib/generators/katapult/haml/templates/show.html.haml +41 -0
- data/lib/generators/katapult/install/install_generator.rb +14 -0
- data/lib/generators/katapult/install/templates/lib/katapult/application_model.rb +18 -0
- data/lib/generators/katapult/model/model_generator.rb +59 -0
- data/lib/generators/katapult/model/templates/app/models/shared/does_flag.rb +32 -0
- data/lib/generators/katapult/model/templates/model.rb +21 -0
- data/lib/generators/katapult/model_specs/model_specs_generator.rb +51 -0
- data/lib/generators/katapult/model_specs/templates/model_spec.rb +34 -0
- data/lib/generators/katapult/navigation/navigation_generator.rb +25 -0
- data/lib/generators/katapult/navigation/templates/app/models/navigation.rb +12 -0
- data/lib/generators/katapult/transform/transform_generator.rb +47 -0
- data/lib/generators/katapult/w_u_i/templates/_route.rb +13 -0
- data/lib/generators/katapult/w_u_i/templates/controller.rb +106 -0
- data/lib/generators/katapult/w_u_i/w_u_i_generator.rb +57 -0
- data/lib/katapult.rb +5 -0
- data/lib/katapult/action.rb +44 -0
- data/lib/katapult/application_model.rb +45 -0
- data/lib/katapult/attribute.rb +83 -0
- data/lib/katapult/element.rb +72 -0
- data/lib/katapult/generator.rb +28 -0
- data/lib/katapult/model.rb +33 -0
- data/lib/katapult/navigation.rb +22 -0
- data/lib/katapult/parser.rb +39 -0
- data/lib/katapult/util.rb +16 -0
- data/lib/katapult/version.rb +3 -0
- data/lib/katapult/wui.rb +77 -0
- data/script/console +16 -0
- data/spec/action_spec.rb +44 -0
- data/spec/attribute_spec.rb +48 -0
- data/spec/model_spec.rb +18 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/util_spec.rb +23 -0
- data/spec/wui_spec.rb +49 -0
- metadata +253 -0
data/katapult.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'katapult/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'katapult'
|
8
|
+
spec.version = Katapult::VERSION
|
9
|
+
spec.authors = ['Dominik Schöler']
|
10
|
+
spec.email = ['dominik.schoeler@makandra.de']
|
11
|
+
spec.summary = %q{Kickstart Rails development}
|
12
|
+
spec.description = %q{Katapult is a framework for generating base code}
|
13
|
+
spec.homepage = 'https://github.com/makandra/katapult'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.required_ruby_version = '>= 2.0'
|
22
|
+
|
23
|
+
spec.add_runtime_dependency 'rails'
|
24
|
+
spec.add_runtime_dependency 'spring' # speed-up
|
25
|
+
|
26
|
+
# Development
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
28
|
+
spec.add_development_dependency 'rake'
|
29
|
+
spec.add_development_dependency 'pry'
|
30
|
+
|
31
|
+
# Testing
|
32
|
+
spec.add_development_dependency 'aruba'
|
33
|
+
spec.add_development_dependency 'guard-cucumber'
|
34
|
+
spec.add_development_dependency 'rspec'
|
35
|
+
end
|
data/katapult.png
ADDED
Binary file
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Generates model-independent application basics (see method names).
|
2
|
+
|
3
|
+
module Katapult
|
4
|
+
module Generators
|
5
|
+
class BasicsGenerator < Rails::Generators::Base
|
6
|
+
|
7
|
+
SKIP_GEMS = %w(sass-rails coffee-rails turbolinks sdoc uglifier)
|
8
|
+
|
9
|
+
desc 'Generate basics like test directories and gems'
|
10
|
+
source_root File.expand_path('../templates', __FILE__)
|
11
|
+
|
12
|
+
|
13
|
+
def write_database_ymls
|
14
|
+
template 'config/database.yml', force: true
|
15
|
+
template 'config/database.sample.yml'
|
16
|
+
end
|
17
|
+
|
18
|
+
# Overwrite Gemfile with the template, but transfer all gems that are not
|
19
|
+
# skipped (see SKIP_GEMS).
|
20
|
+
def enhance_gemfile
|
21
|
+
gem_lines = File.readlines('Gemfile').select{ |line| line =~ /^gem/ }
|
22
|
+
@original_gems = gem_lines.reject do |line|
|
23
|
+
line =~ /'(#{ SKIP_GEMS.join '|' })'/
|
24
|
+
end
|
25
|
+
|
26
|
+
template 'Gemfile', force: true
|
27
|
+
end
|
28
|
+
|
29
|
+
def bundle_install
|
30
|
+
bundle 'install'
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove_turbolinks_js
|
34
|
+
gsub_file 'app/assets/javascripts/application.js', "//= require turbolinks\n", ''
|
35
|
+
end
|
36
|
+
|
37
|
+
def setup_spring
|
38
|
+
bundle 'exec spring binstub --all'
|
39
|
+
template 'config/spring.rb'
|
40
|
+
run 'spring stop' # reload
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_modularity_load_paths
|
44
|
+
# This results in correct formatting :)
|
45
|
+
application <<-'LOAD_PATHS'
|
46
|
+
config.autoload_paths << "#{Rails.root}/app/controllers/shared"
|
47
|
+
config.autoload_paths << "#{Rails.root}/app/models/shared"
|
48
|
+
config.autoload_paths << "#{Rails.root}/app/util"
|
49
|
+
config.autoload_paths << "#{Rails.root}/app/util/shared"
|
50
|
+
LOAD_PATHS
|
51
|
+
end
|
52
|
+
|
53
|
+
def install_cucumber
|
54
|
+
generate 'cucumber:install'
|
55
|
+
|
56
|
+
template 'features/support/paths.rb'
|
57
|
+
template 'features/support/env-custom.rb'
|
58
|
+
end
|
59
|
+
|
60
|
+
def install_rspec
|
61
|
+
generate 'rspec:install'
|
62
|
+
|
63
|
+
# Do not show Ruby warnings in RSpec runs.
|
64
|
+
gsub_file '.rspec', "--warnings\n", ''
|
65
|
+
|
66
|
+
inject_into_file 'spec/rails_helper.rb', after: "require 'rspec/rails'\n" do
|
67
|
+
"require 'shoulda/matchers'\n"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def install_styles
|
72
|
+
remove_file 'app/assets/stylesheets/application.css'
|
73
|
+
directory 'app/assets/stylesheets', force: true
|
74
|
+
end
|
75
|
+
|
76
|
+
# def install_capistrano
|
77
|
+
# capify!
|
78
|
+
# template 'config/deploy.rb'
|
79
|
+
# end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def app_name
|
84
|
+
File.basename(Dir.pwd)
|
85
|
+
end
|
86
|
+
|
87
|
+
def bundle(command)
|
88
|
+
Bundler.with_clean_env do
|
89
|
+
run 'bundle ' + command
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# from original Gemfile
|
4
|
+
<%= @original_gems.join %>
|
5
|
+
|
6
|
+
# engines
|
7
|
+
gem 'haml-rails'
|
8
|
+
|
9
|
+
# internal
|
10
|
+
gem 'exception_notification'
|
11
|
+
gem 'breach-mitigation-rails'
|
12
|
+
|
13
|
+
# better coding
|
14
|
+
gem 'modularity'
|
15
|
+
gem 'edge_rider'
|
16
|
+
gem 'andand'
|
17
|
+
|
18
|
+
# models
|
19
|
+
gem 'has_defaults'
|
20
|
+
gem 'assignable_values'
|
21
|
+
|
22
|
+
# gem 'carrierwave'
|
23
|
+
# gem 'mini_magick'
|
24
|
+
|
25
|
+
# gem 'spreadsheet'
|
26
|
+
# gem 'vcard'
|
27
|
+
|
28
|
+
# views
|
29
|
+
# gem 'simple_form'
|
30
|
+
# gem 'nested_form'
|
31
|
+
gem 'will_paginate'
|
32
|
+
gem 'makandra-navy', require: 'navy'
|
33
|
+
|
34
|
+
# assets
|
35
|
+
gem 'bootstrap-sass'
|
36
|
+
gem 'sass-rails'
|
37
|
+
gem 'autoprefixer-rails'
|
38
|
+
gem 'coffee-rails'
|
39
|
+
gem 'uglifier'
|
40
|
+
gem 'compass-rails'
|
41
|
+
gem 'compass-rgbapng'
|
42
|
+
|
43
|
+
group :development do
|
44
|
+
gem 'query_diet'
|
45
|
+
gem 'better_errors'
|
46
|
+
gem 'binding_of_caller'
|
47
|
+
gem 'thin'
|
48
|
+
|
49
|
+
gem 'guard-livereload', require: false
|
50
|
+
gem 'rack-livereload'
|
51
|
+
gem 'spring-commands-rspec'
|
52
|
+
gem 'spring-commands-cucumber'
|
53
|
+
end
|
54
|
+
|
55
|
+
group :development, :test do
|
56
|
+
gem 'byebug'
|
57
|
+
gem 'factory_girl_rails'
|
58
|
+
gem 'rspec-rails'
|
59
|
+
end
|
60
|
+
|
61
|
+
group :test do
|
62
|
+
gem 'parallel_tests'
|
63
|
+
gem 'database_cleaner'
|
64
|
+
gem 'timecop'
|
65
|
+
gem 'launchy'
|
66
|
+
|
67
|
+
gem 'capybara'
|
68
|
+
gem 'cucumber-rails', require: false
|
69
|
+
gem 'cucumber_factory'
|
70
|
+
gem 'cucumber_spinner'
|
71
|
+
gem 'selenium-webdriver'
|
72
|
+
gem 'spreewald'
|
73
|
+
|
74
|
+
gem 'rspec_candy'
|
75
|
+
gem 'shoulda-matchers', require: false
|
76
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
@import compass/css3/box-shadow
|
2
|
+
@import bootstrap/variables
|
3
|
+
|
4
|
+
.layout
|
5
|
+
margin: 100px auto
|
6
|
+
width: 800px
|
7
|
+
|
8
|
+
background-color: white
|
9
|
+
+single-box-shadow
|
10
|
+
|
11
|
+
.layout__head
|
12
|
+
padding: 10px 35px
|
13
|
+
|
14
|
+
color: #fff
|
15
|
+
background-color: $brand-primary
|
16
|
+
|
17
|
+
.layout__main
|
18
|
+
padding: 20px 35px
|
19
|
+
|
20
|
+
.layout__tail
|
21
|
+
padding: 10px 35px
|
22
|
+
|
23
|
+
color: $gray-light
|
24
|
+
background-color: $gray-lighter
|
25
|
+
border-top: 1px solid darken($gray-lighter, 10%)
|
26
|
+
font-size: $font-size-small
|
@@ -0,0 +1,16 @@
|
|
1
|
+
common: &common
|
2
|
+
adapter: mysql2
|
3
|
+
encoding: utf8
|
4
|
+
username: root
|
5
|
+
password:
|
6
|
+
|
7
|
+
development:
|
8
|
+
<<: *common
|
9
|
+
database: <%= app_name %>_development
|
10
|
+
|
11
|
+
test: &test
|
12
|
+
<<: *common
|
13
|
+
database: <%= app_name %>_test<%%= ENV['TEST_ENV_NUMBER'] %>
|
14
|
+
|
15
|
+
cucumber:
|
16
|
+
<<: *test
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module NavigationHelpers
|
2
|
+
|
3
|
+
def path_to(page_name)
|
4
|
+
case page_name
|
5
|
+
|
6
|
+
when /^the list of (.*?)$/
|
7
|
+
models_prose = $1
|
8
|
+
route = "#{model_prose_to_route_segment(models_prose)}_path"
|
9
|
+
send(route)
|
10
|
+
|
11
|
+
when /^the (page|form) for the (.*?) above$/
|
12
|
+
action_prose, model_prose = $1, $2
|
13
|
+
route = "#{action_prose == 'form' ? 'edit_' : ''}#{model_prose_to_route_segment(model_prose)}_path"
|
14
|
+
model = model_prose.classify.constantize
|
15
|
+
send(route, model.last)
|
16
|
+
|
17
|
+
when /^the (page|form) for the (.*?) "(.*?)"$/
|
18
|
+
action_prose, model_prose, identifier = $1, $2, $3
|
19
|
+
path_to_show_or_edit(action_prose, model_prose, identifier)
|
20
|
+
|
21
|
+
when /^the (.*?) (page|form) for "(.*?)"$/
|
22
|
+
model_prose, action_prose, identifier = $1, $2, $3
|
23
|
+
path_to_show_or_edit(action_prose, model_prose, identifier)
|
24
|
+
|
25
|
+
when /^the (.*?) form$/
|
26
|
+
model_prose = $1
|
27
|
+
route = "new_#{model_prose_to_route_segment(model_prose)}_path"
|
28
|
+
send(route)
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def path_to_show_or_edit(action_prose, model_prose, identifier)
|
36
|
+
model = model_prose.classify.constantize
|
37
|
+
route = "#{action_prose == 'form' ? 'edit_' : ''}#{model_prose_to_route_segment(model_prose)}_path"
|
38
|
+
send(route, model.find_by_anything!(identifier))
|
39
|
+
end
|
40
|
+
|
41
|
+
def model_prose_to_route_segment(model_prose)
|
42
|
+
model_prose.gsub(/[\ \/]/, '_')
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
World(NavigationHelpers)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'katapult/generator'
|
2
|
+
|
3
|
+
module Katapult
|
4
|
+
module Generators
|
5
|
+
class CucumberFeaturesGenerator < Katapult::Generator
|
6
|
+
|
7
|
+
desc 'Generate Cucumber features for CRUD'
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
9
|
+
|
10
|
+
|
11
|
+
def create_crud_feature
|
12
|
+
template 'feature.feature', "features/#{model.name(:variables)}.feature"
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def model
|
18
|
+
@element
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
Feature: <%= model.name(:human_plural).titleize %>
|
2
|
+
|
3
|
+
Scenario: CRUD <%= model.name(:human_plural) %>
|
4
|
+
Given I am on the list of <%= model.name(:variables) %>
|
5
|
+
|
6
|
+
# create
|
7
|
+
When I follow "Add <%= model.name(:variable) %>"
|
8
|
+
<% model.attrs.each do |attr| -%>
|
9
|
+
<%- if attr.assignable_values -%>
|
10
|
+
And I select "<%= attr.test_value %>" from "<%= attr.name.humanize %>"
|
11
|
+
<%- else -%>
|
12
|
+
<%- case attr.type -%>
|
13
|
+
<%- when :string, :email, :url, :integer, :money, :text, :markdown, :datetime -%>
|
14
|
+
And I fill in "<%= attr.name.humanize %>" with "<%= attr.test_value %>"
|
15
|
+
<%- when :flag -%>
|
16
|
+
And I check "<%= attr.name.humanize %>"
|
17
|
+
<%- end -%>
|
18
|
+
<%- end -%>
|
19
|
+
<% end -%>
|
20
|
+
And I press "Save"
|
21
|
+
|
22
|
+
# read
|
23
|
+
Then I should be on the page for the <%= model.name(:variable) %> above
|
24
|
+
<% model.attrs.each do |attr| -%>
|
25
|
+
<%- case attr.type -%>
|
26
|
+
<%- when :string, :email, :url, :integer, :money, :text, :markdown -%>
|
27
|
+
And I should see "<%= attr.test_value %>"
|
28
|
+
<%- when :flag -%>
|
29
|
+
And I should see "<%= attr.name.humanize %> Yes"
|
30
|
+
<%- when :datetime -%>
|
31
|
+
And I should see "<%= I18n.localize(attr.test_value) %>"
|
32
|
+
<%- end -%>
|
33
|
+
<% end -%>
|
34
|
+
|
35
|
+
# update
|
36
|
+
When I follow "Edit"
|
37
|
+
Then I should be on the form for the <%= model.name(:variable) %> above
|
38
|
+
<% model.attrs.each do |attr| -%>
|
39
|
+
<%- if attr.assignable_values -%>
|
40
|
+
And "<%= attr.test_value %>" should be selected for "<%= attr.name.humanize %>"
|
41
|
+
<%- else -%>
|
42
|
+
<%- case attr.type -%>
|
43
|
+
<%- when :string, :email, :url, :integer, :money, :text, :markdown, :datetime -%>
|
44
|
+
And the "<%= attr.name.humanize %>" field should contain "<%= attr.test_value %>"
|
45
|
+
<%- when :flag -%>
|
46
|
+
And the "<%= attr.name.humanize %>" checkbox should be checked
|
47
|
+
<%- end -%>
|
48
|
+
<%- end -%>
|
49
|
+
<% end -%>
|
50
|
+
|
51
|
+
<% if model.label_attr # do not crash when the model has no label attr -%>
|
52
|
+
# destroy
|
53
|
+
When I go to the list of <%= model.name(:variables) %>
|
54
|
+
Then I should see "<%= model.label_attr.test_value %>"
|
55
|
+
|
56
|
+
When I follow "Destroy"
|
57
|
+
Then I should be on the list of <%= model.name(:variables) %>
|
58
|
+
But I should not see "<%= model.label_attr.test_value %>"
|
59
|
+
<% end -%>
|