katapult 0.2.0 → 0.3.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 (143) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +1 -0
  3. data/.ruby-version +1 -1
  4. data/Gemfile +9 -0
  5. data/README.md +122 -94
  6. data/Rakefile +13 -0
  7. data/bin/katapult +59 -25
  8. data/features/application_model.feature +55 -0
  9. data/features/authenticate.feature +88 -62
  10. data/features/basics.feature +64 -402
  11. data/features/binary.feature +56 -42
  12. data/features/configuration.feature +4 -4
  13. data/features/model.feature +21 -30
  14. data/features/navigation.feature +35 -48
  15. data/features/step_definitions/aruba_steps.rb +3 -0
  16. data/features/step_definitions/katapult_steps.rb +307 -8
  17. data/features/step_definitions/rails_steps.rb +74 -14
  18. data/features/step_definitions/test_steps.rb +5 -5
  19. data/features/step_definitions/version_steps.rb +22 -0
  20. data/features/support/env.rb +11 -3
  21. data/features/{wui.feature → web_ui.feature} +175 -148
  22. data/katapult.gemspec +8 -13
  23. data/lib/generators/katapult/app_model/app_model_generator.rb +12 -0
  24. data/lib/generators/katapult/app_model/templates/lib/katapult/application_model.rb +40 -0
  25. data/lib/generators/katapult/basics/basics_generator.rb +186 -51
  26. data/lib/generators/katapult/basics/templates/.browserslistrc +1 -0
  27. data/lib/generators/katapult/basics/templates/.gitignore +20 -21
  28. data/lib/generators/katapult/basics/templates/.rspec_parallel +3 -0
  29. data/lib/generators/katapult/basics/templates/Capfile +5 -1
  30. data/lib/generators/katapult/basics/templates/Gemfile +23 -34
  31. data/lib/generators/katapult/basics/templates/Guardfile +0 -12
  32. data/lib/generators/katapult/basics/templates/app/controllers/errors_controller.rb +9 -0
  33. data/lib/generators/katapult/basics/templates/app/helpers/unpoly_helper.rb +13 -0
  34. data/lib/generators/katapult/{haml → basics}/templates/app/views/layouts/_flashes.html.haml +1 -1
  35. data/lib/generators/katapult/basics/templates/app/views/layouts/_menu_bar.html.haml.tt +12 -0
  36. data/lib/generators/katapult/basics/templates/app/views/layouts/application.html.haml.tt +25 -0
  37. data/lib/generators/katapult/basics/templates/app/webpack/assets/images/.keep +0 -0
  38. data/lib/generators/katapult/basics/templates/app/webpack/assets/index.js +16 -0
  39. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/application.js +0 -0
  40. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/bootstrap.js +12 -0
  41. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/compilers/.keep +0 -0
  42. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/macros/content_link.js +17 -0
  43. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/macros/modal_link.js +17 -0
  44. data/lib/generators/katapult/basics/templates/app/webpack/assets/javascripts/unpoly.js +9 -0
  45. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/_definitions.sass +25 -0
  46. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/_environment.sass +2 -0
  47. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/_mixins.sass +3 -0
  48. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/blocks/.keep +0 -0
  49. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/custom_bootstrap.sass +50 -0
  50. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/ext/.keep +0 -0
  51. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/ext/bootstrap/navbar.sass +83 -0
  52. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/theme.sass +11 -0
  53. data/lib/generators/katapult/basics/templates/app/webpack/assets/stylesheets/unpoly.sass +2 -0
  54. data/lib/generators/katapult/basics/templates/app/webpack/packs/application.js +13 -0
  55. data/lib/generators/katapult/basics/templates/config/database.sample.yml +1 -1
  56. data/lib/generators/katapult/basics/templates/config/deploy.rb +3 -4
  57. data/lib/generators/katapult/basics/templates/config/environments/staging.rb +5 -0
  58. data/lib/generators/katapult/basics/templates/config/initializers/better_errors.rb +23 -0
  59. data/lib/generators/katapult/basics/templates/config/initializers/exception_notification.rb.tt +1 -1
  60. data/lib/generators/katapult/basics/templates/config/initializers/ext.rb +1 -1
  61. data/lib/generators/katapult/basics/templates/config/webpack/loaders/unpoly.js +4 -0
  62. data/lib/generators/katapult/basics/templates/features/support/capybara_screenshot.rb +7 -0
  63. data/lib/generators/katapult/basics/templates/features/support/factory_bot.rb +1 -0
  64. data/lib/generators/katapult/basics/templates/features/support/paths.rb +7 -2
  65. data/lib/generators/katapult/basics/templates/features/support/rspec_doubles.rb +1 -0
  66. data/lib/generators/katapult/basics/templates/features/support/selectors.rb +3 -3
  67. data/lib/generators/katapult/basics/templates/features/support/selenium.rb +13 -0
  68. data/lib/generators/katapult/basics/templates/features/support/{env-custom.rb → spreewald.rb} +0 -0
  69. data/lib/generators/katapult/basics/templates/features/support/webpacker.rb +35 -0
  70. data/lib/generators/katapult/basics/templates/lib/ext/action_view/form_for_with_development_errors.rb +31 -31
  71. data/lib/generators/katapult/basics/templates/lib/ext/active_record/find_by_anything.rb +4 -3
  72. data/lib/generators/katapult/basics/templates/public/robots.txt +5 -0
  73. data/lib/generators/katapult/basics/templates/spec/assets/sample.pdf +0 -0
  74. data/lib/generators/katapult/basics/templates/spec/factories/factories.rb +1 -1
  75. data/lib/generators/katapult/basics/templates/spec/support/database_cleaner.rb +20 -0
  76. data/lib/generators/katapult/basics/templates/spec/support/factory_bot.rb +3 -0
  77. data/lib/generators/katapult/basics/templates/spec/support/fixture_file.rb +6 -0
  78. data/lib/generators/katapult/basics/templates/spec/support/postgresql_sequences.rb +15 -0
  79. data/lib/generators/katapult/basics/templates/spec/support/timecop.rb +3 -0
  80. data/lib/generators/katapult/clearance/clearance_generator.rb +14 -2
  81. data/lib/generators/katapult/clearance/templates/app/views/layouts/_current_user.html.haml +11 -0
  82. data/lib/generators/katapult/clearance/templates/app/views/passwords/create.html.haml +10 -4
  83. data/lib/generators/katapult/clearance/templates/app/views/passwords/edit.html.haml +12 -12
  84. data/lib/generators/katapult/clearance/templates/app/views/passwords/new.html.haml +14 -11
  85. data/lib/generators/katapult/clearance/templates/app/views/sessions/new.html.haml +16 -15
  86. data/lib/generators/katapult/clearance/templates/features/authentication.feature +3 -3
  87. data/lib/generators/katapult/cucumber_features/templates/feature.feature +1 -1
  88. data/lib/generators/katapult/model_specs/templates/model_spec.rb +3 -5
  89. data/lib/generators/katapult/navigation/navigation_generator.rb +7 -1
  90. data/lib/generators/katapult/navigation/templates/app/views/layouts/_navigation.html.haml +15 -0
  91. data/lib/generators/katapult/transform/transform_generator.rb +12 -17
  92. data/lib/generators/katapult/views/templates/_form.html.haml +48 -0
  93. data/lib/generators/katapult/views/templates/app/helpers/table_helper.rb +14 -0
  94. data/lib/generators/katapult/views/templates/app/webpack/assets/stylesheets/blocks/action_bar.sass +22 -0
  95. data/lib/generators/katapult/views/templates/app/webpack/assets/stylesheets/blocks/title.sass +11 -0
  96. data/lib/generators/katapult/views/templates/custom_action.html.haml +5 -0
  97. data/lib/generators/katapult/views/templates/edit.html.haml +4 -0
  98. data/lib/generators/katapult/views/templates/index.html.haml +26 -0
  99. data/lib/generators/katapult/{haml → views}/templates/new.html.haml +1 -1
  100. data/lib/generators/katapult/views/templates/show.html.haml +39 -0
  101. data/lib/generators/katapult/{haml/haml_generator.rb → views/views_generator.rb} +19 -25
  102. data/lib/generators/katapult/{w_u_i → web_ui}/templates/_route.rb +3 -3
  103. data/lib/generators/katapult/{w_u_i → web_ui}/templates/controller.rb +21 -23
  104. data/lib/generators/katapult/{w_u_i/w_u_i_generator.rb → web_ui/web_ui_generator.rb} +7 -12
  105. data/lib/katapult/action.rb +1 -1
  106. data/lib/katapult/application_model.rb +8 -8
  107. data/lib/katapult/binary_util.rb +48 -10
  108. data/lib/katapult/generator.rb +2 -10
  109. data/lib/katapult/generator_goodies.rb +23 -0
  110. data/lib/katapult/navigation.rb +10 -5
  111. data/lib/katapult/parser.rb +15 -8
  112. data/lib/katapult/version.rb +5 -1
  113. data/lib/katapult/{wui.rb → web_ui.rb} +19 -4
  114. data/lib/katapult.rb +0 -5
  115. data/script/console +5 -2
  116. data/script/kta +8 -0
  117. data/script/update +80 -0
  118. data/spec/action_spec.rb +0 -1
  119. data/spec/attribute_spec.rb +0 -1
  120. data/spec/element_spec.rb +0 -1
  121. data/spec/model_spec.rb +0 -1
  122. data/spec/parser_spec.rb +26 -0
  123. data/spec/util_spec.rb +0 -1
  124. data/spec/{wui_spec.rb → web_ui_spec.rb} +24 -12
  125. metadata +86 -124
  126. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_all.sass +0 -4
  127. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_items.sass +0 -11
  128. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_layout.sass +0 -26
  129. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_navigation.sass +0 -11
  130. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application/blocks/_tools.sass +0 -12
  131. data/lib/generators/katapult/basics/templates/app/assets/stylesheets/application.sass +0 -6
  132. data/lib/generators/katapult/basics/templates/config/spring.rb +0 -3
  133. data/lib/generators/katapult/basics/templates/features/support/factory_girl.rb +0 -1
  134. data/lib/generators/katapult/basics/templates/spec/support/factory_girl.rb +0 -3
  135. data/lib/generators/katapult/haml/templates/_form.html.haml +0 -38
  136. data/lib/generators/katapult/haml/templates/app/views/layouts/application.html.haml +0 -33
  137. data/lib/generators/katapult/haml/templates/custom_action.html.haml +0 -5
  138. data/lib/generators/katapult/haml/templates/edit.html.haml +0 -4
  139. data/lib/generators/katapult/haml/templates/index.html.haml +0 -29
  140. data/lib/generators/katapult/haml/templates/show.html.haml +0 -39
  141. data/lib/generators/katapult/install/install_generator.rb +0 -14
  142. data/lib/generators/katapult/install/templates/lib/katapult/application_model.rb +0 -20
  143. data/lib/generators/katapult/navigation/templates/app/models/navigation.rb +0 -12
