katapult 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +57 -9
- data/bin/katapult +7 -3
- data/features/application_model.feature +4 -1
- data/features/authenticate.feature +1 -18
- data/features/basics.feature +1 -0
- data/features/binary.feature +5 -7
- data/features/model.feature +42 -3
- data/features/step_definitions/rails_steps.rb +1 -1
- data/features/web_ui.feature +17 -5
- data/lib/generators/katapult/app_model/templates/lib/katapult/application_model.rb +3 -0
- data/lib/generators/katapult/basics/basics_generator.rb +3 -8
- data/lib/generators/katapult/basics/templates/README.md.tt +33 -0
- data/lib/generators/katapult/basics/templates/features/support/paths.rb +1 -1
- data/lib/generators/katapult/clearance/clearance_generator.rb +6 -2
- data/lib/generators/katapult/clearance/templates/config/initializers/clearance.rb +1 -0
- data/lib/generators/katapult/cucumber_features/cucumber_features_generator.rb +10 -0
- data/lib/generators/katapult/cucumber_features/templates/feature.feature +4 -3
- data/lib/generators/katapult/model/model_generator.rb +15 -0
- data/lib/generators/katapult/model/templates/model.rb +13 -3
- data/lib/generators/katapult/model_specs/model_specs_generator.rb +1 -1
- data/lib/generators/katapult/model_specs/templates/model_spec.rb +1 -1
- data/lib/generators/katapult/transform/transform_generator.rb +4 -7
- data/lib/generators/katapult/views/templates/_form.html.haml +16 -13
- data/lib/generators/katapult/views/templates/show.html.haml +2 -0
- data/lib/katapult/application_model.rb +68 -19
- data/lib/katapult/element.rb +13 -18
- data/lib/katapult/{action.rb → elements/action.rb} +0 -0
- data/lib/katapult/elements/association.rb +35 -0
- data/lib/katapult/{attribute.rb → elements/attribute.rb} +14 -5
- data/lib/katapult/{authentication.rb → elements/authentication.rb} +2 -5
- data/lib/katapult/elements/model.rb +76 -0
- data/lib/katapult/{navigation.rb → elements/navigation.rb} +0 -0
- data/lib/katapult/{web_ui.rb → elements/web_ui.rb} +2 -12
- data/lib/katapult/generator.rb +2 -2
- data/lib/katapult/{binary_util.rb → support/binary_util.rb} +2 -1
- data/lib/katapult/{generator_goodies.rb → support/generator_goodies.rb} +9 -2
- data/lib/katapult/version.rb +1 -1
- data/script/console +5 -2
- data/script/update +1 -1
- data/spec/action_spec.rb +1 -1
- data/spec/application_model_spec.rb +26 -0
- data/spec/association_spec.rb +12 -0
- data/spec/attribute_spec.rb +35 -1
- data/spec/model_spec.rb +5 -2
- data/spec/util_spec.rb +1 -1
- data/spec/web_ui_spec.rb +11 -33
- metadata +17 -13
- data/lib/katapult/model.rb +0 -45
- data/lib/katapult/parser.rb +0 -53
- data/spec/parser_spec.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f4099dfe92529880417ce7c3ac5204b70fc115b33a6b60b0027d75c6f7e001e3
|
4
|
+
data.tar.gz: 688a93e927f9240fc0d6e67caceeaae882438c9f5114618f051fda4c5063495f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a2a28034878af36af8c5251550c87b257091d4ddadc0e923a7845ea4ace323660040c50de547f7460153fac5df88520bbe10558870a6ec6de9f22153300c5e4
|
7
|
+
data.tar.gz: 405ae1ffbdd3172e78f5e2aced6bf4096e400b5ca30d86aaa6f23b8ed10e0875c6de048d5da11e333f20709644e4fb21c6941a8e68b5e7c83eb1590ff4256f41
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 0.4.0 on 2018-01-15
|
4
|
+
|
5
|
+
### Features
|
6
|
+
- Support for has_many/belongs_to associations
|
7
|
+
- Create a project README
|
8
|
+
- New CHANGELOG
|
9
|
+
|
10
|
+
### Fixes
|
11
|
+
- Models now inherit from `ApplicationRecord`
|
12
|
+
|
13
|
+
|
14
|
+
## 0.3.0 on 2018-01-11
|
15
|
+
|
16
|
+
### Features
|
17
|
+
- Generating a Rails 5.1.4 app on Ruby 2.5.0
|
18
|
+
- Dropped asset pipeline in favor of Webpacker
|
19
|
+
- The generated application now has a sleek, simple design based on Bootstrap
|
20
|
+
- Employing [Unpoly](https://unpoly.com)
|
21
|
+
- New DSL command `crud` for creating Model plus WebUI
|
22
|
+
- The generated application model is now a transformable example of katapult's features
|
23
|
+
|
24
|
+
### Development improvements
|
25
|
+
- Add katapult update script
|
26
|
+
- Speed up tests (now running in about 9 min)
|
27
|
+
- Improve development workflow (see README)
|
28
|
+
- No bundler issues in tests any more
|
29
|
+
|
30
|
+
See [all changes](https://github.com/makandra/katapult/compare/v0.2.0...v0.3.0).
|
data/README.md
CHANGED
@@ -99,15 +99,18 @@ has the following syntax, taking a name, options, and a block:
|
|
99
99
|
|
100
100
|
|
101
101
|
### Model
|
102
|
-
Takes a name and a block
|
102
|
+
Takes a name and a block. Generates a Rails model, a migration, and a spec.
|
103
103
|
|
104
104
|
model 'Customer' do |customer|
|
105
105
|
# customer.attr :name etc, see Attribute element
|
106
|
+
# customer.belongs_to :group, see Association element
|
106
107
|
end
|
107
108
|
|
108
109
|
|
109
110
|
#### Attribute
|
110
|
-
Defined on Model
|
111
|
+
Defined on Model; takes a name and options. Adds a database field in the model
|
112
|
+
migration, form fields in a WebUI, and configuration code in the model as
|
113
|
+
needed.
|
111
114
|
|
112
115
|
# Default type :string
|
113
116
|
model.attr :name
|
@@ -136,8 +139,21 @@ Defined on Model. Takes a name and options:
|
|
136
139
|
model.attr :avoid, type: :plain_json # PostgreSQL "json"
|
137
140
|
|
138
141
|
|
142
|
+
### Association
|
143
|
+
Defined on Model; takes the name of another model just like you called it in the
|
144
|
+
model. Adds a foreign key attribute to the model and `belongs_to`/`has_many`
|
145
|
+
calls to the respective models.
|
146
|
+
|
147
|
+
model 'Customer' do |customer|
|
148
|
+
customer.belongs_to 'Group'
|
149
|
+
end
|
150
|
+
|
151
|
+
model 'Group'
|
152
|
+
|
153
|
+
|
139
154
|
### WebUI
|
140
|
-
Takes a name, options and a block
|
155
|
+
Takes a name, options and a block. Generates controller, routes, views, and a
|
156
|
+
passing Cucumber feature.
|
141
157
|
|
142
158
|
web_ui 'Customer', model: 'User' do |web_ui|
|
143
159
|
web_ui.crud # Create all the standard rails actions
|
@@ -150,7 +166,8 @@ Takes a name, options and a block:
|
|
150
166
|
|
151
167
|
|
152
168
|
#### Action
|
153
|
-
Defined on WebUI
|
169
|
+
Defined on WebUI; takes a name and options. Adds an action to the controller,
|
170
|
+
and a route as needed.
|
154
171
|
|
155
172
|
# Select single Rails actions
|
156
173
|
web_ui.action :index
|
@@ -164,7 +181,7 @@ Defined on WebUI. Takes a name and options:
|
|
164
181
|
web_ui.action :other_action, method: :get, scope: :collection
|
165
182
|
|
166
183
|
### Crud
|
167
|
-
|
184
|
+
Shortcut for creating a model together with a WebUI with CRUD actions.
|
168
185
|
|
169
186
|
crud 'Customer' do |customer|
|
170
187
|
customer.attr :name
|
@@ -172,8 +189,7 @@ This is a shortcut for creating a model together with a WebUI with CRUD actions.
|
|
172
189
|
|
173
190
|
|
174
191
|
### Navigation
|
175
|
-
|
176
|
-
WebUIs.
|
192
|
+
Generates a main menu with links to the index pages of all WebUIs.
|
177
193
|
|
178
194
|
navigation
|
179
195
|
|
@@ -184,8 +200,8 @@ email address. Generates authentication with [Clearance](https://github.com/thou
|
|
184
200
|
|
185
201
|
authenticate 'User', system_email: 'system@example.com'
|
186
202
|
|
187
|
-
The email address will be the sender for
|
188
|
-
requests.
|
203
|
+
The given email address will be configured as the sender for all mails sent by
|
204
|
+
Rails, including Clearance mails like password reset requests.
|
189
205
|
|
190
206
|
|
191
207
|
## Development
|
@@ -204,6 +220,31 @@ Create a dedicated account on your local PostgreSQL server:
|
|
204
220
|
Whenever you start working on `katapult`, you should run `script/update`, which
|
205
221
|
will guide you through a quick update process.
|
206
222
|
|
223
|
+
### Architecture
|
224
|
+
`katapult` is roughly split into three parts: the `katapult` binary in bin/,
|
225
|
+
the model in lib/katapult/ and the generators in lib/generators. Also, there
|
226
|
+
is a script/ directory that holds some scripts to ease development. It is not
|
227
|
+
part of the `katapult` gem, however.
|
228
|
+
|
229
|
+
The generators of `katapult` base on the `rails/generators` you probably know
|
230
|
+
from generating migration files or scaffolds; however, it lifts their usage on a
|
231
|
+
new level by invoking generators programmatically with a "model object". Instead
|
232
|
+
of plain text input, the `katapult` generators can explore the whole application
|
233
|
+
model. They are all to be run from within a Rails application.
|
234
|
+
|
235
|
+
There are three base generators that can be considered the next-lower level API
|
236
|
+
of `katapult`:
|
237
|
+
|
238
|
+
- `basics` generator: Enhances a pristine Rails app with all of the basic
|
239
|
+
configuration `katapult` brings.
|
240
|
+
- `app_model` generator: Installs a boilerplate application model that serves as
|
241
|
+
a starting point for modeling your own application.
|
242
|
+
- `transform` generator: Parses the application model into an internal
|
243
|
+
representation, which will be turned into code by all the other generators.
|
244
|
+
|
245
|
+
Note that the `katapult` binary is the only Rails-independent part of Katapult;
|
246
|
+
everything else runs in the context of the Rails appplication.
|
247
|
+
|
207
248
|
### Suggested workflow
|
208
249
|
When adding a feature to `katapult`, it will usually take you some time to
|
209
250
|
figure out how exactly the generated code should look like. You'll be switching
|
@@ -225,6 +266,13 @@ Here's a the suggested process:
|
|
225
266
|
7) Remove the @no-clobber tag and run the scenario normally to see if it's still
|
226
267
|
green. Remember to stop the development server first.
|
227
268
|
|
269
|
+
### Guidelines
|
270
|
+
Please respect the following guidelines during development:
|
271
|
+
|
272
|
+
- The application model should be order-agnostic. There is a #prepare_render
|
273
|
+
method in `ApplicationModel` for things that need to happen between parsing
|
274
|
+
and rendering the application model.
|
275
|
+
|
228
276
|
### Debugging
|
229
277
|
Add the `@announce-output` tag to `katapult` features in order to have any output
|
230
278
|
logged to your terminal. Note that each step will print all output to date, so
|
data/bin/katapult
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
usage = 'Usage: katapult new APP_NAME | fire [path/to/model] | version'
|
7
7
|
|
8
8
|
require_relative '../lib/katapult/version'
|
9
|
-
require_relative '../lib/katapult/binary_util'
|
9
|
+
require_relative '../lib/katapult/support/binary_util'
|
10
10
|
util = Katapult::BinaryUtil
|
11
11
|
|
12
12
|
require 'optparse'
|
@@ -74,8 +74,12 @@ when 'new'
|
|
74
74
|
util.pink <<-INSTRUCTIONS
|
75
75
|
Application initialization done.
|
76
76
|
|
77
|
-
Next
|
78
|
-
|
77
|
+
Next steps:
|
78
|
+
|
79
|
+
- Model your application in lib/katapult/application_model.rb and transform it
|
80
|
+
into code by running `katapult fire`
|
81
|
+
- Configure public/robots.txt
|
82
|
+
- Write a README
|
79
83
|
INSTRUCTIONS
|
80
84
|
|
81
85
|
when 'fire'
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#@announce-output
|
2
|
-
Feature: The application model prepared by Katapult
|
2
|
+
Feature: The default application model prepared by Katapult
|
3
3
|
|
4
4
|
Scenario: Generating the application model template
|
5
5
|
Given a new Rails application with Katapult basics installed
|
@@ -19,6 +19,9 @@ Feature: The application model prepared by Katapult
|
|
19
19
|
product.attr :mode, assignable_values: %w[public private]
|
20
20
|
product.attr :provider, type: :url
|
21
21
|
product.attr :import_data, type: :json
|
22
|
+
|
23
|
+
# Reference other models just like you called them
|
24
|
+
product.belongs_to 'user'
|
22
25
|
end
|
23
26
|
|
24
27
|
# Define a model
|
@@ -170,24 +170,7 @@ Feature: Add authentication to an application
|
|
170
170
|
config.middleware.use Clearance::BackDoor
|
171
171
|
|
172
172
|
"""
|
173
|
-
And the file "config/initializers/clearance.rb" should contain
|
174
|
-
"""
|
175
|
-
Clearance.configure do |config|
|
176
|
-
config.allow_sign_up = false
|
177
|
-
# config.cookie_domain = '.example.com'
|
178
|
-
# config.cookie_expiration = lambda { |cookies| 1.year.from_now.utc }
|
179
|
-
# config.cookie_name = 'remember_token'
|
180
|
-
# config.cookie_path = '/'
|
181
|
-
config.routes = false
|
182
|
-
# config.httponly = true
|
183
|
-
config.mailer_sender = 'system@example.com'
|
184
|
-
# config.password_strategy = Clearance::PasswordStrategies::BCrypt
|
185
|
-
# config.redirect_url = '/'
|
186
|
-
# config.secure_cookie = true
|
187
|
-
# config.sign_in_guards = []
|
188
|
-
# config.user_model = User
|
189
|
-
end
|
190
|
-
"""
|
173
|
+
And the file "config/initializers/clearance.rb" should contain " config.mailer_sender = 'system@example.com'"
|
191
174
|
And a file named "config/locales/clearance.en.yml" should exist
|
192
175
|
And the file "config/routes.rb" should contain:
|
193
176
|
"""
|
data/features/basics.feature
CHANGED
@@ -10,6 +10,7 @@ Feature: Preparation of a new Rails app (basics generator)
|
|
10
10
|
Then the ruby-version file should be up-to-date
|
11
11
|
|
12
12
|
And the file ".gitignore" should contain "config/database.yml"
|
13
|
+
And the file "README.md" should contain "# Katapult Test App"
|
13
14
|
And the file ".bundle/config" should match /NOKOGIRI.*--use-system-libraries/
|
14
15
|
And the file "Guardfile" should contain:
|
15
16
|
"""
|
data/features/binary.feature
CHANGED
@@ -44,13 +44,11 @@ Feature: Katapult binary `katapult`
|
|
44
44
|
And the output should contain "Installing katapult"
|
45
45
|
And the output should contain "Generating katapult basics"
|
46
46
|
And the output should contain the configured Rails version
|
47
|
-
And the output should contain:
|
48
|
-
"""
|
49
|
-
Application initialization done.
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
And the output should contain "Application initialization done."
|
49
|
+
And the output should contain "Model your application in lib/katapult/application_model.rb"
|
50
|
+
And the output should contain "Configure public/robots.txt"
|
51
|
+
And the output should contain "Write a README"
|
54
52
|
|
55
53
|
When I cd to "binary_test"
|
56
54
|
Then the file "Gemfile" should contain "gem 'katapult'"
|
@@ -69,7 +67,7 @@ Feature: Katapult binary `katapult`
|
|
69
67
|
And the output should contain "Author: katapult <katapult@makandra.com>"
|
70
68
|
|
71
69
|
|
72
|
-
Scenario: Transform the application model
|
70
|
+
Scenario: Transform the default application model
|
73
71
|
Given a new Rails application with Katapult basics installed
|
74
72
|
And the default aruba exit timeout is 45 seconds
|
75
73
|
|
data/features/model.feature
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#@announce-output
|
2
|
+
#@announce-stderr
|
2
3
|
Feature: Generate Models
|
3
4
|
|
4
5
|
Background:
|
@@ -13,11 +14,13 @@ Feature: Generate Models
|
|
13
14
|
And I successfully transform the application model
|
14
15
|
Then the file "app/models/car.rb" should contain exactly:
|
15
16
|
"""
|
16
|
-
class Car <
|
17
|
+
class Car < ApplicationRecord
|
18
|
+
|
17
19
|
|
18
20
|
def to_s
|
19
21
|
"Car##{id}"
|
20
22
|
end
|
23
|
+
|
21
24
|
end
|
22
25
|
|
23
26
|
"""
|
@@ -47,6 +50,10 @@ Feature: Generate Models
|
|
47
50
|
end
|
48
51
|
|
49
52
|
"""
|
53
|
+
And the file "spec/factories/factories.rb" should contain:
|
54
|
+
"""
|
55
|
+
factory :car
|
56
|
+
"""
|
50
57
|
|
51
58
|
|
52
59
|
Scenario: Generate ActiveRecord Model with attributes
|
@@ -72,13 +79,16 @@ Feature: Generate Models
|
|
72
79
|
And I successfully transform the application model including migrations
|
73
80
|
Then the file "app/models/person.rb" should contain exactly:
|
74
81
|
"""
|
75
|
-
class Person <
|
82
|
+
class Person < ApplicationRecord
|
83
|
+
|
76
84
|
include DoesFlag[:locked, default: false]
|
85
|
+
|
77
86
|
has_defaults({:homepage=>"http://www.makandra.de"})
|
78
87
|
|
79
88
|
def to_s
|
80
89
|
age.to_s
|
81
90
|
end
|
91
|
+
|
82
92
|
end
|
83
93
|
|
84
94
|
"""
|
@@ -148,6 +158,31 @@ Feature: Generate Models
|
|
148
158
|
Then the output should contain "Katapult::Attribute does not support option :invalid_option. (Katapult::Element::UnknownOptionError)"
|
149
159
|
|
150
160
|
|
161
|
+
Scenario: Specify model associations
|
162
|
+
When I write to "lib/katapult/application_model.rb" with:
|
163
|
+
"""
|
164
|
+
model('Company') { |c| c.attr :name }
|
165
|
+
model 'User' do |user|
|
166
|
+
user.belongs_to 'Company'
|
167
|
+
end
|
168
|
+
"""
|
169
|
+
And I successfully transform the application model including migrations
|
170
|
+
Then the file "app/models/company.rb" should contain "has_many :users"
|
171
|
+
And the file "app/models/user.rb" should contain "belongs_to :company"
|
172
|
+
And the file "app/models/user.rb" should contain:
|
173
|
+
"""
|
174
|
+
assignable_values_for :company, {:allow_blank=>true} do
|
175
|
+
Company.all.to_a
|
176
|
+
end
|
177
|
+
"""
|
178
|
+
|
179
|
+
And there should be a migration with:
|
180
|
+
"""
|
181
|
+
create_table :users do |t|
|
182
|
+
t.integer :company_id
|
183
|
+
"""
|
184
|
+
|
185
|
+
|
151
186
|
Scenario: Specify assignable values
|
152
187
|
When I write to "lib/katapult/application_model.rb" with:
|
153
188
|
"""
|
@@ -159,10 +194,13 @@ Feature: Generate Models
|
|
159
194
|
And I successfully transform the application model including migrations
|
160
195
|
Then the file "app/models/person.rb" should contain exactly:
|
161
196
|
"""
|
162
|
-
class Person <
|
197
|
+
class Person < ApplicationRecord
|
198
|
+
|
199
|
+
|
163
200
|
assignable_values_for :age, {} do
|
164
201
|
9..99
|
165
202
|
end
|
203
|
+
|
166
204
|
assignable_values_for :hobby, {:allow_blank=>true, :default=>"soccer"} do
|
167
205
|
["soccer", "baseball"]
|
168
206
|
end
|
@@ -170,6 +208,7 @@ Feature: Generate Models
|
|
170
208
|
def to_s
|
171
209
|
age.to_s
|
172
210
|
end
|
211
|
+
|
173
212
|
end
|
174
213
|
|
175
214
|
"""
|
data/features/web_ui.feature
CHANGED
@@ -9,7 +9,7 @@ Feature: Web User Interface
|
|
9
9
|
Scenario: Generate a Web User Interface
|
10
10
|
When I write to "lib/katapult/application_model.rb" with:
|
11
11
|
"""
|
12
|
-
|
12
|
+
crud 'customer' do |customer|
|
13
13
|
customer.attr :name
|
14
14
|
customer.attr :age, type: :integer
|
15
15
|
|
@@ -22,11 +22,11 @@ Feature: Web User Interface
|
|
22
22
|
customer.attr :first_visit, type: :datetime
|
23
23
|
customer.attr :indexable_data, type: :json
|
24
24
|
customer.attr :plain_data, type: :plain_json
|
25
|
-
end
|
26
25
|
|
27
|
-
|
28
|
-
web_ui.crud
|
26
|
+
customer.belongs_to 'project'
|
29
27
|
end
|
28
|
+
|
29
|
+
model('project') { |p| p.attr :title }
|
30
30
|
"""
|
31
31
|
And I successfully transform the application model including migrations
|
32
32
|
Then the file "app/controllers/customers_controller.rb" should contain exactly:
|
@@ -107,6 +107,7 @@ Feature: Web User Interface
|
|
107
107
|
:first_visit,
|
108
108
|
:indexable_data,
|
109
109
|
:plain_data,
|
110
|
+
:project_id,
|
110
111
|
)
|
111
112
|
end
|
112
113
|
|
@@ -195,6 +196,10 @@ Feature: Web User Interface
|
|
195
196
|
= Customer.human_attribute_name(:first_visit)
|
196
197
|
%dd
|
197
198
|
= l(@customer.first_visit.to_date) if @customer.first_visit
|
199
|
+
%dt
|
200
|
+
= Customer.human_attribute_name(:project_id)
|
201
|
+
%dd
|
202
|
+
= @customer.project
|
198
203
|
|
199
204
|
"""
|
200
205
|
And the file "app/views/customers/new.html.haml" should contain exactly:
|
@@ -250,6 +255,10 @@ Feature: Web User Interface
|
|
250
255
|
.form-group
|
251
256
|
= form.label :first_visit
|
252
257
|
= form.date_field :first_visit, class: 'form-control'
|
258
|
+
.form-group
|
259
|
+
= form.label :project_id
|
260
|
+
= form.collection_select :project_id, form.object.assignable_projects,
|
261
|
+
:id, :title, { include_blank: true }, class: 'form-control'
|
253
262
|
|
254
263
|
.action-bar
|
255
264
|
- cancel_path = @customer.new_record? ? customers_path : customer_path(@customer)
|
@@ -272,6 +281,7 @@ Feature: Web User Interface
|
|
272
281
|
|
273
282
|
Scenario: CRUD customers
|
274
283
|
Given I am on the list of customers
|
284
|
+
And there is a project with the title "title-string"
|
275
285
|
|
276
286
|
# create
|
277
287
|
When I follow "Add customer"
|
@@ -284,6 +294,7 @@ Feature: Web User Interface
|
|
284
294
|
And I check "Locked"
|
285
295
|
And I fill in "Notes" with "notes-text"
|
286
296
|
And I fill in "First visit" with "2022-03-25"
|
297
|
+
And I select "title-string" from "Project"
|
287
298
|
And I press "Save"
|
288
299
|
|
289
300
|
# read
|
@@ -296,6 +307,7 @@ Feature: Web User Interface
|
|
296
307
|
And I should see "Locked Yes"
|
297
308
|
And I should see "notes-text"
|
298
309
|
And I should see "2022-03-25"
|
310
|
+
And I should see "title-string"
|
299
311
|
|
300
312
|
# update
|
301
313
|
When I follow "Edit"
|
@@ -308,6 +320,7 @@ Feature: Web User Interface
|
|
308
320
|
And the "Locked" checkbox should be checked
|
309
321
|
And the "Notes" field should contain "notes-text"
|
310
322
|
And the "First visit" field should contain "2022-03-25"
|
323
|
+
And "title-string" should be selected for "Project"
|
311
324
|
|
312
325
|
# destroy
|
313
326
|
When I go to the list of customers
|
@@ -318,7 +331,6 @@ Feature: Web User Interface
|
|
318
331
|
But I should not see "name-string"
|
319
332
|
|
320
333
|
"""
|
321
|
-
|
322
334
|
When I run cucumber
|
323
335
|
Then the features should pass
|
324
336
|
|
@@ -13,6 +13,9 @@ crud 'product' do |product|
|
|
13
13
|
product.attr :mode, assignable_values: %w[public private]
|
14
14
|
product.attr :provider, type: :url
|
15
15
|
product.attr :import_data, type: :json
|
16
|
+
|
17
|
+
# Reference other models just like you called them
|
18
|
+
product.belongs_to 'user'
|
16
19
|
end
|
17
20
|
|
18
21
|
# Define a model
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Generates model-independent application basics (see method names).
|
2
2
|
|
3
|
-
require 'katapult/generator_goodies'
|
3
|
+
require 'katapult/support/generator_goodies'
|
4
4
|
require 'katapult/version' # For writing .ruby-version
|
5
5
|
|
6
6
|
module Katapult
|
@@ -26,16 +26,11 @@ module Katapult
|
|
26
26
|
class_option :db_password, type: :string, default: '',
|
27
27
|
description: 'The password to set in config/database.yml'
|
28
28
|
|
29
|
-
def
|
29
|
+
def add_basic_files
|
30
30
|
template '.ruby-version'
|
31
|
-
end
|
32
|
-
|
33
|
-
def add_gitignore
|
34
31
|
template '.gitignore', force: true
|
35
|
-
end
|
36
|
-
|
37
|
-
def add_robots_txt
|
38
32
|
template 'public/robots.txt', force: true
|
33
|
+
template 'README.md', force: true
|
39
34
|
end
|
40
35
|
|
41
36
|
# Gems ###################################################################
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# <%= app_name(:human) %>
|
2
|
+
|
3
|
+
Describe the whole project in a few sentences to a few paragraphs, just as you
|
4
|
+
would explain it to your fellow developer. What is it actually, what was it
|
5
|
+
built for, who is using it, etc
|
6
|
+
|
7
|
+
See <https://makandracards.com/makandra/48339>.
|
8
|
+
|
9
|
+
|
10
|
+
## Architecture and models
|
11
|
+
|
12
|
+
Give a quick overview of the few core models and how they interact. Do not go
|
13
|
+
into detail – class documentation should be written atop the class file. Just
|
14
|
+
impart the very basics to grasp the application model, so a new developer knows
|
15
|
+
where to dive in.
|
16
|
+
|
17
|
+
|
18
|
+
## Development
|
19
|
+
|
20
|
+
Describe how to get started with the project. Document employed 3rd party
|
21
|
+
services and how to use them, how to start a development server – just about
|
22
|
+
anything that a new developer needs to know.
|
23
|
+
|
24
|
+
|
25
|
+
## Peculiarity X
|
26
|
+
|
27
|
+
Add a section for each special concept in the application, e.g. a CDN and what
|
28
|
+
it is used for, that icons are rendered from a custom icon font and how to update
|
29
|
+
it, that all posts are created from an importer, that there's a web UI *and* a
|
30
|
+
JSON API *and* an embeddable component.
|
31
|
+
|
32
|
+
Make the reader aware of a peculiarity, but remember to keep it short. Details
|
33
|
+
should be documented in the respective area.
|
@@ -15,7 +15,7 @@ module NavigationHelpers
|
|
15
15
|
action_prose, model_prose = $1, $2
|
16
16
|
route = "#{action_prose == 'form' ? 'edit_' : ''}#{model_prose_to_route_segment(model_prose)}_path"
|
17
17
|
model = model_prose_to_class(model_prose)
|
18
|
-
send(route, model.last)
|
18
|
+
send(route, model.reorder(:id).last!)
|
19
19
|
|
20
20
|
when /^the (page|form) for the (.*?) "(.*?)"$/
|
21
21
|
action_prose, model_prose, identifier = $1, $2, $3
|
@@ -19,7 +19,7 @@ module Katapult
|
|
19
19
|
|
20
20
|
def install_clearance
|
21
21
|
insert_into_file 'Gemfile', <<-GEM, before: "gem 'katapult'"
|
22
|
-
gem 'clearance'
|
22
|
+
gem 'clearance'
|
23
23
|
|
24
24
|
GEM
|
25
25
|
run 'bundle install --quiet'
|
@@ -122,8 +122,12 @@ resources :users do
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def add_user_factory
|
125
|
-
|
125
|
+
factories_file = 'spec/factories/factories.rb'
|
126
126
|
|
127
|
+
# Remove empty factory, if it exists
|
128
|
+
gsub_file factories_file, " factory :user\n\n", ''
|
129
|
+
|
130
|
+
inject_into_file factories_file, <<-'CONTENT', before: /end\n\z/
|
127
131
|
factory :user do
|
128
132
|
sequence(:email) { |i| "user-#{ i }@example.com" }
|
129
133
|
password 'password'
|
@@ -12,12 +12,22 @@ module Katapult
|
|
12
12
|
template 'feature.feature', "features/#{model.name(:variables)}.feature"
|
13
13
|
end
|
14
14
|
|
15
|
+
no_tasks do
|
16
|
+
def belongs_tos
|
17
|
+
app_model.get_belongs_tos_for model.name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
15
21
|
private
|
16
22
|
|
17
23
|
def model
|
18
24
|
@element
|
19
25
|
end
|
20
26
|
|
27
|
+
def app_model
|
28
|
+
model.application_model
|
29
|
+
end
|
30
|
+
|
21
31
|
end
|
22
32
|
end
|
23
33
|
end
|
@@ -2,6 +2,9 @@ Feature: <%= model.name(:humans).titleize %>
|
|
2
2
|
|
3
3
|
Scenario: CRUD <%= model.name(:humans) %>
|
4
4
|
Given I am on the list of <%= model.name(:variables) %>
|
5
|
+
<% belongs_tos.each do |model| -%>
|
6
|
+
And there is a <%= model.name(:human) %> with the <%= model.label_attr.name(:human) %> "<%= model.label_attr.test_value %>"
|
7
|
+
<% end -%>
|
5
8
|
|
6
9
|
# create
|
7
10
|
When I follow "Add <%= model.name(:human) %>"
|
@@ -25,7 +28,7 @@ Feature: <%= model.name(:humans).titleize %>
|
|
25
28
|
Then I should be on the page for the <%= model.name(:variable) %> above
|
26
29
|
<% model.attrs.each do |attr| -%>
|
27
30
|
<%- case attr.type -%>
|
28
|
-
<%- when :string, :email, :url, :integer, :money, :text -%>
|
31
|
+
<%- when :string, :email, :url, :integer, :money, :text, :foreign_key -%>
|
29
32
|
And I should see "<%= attr.test_value %>"
|
30
33
|
<%- when :flag -%>
|
31
34
|
And I should see "<%= attr.name.humanize %> Yes"
|
@@ -52,7 +55,6 @@ Feature: <%= model.name(:humans).titleize %>
|
|
52
55
|
<%- end -%>
|
53
56
|
<% end -%>
|
54
57
|
|
55
|
-
<% if model.label_attr -%>
|
56
58
|
# destroy
|
57
59
|
When I go to the list of <%= model.name(:variables) %>
|
58
60
|
Then I should see "<%= model.label_attr.test_value %>"
|
@@ -60,4 +62,3 @@ Feature: <%= model.name(:humans).titleize %>
|
|
60
62
|
When I follow "Destroy <%= model.label_attr.test_value %>"
|
61
63
|
Then I should be on the list of <%= model.name(:variables) %>
|
62
64
|
But I should not see "<%= model.label_attr.test_value %>"
|
63
|
-
<% end -%>
|
@@ -30,11 +30,26 @@ module Katapult
|
|
30
30
|
template 'app/models/shared/does_flag.rb' if flag_attrs.any?
|
31
31
|
end
|
32
32
|
|
33
|
+
def write_factory
|
34
|
+
insert_into_file 'spec/factories/factories.rb', <<-FACTORY, before: /end\n\z/
|
35
|
+
factory #{ model.name(:symbol) }
|
36
|
+
|
37
|
+
FACTORY
|
38
|
+
end
|
39
|
+
|
33
40
|
def generate_unit_tests
|
34
41
|
Generators::ModelSpecsGenerator.new(model).invoke_all
|
35
42
|
end
|
36
43
|
|
37
44
|
no_commands do
|
45
|
+
def belongs_tos
|
46
|
+
model.application_model.get_belongs_tos_for model.name
|
47
|
+
end
|
48
|
+
|
49
|
+
def has_manys
|
50
|
+
model.application_model.get_has_manys_for model.name
|
51
|
+
end
|
52
|
+
|
38
53
|
def flag_attrs
|
39
54
|
model.attrs.select(&:flag?)
|
40
55
|
end
|