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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +57 -9
  4. data/bin/katapult +7 -3
  5. data/features/application_model.feature +4 -1
  6. data/features/authenticate.feature +1 -18
  7. data/features/basics.feature +1 -0
  8. data/features/binary.feature +5 -7
  9. data/features/model.feature +42 -3
  10. data/features/step_definitions/rails_steps.rb +1 -1
  11. data/features/web_ui.feature +17 -5
  12. data/lib/generators/katapult/app_model/templates/lib/katapult/application_model.rb +3 -0
  13. data/lib/generators/katapult/basics/basics_generator.rb +3 -8
  14. data/lib/generators/katapult/basics/templates/README.md.tt +33 -0
  15. data/lib/generators/katapult/basics/templates/features/support/paths.rb +1 -1
  16. data/lib/generators/katapult/clearance/clearance_generator.rb +6 -2
  17. data/lib/generators/katapult/clearance/templates/config/initializers/clearance.rb +1 -0
  18. data/lib/generators/katapult/cucumber_features/cucumber_features_generator.rb +10 -0
  19. data/lib/generators/katapult/cucumber_features/templates/feature.feature +4 -3
  20. data/lib/generators/katapult/model/model_generator.rb +15 -0
  21. data/lib/generators/katapult/model/templates/model.rb +13 -3
  22. data/lib/generators/katapult/model_specs/model_specs_generator.rb +1 -1
  23. data/lib/generators/katapult/model_specs/templates/model_spec.rb +1 -1
  24. data/lib/generators/katapult/transform/transform_generator.rb +4 -7
  25. data/lib/generators/katapult/views/templates/_form.html.haml +16 -13
  26. data/lib/generators/katapult/views/templates/show.html.haml +2 -0
  27. data/lib/katapult/application_model.rb +68 -19
  28. data/lib/katapult/element.rb +13 -18
  29. data/lib/katapult/{action.rb → elements/action.rb} +0 -0
  30. data/lib/katapult/elements/association.rb +35 -0
  31. data/lib/katapult/{attribute.rb → elements/attribute.rb} +14 -5
  32. data/lib/katapult/{authentication.rb → elements/authentication.rb} +2 -5
  33. data/lib/katapult/elements/model.rb +76 -0
  34. data/lib/katapult/{navigation.rb → elements/navigation.rb} +0 -0
  35. data/lib/katapult/{web_ui.rb → elements/web_ui.rb} +2 -12
  36. data/lib/katapult/generator.rb +2 -2
  37. data/lib/katapult/{binary_util.rb → support/binary_util.rb} +2 -1
  38. data/lib/katapult/{generator_goodies.rb → support/generator_goodies.rb} +9 -2
  39. data/lib/katapult/version.rb +1 -1
  40. data/script/console +5 -2
  41. data/script/update +1 -1
  42. data/spec/action_spec.rb +1 -1
  43. data/spec/application_model_spec.rb +26 -0
  44. data/spec/association_spec.rb +12 -0
  45. data/spec/attribute_spec.rb +35 -1
  46. data/spec/model_spec.rb +5 -2
  47. data/spec/util_spec.rb +1 -1
  48. data/spec/web_ui_spec.rb +11 -33
  49. metadata +17 -13
  50. data/lib/katapult/model.rb +0 -45
  51. data/lib/katapult/parser.rb +0 -53
  52. data/spec/parser_spec.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddcf0832f9fb8d7597253465296fe0726761e1bd2d3088d741e4bedf51e05cf7
4
- data.tar.gz: 293a4ba645e9710e1392707ae59df834e9d14cbd841920e919d02d3d0db02e73
3
+ metadata.gz: f4099dfe92529880417ce7c3ac5204b70fc115b33a6b60b0027d75c6f7e001e3
4
+ data.tar.gz: 688a93e927f9240fc0d6e67caceeaae882438c9f5114618f051fda4c5063495f
5
5
  SHA512:
6
- metadata.gz: 2ead2ca1d7f9bbee69ad9bdac6e5043c513e23deffa6f73119b3b4145206d56f7cf3537067d7116b39d04b0e7c07f795eb839600dedd14f9e22d6bc501e8f33e
7
- data.tar.gz: cd2336671a2317373433ff47a3568e35073757c21ff2972d1a8d3004830c764adcc7c422e55b34966255952516760eee329a0468687159adf78c5aa2c46551f3
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. Takes a name and options:
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. Takes a name and options:
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
- This is a shortcut for creating a model together with a WebUI with CRUD actions.
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
- No arguments, will generate a main menu with links to the index pages of all
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 Clearance mails like password reset
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 step: Model your application in lib/katapult/application_model.rb and
78
- transform it into code by running `katapult fire`.
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 exactly:
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
  """
@@ -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
  """
@@ -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
- Next step: Model your application in lib/katapult/application_model.rb and
52
- transform it into code by running `katapult fire`.
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
 
@@ -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 < ActiveRecord::Base
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 < ActiveRecord::Base
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 < ActiveRecord::Base
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
  """
@@ -1,4 +1,4 @@
1
- require 'katapult/binary_util'
1
+ require 'katapult/support/binary_util'
2
2
 
3
3
  module RailsHelper
4
4
 
@@ -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
- model 'customer' do |customer|
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
- web_ui 'customer', model: 'customer' do |web_ui|
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 write_ruby_version
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', '< 1.14.0' # Has broken InstallGenerator :(
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
- inject_into_file 'spec/factories/factories.rb', <<-'CONTENT', after: 'FactoryBot.define do'
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,4 +12,5 @@ Clearance.configure do |config|
12
12
  # config.secure_cookie = true
13
13
  # config.sign_in_guards = []
14
14
  # config.user_model = User
15
+ config.rotate_csrf_on_sign_in = true
15
16
  end
@@ -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