@@ -1,13 +1,13 @@
1
+ #@announce-output
2
+ #@announce-stderr
1
3
  Feature: Web User Interface
2
4
 
3
5
  Background:
4
- Given a pristine Rails application
5
- And I install katapult
6
- And I generate katapult basics
6
+ Given a new Rails application with Katapult basics installed
7
7
 
8
8
 
9
9
  Scenario: Generate a Web User Interface
10
- When I overwrite "lib/katapult/application_model.rb" with:
10
+ When I write to "lib/katapult/application_model.rb" with:
11
11
  """
12
12
  model 'customer' do |customer|
13
13
  customer.attr :name
@@ -24,15 +24,11 @@ Feature: Web User Interface
24
24
  customer.attr :plain_data, type: :plain_json
25
25
  end
26
26
 
27
- wui 'customer', model: 'customer' do |wui|
28
- wui.crud
29
- wui.action :get_member, method: :get, scope: :member
30
- wui.action :post_member, method: :post, scope: :member
31
- wui.action :get_collection, method: :get, scope: :collection
32
- wui.action :put_collection, method: :put, scope: :collection
27
+ web_ui 'customer', model: 'customer' do |web_ui|
28
+ web_ui.crud
33
29
  end
34
30
  """
35
- And I successfully transform the application model
31
+ And I successfully transform the application model including migrations
36
32
  Then the file "app/controllers/customers_controller.rb" should contain exactly:
