katapult 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|