37
33
  """
38
34
  class CustomersController < ApplicationController
@@ -51,7 +47,7 @@ Feature: Web User Interface
51
47
 
52
48
  def create
53
49
  build_customer
54
- save_customer or render :new
50
+ save_customer
55
51
  end
56
52
 
57
53
  def edit
@@ -62,7 +58,7 @@ Feature: Web User Interface
62
58
  def update
63
59
  load_customer
64
60
  build_customer
65
- save_customer or render :edit
61
+ save_customer
66
62
  end
67
63
 
68
64
  def destroy
@@ -71,24 +67,6 @@ Feature: Web User Interface
71
67
  redirect_to customers_path
72
68
  end
73
69
 
74
- def get_member
75
- load_customer
76
- end
77
-
78
- def post_member
79
- load_customer
80
- redirect_to @customer
81
- end
82
-
83
- def get_collection
84
- load_customers
85
- end
86
-
87
- def put_collection
88
- load_customers
89
- redirect_to customers_path
90
- end
91
-
92
70
  private
93
71
 
94
72
  def load_customers
@@ -100,19 +78,36 @@ Feature: Web User Interface
100
78
  end
101
79
 
102
80
  def build_customer
103
- @customer ||= customer_scope.build
81
+ @customer ||= customer_scope.new
104
82
  @customer.attributes = customer_params
105
83
  end
106
84
 
107
85
  def save_customer
108
86
  if @customer.save
109
87
  redirect_to @customer
88
+ else
89
+ action = @customer.new_record? ? 'new' : 'edit'
90
+ render action, status: :unprocessable_entity
110
91
  end
111
92
  end
112
93
 
113
94
  def customer_params
114
95
  customer_params = params[:customer]
115
- customer_params ? customer_params.permit(%i[name age email password revenue homepage locked notes first_visit indexable_data plain_data]) : {}
96
+ return {} if customer_params.blank?
97
+
98
+ customer_params.permit(
99
+ :name,
100
+ :age,
101
+ :email,
102
+ :password,
103
+ :revenue,
104
+ :homepage,
105
+ :locked,
106
+ :notes,
107
+ :first_visit,
108
+ :indexable_data,
109
+ :plain_data,
110
+ )
116
111
  end
117
112
 
118
113
  def customer_scope
@@ -124,58 +119,49 @@ Feature: Web User Interface
124
119
  """
125
120
  And the file "config/routes.rb" should contain:
126
121
  """
127
- resources :customers, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
128
- member do
129
- get 'get_member'
130
- post 'post_member'
131
- end
132
- collection do
133
- get 'get_collection'
134
- put 'put_collection'
135
- end
136
- end
122
+ resources :customers
137
123
  """
124
+ And the file "app/helpers/table_helper.rb" should contain "def table(*headers, &block)"
125
+
126
+ And a file named "app/webpack/assets/stylesheets/blocks/action_bar.sass" should exist
127
+ And a file named "app/webpack/assets/stylesheets/blocks/title.sass" should exist
128
+
138
129
  And the file "app/views/customers/index.html.haml" should contain exactly:
139
130
  """
140
- %h1
141
- Customers
131
+ .action-bar.-main.btn-group
132
+ = link_to 'Add customer', new_customer_path, class: 'btn btn-default'
142
133
 
143
- .tools
144
- = link_to 'Add customer', new_customer_path, class: 'tools__button is_primary'
145
- = link_to 'Get Collection', get_collection_customers_path, class: 'tools__button'
146
- = link_to 'Put Collection', put_collection_customers_path, class: 'tools__button'
134
+ %h1.title
135
+ Customers
147
136
 
148
137
  - if @customers.any?
149
- %table.items
138
+
139
+ = table 'Name', 'Actions' do
150
140
  - @customers.each do |customer|
151
- %tr
141
+ %tr(up-expand)
142
+ %td(width='40%')
143
+ = link_to customer, customer
152
144
  %td
153
- = link_to customer.to_s, customer, class: 'hyperlink'
154
- %td
155
- .items__actions
156
- = link_to 'Edit', edit_customer_path(customer), class: 'items__action'
157
- = link_to 'Destroy', customer_path(customer), method: :delete, class: 'items__action', data: { confirm: 'Really destroy?' }, title: "Destroy #{customer.to_s}"
158
- = link_to 'Get Member', get_member_customer_path(customer), class: 'items__action'
159
- = link_to 'Post Member', post_member_customer_path(customer), class: 'items__action', method: :post
145
+ = link_to 'Edit', edit_customer_path(customer)
146
+ = link_to 'Destroy', customer_path(customer), method: :delete,
147
+ class: 'text-danger',
148
+ data: { confirm: 'Really destroy?' }, title: "Destroy #{customer}"
160
149
 
161
150
  - else
162
151
  %p.help-block
163
- There are no customers yet.
152
+ No customers found.
164
153
 
165
154
  """
166
155
  And the file "app/views/customers/show.html.haml" should contain exactly:
167
156
  """
168
- %h1
169
- = @customer.to_s
157
+ .action-bar.-main.btn-group
158
+ = link_to 'All customers', customers_path, class: 'btn btn-default'
159
+ = link_to 'Edit', edit_customer_path(@customer), class: 'btn btn-default'
170
160
 
171
- .tools
172
- = link_to 'All customers', customers_path, class: 'tools__button'
173
- = link_to 'Edit', edit_customer_path(@customer), class: 'tools__button is_primary'
174
- = link_to 'Destroy', customer_path(@customer), method: :delete, class: 'tools__button', confirm: 'Really destroy?'
175
- = link_to 'Get Member', get_member_customer_path(@customer), class: 'tools__button'
176
- = link_to 'Post Member', post_member_customer_path(@customer), class: 'tools__button', method: :post
161
+ %h1.title
162
+ = @customer
177
163
 
178
- %dl.values
164
+ %dl
179
165
  %dt
180
166
  = Customer.human_attribute_name(:name)
181
167
  %dd
@@ -187,7 +173,7 @@ Feature: Web User Interface
187
173
  %dt
188
174
  = Customer.human_attribute_name(:email)
189
175
  %dd
190
- = mail_to @customer.email, nil, class: 'hyperlink'
176
+ = mail_to @customer.email, nil
191
177
  %dt
192
178
  = Customer.human_attribute_name(:revenue)
193
179
  %dd
@@ -196,7 +182,7 @@ Feature: Web User Interface
196
182
  %dt
197
183
  = Customer.human_attribute_name(:homepage)
198
184
  %dd
199
- = link_to @customer.homepage, @customer.homepage, class: 'hyperlink'
185
+ = link_to @customer.homepage, @customer.homepage
200
186
  %dt
201
187
  = Customer.human_attribute_name(:locked)
202
188
  %dd
@@ -211,12 +197,9 @@ Feature: Web User Interface
211
197
  = l(@customer.first_visit.to_date) if @customer.first_visit
212
198
 
213
199
  """
214
- # Note that no views are generated for JSON fields, as they are mainly data
215
- # storage fields
216
-
217
200
  And the file "app/views/customers/new.html.haml" should contain exactly:
218
201
  """
219
- %h1
202
+ %h1.title
220
203
  Add customer
221
204
 
222
205
  = render 'form'
@@ -224,8 +207,8 @@ Feature: Web User Interface
224
207
  """
225
208
  And the file "app/views/customers/edit.html.haml" should contain exactly:
226
209
  """
227
- %h1
228
- = @customer.to_s
210
+ %h1.title
211
+ = @customer
229
212
 
230
213
  = render 'form'
231
214
 
@@ -234,71 +217,55 @@ Feature: Web User Interface
234
217
  """
235
218
  = form_for @customer do |form|
236
219
 
237
- %dl.controls
238
- %dt
239
- = form.label :name
240
- %dd
241
- = form.text_field :name
242
- %dt
243
- = form.label :age
244
- %dd
245
- = form.number_field :age
246
- %dt
247
- = form.label :email
248
- %dd
249
- = form.email_field :email
250
- %dt
251
- = form.label :password
252
- %dd
253
- = form.password_field :password
254
- %dt
255
- = form.label :revenue
256
- %dd
257
- = form.number_field :revenue
258
-
259
- %dt
260
- = form.label :homepage
261
- %dd
262
- = form.url_field :homepage
263
- %dt
264
- = form.label :locked
265
- %dd
266
- = form.check_box :locked
267
- %dt
268
- = form.label :notes
269
- %dd
270
- = form.text_area :notes, rows: 5
271
- %dt
272
- = form.label :first_visit
273
- %dd
274
- = form.date_field :first_visit
275
-
276
- .tools
277
- = form.submit 'Save', class: 'tools__button is_primary'
220
+ .form-group
221
+ = form.label :name
222
+ = form.text_field :name, class: 'form-control'
223
+ .form-group
224
+ = form.label :age
225
+ = form.number_field :age, class: 'form-control'
226
+ .form-group
227
+ = form.label :email
228
+ = form.email_field :email, class: 'form-control'
229
+ .form-group
230
+ = form.label :password
231
+ = form.password_field :password, class: 'form-control',
232
+ autocomplete: 'new-password'
233
+ .form-group
234
+ = form.label :revenue
235
+ .input-group
236
+ = form.number_field :revenue, class: 'form-control'
237
+ .input-group-addon
238
+
239
+ .form-group
240
+ = form.label :homepage
241
+ = form.url_field :homepage, class: 'form-control'
242
+ .form-group
243
+ = form.label :locked
244
+ .checkbox
245
+ = form.label :locked do
246
+ = form.check_box :locked
247
+ .form-group
248
+ = form.label :notes
249
+ = form.text_area :notes, rows: 5, class: 'form-control'
250
+ .form-group
251
+ = form.label :first_visit
252
+ = form.date_field :first_visit, class: 'form-control'
253
+
254
+ .action-bar
278
255
  - cancel_path = @customer.new_record? ? customers_path : customer_path(@customer)
279
- = link_to 'Cancel', cancel_path, class: 'tools__button'
280
256
 
281
- """
282
- And the file "app/views/customers/get_member.html.haml" should contain exactly:
283
- """
284
- %h1
285
- Get Member
257
+ .pull-right
258
+ - if @customer.persisted?
259
+ = link_to "Destroy customer", customer_path(@customer), method: :delete,
260
+ class: 'btn btn-danger', data: { confirm: 'Really destroy?' }
286
261
 
287
- .tools
288
- = link_to 'All customers', customers_path, class: 'tools__button'
262
+ = form.submit 'Save', class: 'btn btn-primary'
263
+ = link_to 'Cancel', cancel_path, class: 'btn btn-link'
289
264
 
290
265
  """
291
- But a file named "app/views/customers/post_member.html.haml" should not exist
292
- And the file "app/views/customers/get_collection.html.haml" should contain exactly:
293
- """
294
- %h1
295
- Get Collection
296
-
297
- .tools
298
- = link_to 'All customers', customers_path, class: 'tools__button'
266
+ # Note that no form fields are generated for JSON fields, as they are mainly
267
+ # data storage fields
299
268
 
300
- """
301
- But a file named "app/views/customers/put_collection.html.haml" should not exist
302
269
  And the file "features/customers.feature" should contain exactly:
303
270
  """
304
271
  Feature: Customers
@@ -348,7 +315,7 @@ Feature: Web User Interface
348
315
 
349
316
  When I follow "Destroy name-string"
350
317
  Then I should be on the list of customers
351
- But I should not see "name-string"
318
+ But I should not see "name-string"
352
319
 
353
320
  """
354
321
 
@@ -356,24 +323,84 @@ Feature: Web User Interface
356
323
  Then the features should pass
357
324
 
358
325
 
359
- Scenario: A WUI also generates the application layout file
360
- When I overwrite "lib/katapult/application_model.rb" with:
326
+ Scenario: Generate a Web User Interface with custom actions
327
+ When I write to "lib/katapult/application_model.rb" with:
361
328
  """
362
- model 'Car'
363
- wui 'Car'
329
+ model 'customer' do |customer|
330
+ customer.attr :name
331
+ end
332
+
333
+ web_ui 'customer', model: 'customer' do |web_ui|
334
+ web_ui.crud
335
+ web_ui.action :get_member, method: :get, scope: :member
336
+ web_ui.action :post_member, method: :post, scope: :member
337
+ web_ui.action :get_collection, method: :get, scope: :collection
338
+ web_ui.action :put_collection, method: :put, scope: :collection
339
+ end
364
340
  """
365
341
  And I successfully transform the application model
366
- Then the file "app/views/layouts/application.html.haml" should contain:
342
+ Then the file "app/controllers/customers_controller.rb" should contain:
367
343
  """
368
- = query_diet_widget(bad_count: 15) if Rails.env.development?
344
+
345
+ def get_member
346
+ load_customer
347
+ end
348
+
349
+ def post_member
350
+ load_customer
351
+ redirect_to @customer
352
+ end
353
+
354
+ def get_collection
355
+ load_customers
356
+ end
357
+
358
+ def put_collection
359
+ load_customers
360
+ redirect_to customers_path
361
+ end
362
+
369
363
  """
370
- And the file "app/views/layouts/application.html.haml" should contain:
364
+ And the file "config/routes.rb" should contain:
371
365
  """
372
- = render 'layouts/flashes'
366
+ resources :customers, only: [:index, :show, :new, :create, :edit, :update, :destroy] do
367
+ member do
368
+ get 'get_member'
369
+ post 'post_member'
370
+ end
371
+ collection do
372
+ get 'get_collection'
373
+ put 'put_collection'
374
+ end
375
+ end
376
+ """
377
+ And the file "app/views/customers/index.html.haml" should contain:
378
+ """
379
+ = link_to 'Get Collection', get_collection_customers_path, class: 'btn btn-default'
380
+ = link_to 'Put Collection', put_collection_customers_path, class: 'btn btn-default'
381
+ """
382
+ And the file "app/views/customers/show.html.haml" should contain:
383
+ """
384
+ = link_to 'Get Member', get_member_customer_path(@customer), class: 'btn btn-default'
385
+ = link_to 'Post Member', post_member_customer_path(@customer), class: 'btn btn-default', method: :post
373
386
  """
374
- And the file "app/views/layouts/_flashes.html.haml" should contain:
387
+ And the file "app/views/customers/get_member.html.haml" should contain exactly:
388
+ """
389
+ .action-bar
390
+ = link_to 'All customers', customers_path, class: 'btn btn-default'
391
+
392
+ %h1.title
393
+ Get Member
394
+
395
+ """
396
+ But a file named "app/views/customers/post_member.html.haml" should not exist
397
+ And the file "app/views/customers/get_collection.html.haml" should contain exactly:
375
398
  """
376
- - flash.each do |level, message|
377
- .flash.alert.alert-info
378
- = message
399
+ .action-bar
400
+ = link_to 'All customers', customers_path, class: 'btn btn-default'
401
+
402
+ %h1.title
403
+ Get Collection
404
+
379
405
  """
406
+ But a file named "app/views/customers/put_collection.html.haml" should not exist
data/katapult.gemspec CHANGED
@@ -9,7 +9,12 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Dominik Schöler']
10
10
  spec.email = ['dominik.schoeler@makandra.de']
11
11
  spec.summary = %q{Kickstart Rails development}
12
- spec.description = %q{Katapult is a framework for generating base code}
12
+ spec.description = %q{
13
+ Katapult is a framework for generating base code for Rails applications in
14
+ two leaps. Basics Generation prepares a new Rails application with lots of
15
+ best practices, Model Transformation generates application code from a model
16
+ of the application.
17
+ }
13
18
  spec.homepage = 'https://github.com/makandra/katapult'
14
19
  spec.license = 'MIT'
15
20
 
@@ -18,18 +23,8 @@ Gem::Specification.new do |spec|
18
23
  spec.test_files = spec.files.grep(%r{^(spec|features)/})
19
24
  spec.require_paths = ['lib']
20
25
 
21
- spec.required_ruby_version = '~> 2.0'
26
+ # spec.required_ruby_version = Katapult::RUBY_VERSION
22
27
 
23
- spec.add_runtime_dependency 'rails'
28
+ spec.add_runtime_dependency 'rails', Katapult::RAILS_VERSION
24
29
  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', '~> 0.10.2'
33
- spec.add_development_dependency 'guard-cucumber'
34
- spec.add_development_dependency 'rspec', '~> 3.4.0'
35
30
  end
@@ -0,0 +1,12 @@
1
+ module Katapult
2
+ class AppModelGenerator < Rails::Generators::Base
3
+
4
+ desc 'Generate the default application model'
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def generate_application_model
8
+ template 'lib/katapult/application_model.rb'
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,40 @@
1
+ # In this file, you model your application. Refer to the README or get inspired
2
+ # by the full-fledged example below (which you can generate right away).
3
+
4
+ # Define a model + generate views with CRUD actions
5
+ # Since this generates the first web UI with an index action, the products list
6
+ # will become the home page of the generated app
7
+ crud 'product' do |product|
8
+ # The first attribute of each model is taken as a human identifier/label
9
+ product.attr :title # Default type "string"
10
+
11
+ # The order of attributes is respected when generating the form for that model
12
+ product.attr :price, type: :money
13
+ product.attr :mode, assignable_values: %w[public private]
14
+ product.attr :provider, type: :url
15
+ product.attr :import_data, type: :json
16
+ end
17
+
18
+ # Define a model
19
+ model 'user' do |user|
20
+ user.attr :email # Type "email" derived from attribute name
21
+
22
+ user.attr :name
23
+ user.attr :last_visit, type: :datetime
24
+ user.attr :locked, type: :flag, default: false
25
+ end
26
+
27
+ # Add a web user interface for the 'user' model
28
+ web_ui 'user' do |web_ui|
29
+ # All CRUD actions: index, show, new, create, edit, update, destroy
30
+ web_ui.crud
31
+
32
+ # Custom action
33
+ web_ui.action :lock, scope: :member, method: :post
34
+ end
35
+
36
+ # Have a main menu
37
+ navigation
38
+
39
+ # Add authentication
40
+ authenticate 'user', system_email: 'system@example.com'