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
@@ -1,21 +1,31 @@
1
- class <%= class_name %> < ActiveRecord::Base
1
+ class <%= class_name %> < ApplicationRecord
2
+
2
3
  <%- flag_attrs.each do |attr| -%>
3
4
  include DoesFlag[<%= attr.name(:symbol) %>, default: <%= attr.default %>]
4
5
  <%- end -%>
6
+ <% has_manys.each do |model| -%>
7
+ has_many <%= model.name(:symbols) %>
8
+ <% end -%>
9
+ <% belongs_tos.each do |model| -%>
10
+ belongs_to <%= model.name(:symbol) %>, optional: true
11
+ <% end -%>
5
12
  <%- if defaults.any? -%>
13
+
6
14
  has_defaults(<%= defaults %>)
7
15
  <%- end -%>
8
16
  <%- model.attrs.select(&:assignable_values).each do |attr| -%>
9
- assignable_values_for :<%= attr.name %>, <%= attr.options.slice(:allow_blank, :default) %> do
17
+
18
+ assignable_values_for :<%= attr.name(:variable).sub /_id$/, '' %>, <%= attr.options.slice(:allow_blank, :default) %> do
10
19
  <%= attr.assignable_values %>
11
20
  end
12
21
  <%- end -%>
13
22
 
14
23
  def to_s
15
- <% if model.label_attr -%>
24
+ <% if model.label_attr? -%>
16
25
  <%= model.label_attr.name %>.to_s
17
26
  <% else -%>
18
27
  "<%= model.name %>##{id}"
19
28
  <% end -%>
20
29
  end
30
+
21
31
  end
@@ -19,7 +19,7 @@ module Katapult
19
19
  no_tasks do
20
20
  def specable_attrs
21
21
  model.attrs.select do |attr|
22
- attr.assignable_values.present? or attr.default != nil
22
+ attr.assignable_values_as_list? or !attr.default.nil?
23
23
  end
24
24
  end
25
25
 
@@ -1,7 +1,7 @@
1
1
  describe <%= model.name :class %> do
2
2
 
3
3
  describe '#to_s' do
4
- <%- if model.label_attr -%>
4
+ <%- if model.label_attr? -%>
5
5
  it 'returns the #<%= model.label_attr.name %> attribute' do
6
6
  subject.<%= model.label_attr.name %> = <%= model.label_attr.test_value.inspect %>
7
7
  expect(subject.to_s).to eq(<%= model.label_attr.test_value.to_s.inspect %>)
@@ -1,12 +1,9 @@
1
1
  # Generate files and directories from an application model file. Afterwards do
2
2
  # any setup left necessary (e.g. updating the database).
3
3
 
4
- # The application model transformation is split into two parts:
5
- # 1) parse the model into an object-based representation
6
- # 2) render the parsed model into code
7
-
8
- require 'katapult/parser'
9
- require 'katapult/generator_goodies'
4
+ # A normal #require would load the application model from the generated app
5
+ require_relative '../../../katapult/application_model'
6
+ require 'katapult/support/generator_goodies'
10
7
 
11
8
  module Katapult
12
9
  class TransformGenerator < Rails::Generators::Base
@@ -20,7 +17,7 @@ module Katapult
20
17
  def transform_application_model
21
18
  say_status :parse, path
22
19
  application_model = File.read(path)
23
- @app_model = Katapult::Parser.new.parse(application_model, path)
20
+ @app_model = Katapult::ApplicationModel.parse(application_model, path)
24
21
 
25
22
  say_status :render, "into #{app_name}"
26
23
  @app_model.render
@@ -4,36 +4,39 @@
4
4
  <% web_ui.model.editable_attrs.each do |attribute| -%>
5
5
  .form-group
6
6
  = form.label <%= attribute.name(:symbol) %>
7
- <%- if attribute.assignable_values -%>
7
+ <% if attribute.type == :foreign_key -%>
8
+ = form.collection_select <%= attribute.name(:symbol) %>, form.object.assignable_<%= attribute.name(:variables).sub(/_ids$/, 's') %>,
9
+ :id, <%= attribute.associated_model.label_attr.name(:symbol) %>, { include_blank: true }, class: 'form-control'
10
+ <% elsif attribute.assignable_values -%>
8
11
  = form.select <%= attribute.name(:symbol) %>, form.object.assignable_<%= attribute.name(:variables) %>
9
- <%- else -%>
10
- <%- case attribute.type -%>
11
- <%- when :string -%>
12
+ <% else -%>
13
+ <%- case attribute.type -%>
14
+ <%- when :string -%>
12
15
  = form.text_field <%= attribute.name(:symbol) %>, class: 'form-control'
13
- <%- when :email -%>
16
+ <%- when :email -%>
14
17
  = form.email_field <%= attribute.name(:symbol) %>, class: 'form-control'
15
- <%- when :password -%>
18
+ <%- when :password -%>
16
19
  = form.password_field <%= attribute.name(:symbol) %>, class: 'form-control',
17
20
  autocomplete: 'new-password'
18
- <%- when :url -%>
21
+ <%- when :url -%>
19
22
  = form.url_field <%= attribute.name(:symbol) %>, class: 'form-control'
20
- <%- when :integer -%>
23
+ <%- when :integer -%>
21
24
  = form.number_field <%= attribute.name(:symbol) %>, class: 'form-control'
22
- <%- when :money -%>
25
+ <%- when :money -%>
23
26
  .input-group
24
27
  = form.number_field <%= attribute.name(:symbol) %>, class: 'form-control'
25
28
  .input-group-addon
26
29
 
27
- <%- when :text -%>
30
+ <%- when :text -%>
28
31
  = form.text_area <%= attribute.name(:symbol) %>, rows: 5, class: 'form-control'
29
- <%- when :flag -%>
32
+ <%- when :flag -%>
30
33
  .checkbox
31
34
  = form.label <%= attribute.name(:symbol) %> do
32
35
  = form.check_box <%= attribute.name(:symbol) %>
33
- <%- when :datetime -%>
36
+ <%- when :datetime -%>
34
37
  = form.date_field <%= attribute.name(:symbol) %>, class: 'form-control'
35
- <%- end -%>
36
38
  <%- end -%>
39
+ <% end -%>
37
40
  <% end -%>
38
41
 
39
42
  .action-bar
@@ -35,5 +35,7 @@
35
35
  = <%= model_attribute %> ? 'Yes' : 'No'
36
36
  <%- when :datetime -%>
37
37
  = l(<%= model_attribute %>.to_date) if <%= model_attribute %>
38
+ <%- when :foreign_key -%>
39
+ = <%= model_attribute.sub /_id$/, '' %>
38
40
  <%- end -%>
39
41
  <%- end -%>
@@ -1,52 +1,101 @@
1
- # Internal representation of an application model file.
1
+ # Root of the internal representation of an application model file
2
+
3
+ require 'katapult/elements/model'
4
+ require 'katapult/elements/web_ui'
5
+ require 'katapult/elements/navigation'
6
+ require 'katapult/elements/authentication'
7
+ require 'katapult/elements/association'
2
8
 
3
9
  module Katapult
4
10
  class ApplicationModel
5
11
 
6
- attr_reader :models, :web_uis, :navigation, :authentication
12
+ NotFound = Class.new(StandardError)
13
+
14
+ attr_reader :models, :web_uis, :navigation, :authentication, :associations
15
+
16
+ def self.parse(application_model_string, path_to_model = '')
17
+ new.tap do |model|
18
+ model.instance_eval application_model_string, path_to_model
19
+ end
20
+ end
7
21
 
8
22
  def initialize
9
23
  @models = []
24
+ @associations = []
10
25
  @web_uis = []
11
26
  end
12
27
 
13
- def add_model(model)
14
- model.set_application_model(self)
15
- @models << model
28
+ # DSL
29
+ def model(name, &block)
30
+ models << Model.new(name, application_model: self, &block)
31
+ end
32
+
33
+ # DSL
34
+ def web_ui(name, options = {}, &block)
35
+ options[:application_model] = self
36
+ web_uis << WebUI.new(name, options, &block)
37
+ end
38
+
39
+ # DSL
40
+ def navigation(name = :main)
41
+ @navigation = Navigation.new(name, application_model: self)
42
+ end
43
+
44
+ # DSL
45
+ def authenticate(user_model_name, system_email:)
46
+ @authentication = Authentication.new(user_model_name,
47
+ system_email: system_email, application_model: self)
16
48
  end
17
49
 
18
- def get_model(name)
19
- models.find { |m| m.name == name }
50
+ # DSL
51
+ def crud(name, &block)
52
+ model name, &block
53
+ web_ui name, &:crud
20
54
  end
21
55
 
22
- def add_web_ui(web_ui)
23
- web_ui.set_application_model(self)
24
- @web_uis << web_ui
56
+
57
+ def association(name, options = {})
58
+ options[:application_model] = self
59
+ associations << Association.new(name, options)
60
+ end
61
+
62
+ def get_model!(name)
63
+ models.find { |m| m.name == name } or raise NotFound,
64
+ "Could not find a model named #{ name }"
25
65
  end
26
66
 
27
67
  def get_web_ui(name)
28
68
  web_uis.find { |w| w.name == name }
29
69
  end
30
70
 
31
- def set_navigation(navigation)
32
- navigation.set_application_model(self)
33
- @navigation = navigation
71
+ # Returns all models that `model_name` belongs_to
72
+ def get_belongs_tos_for(model_name)
73
+ associations.select { |a| a.name == model_name }.map(&:belongs_to_model)
34
74
  end
35
75
 
36
- def set_authentication(auth)
37
- auth.set_application_model(self)
38
- auth.ensure_user_model_attributes_present
39
- @authentication = auth
76
+ # Returns all models that `model_name` has_many of
77
+ def get_has_manys_for(model_name)
78
+ associations.select { |a| a.belongs_to == model_name }.map(&:model)
40
79
  end
41
80
 
42
- # ---
43
-
44
81
  def render
82
+ prepare_render
83
+
45
84
  models.each &:render
46
85
  web_uis.each &:render
47
86
  navigation.render if navigation
48
87
  authentication.render if authentication
49
88
  end
50
89
 
90
+ private
91
+
92
+ def prepare_render
93
+ authentication &.ensure_user_model_attributes_present
94
+ models.each do |model|
95
+ belongs_tos = get_belongs_tos_for(model.name)
96
+ model.add_foreign_key_attrs(belongs_tos)
97
+ end
98
+ end
99
+
51
100
  end
52
101
  end
@@ -10,10 +10,9 @@ module Katapult
10
10
  UnknownOptionError = Class.new(StandardError)
11
11
  UnknownFormattingError = Class.new(StandardError)
12
12
 
13
- attr_accessor :name, :options
14
- attr_reader :application_model
13
+ attr_accessor :name, :options, :application_model
15
14
 
16
- # Improve semantics in element classes
15
+ # Use #options for DSL/API, attr_accessor for internal attributes
17
16
  class << self
18
17
  alias_method :options, :attr_accessor
19
18
  end
@@ -28,26 +27,22 @@ module Katapult
28
27
  yield(self) if block_given?
29
28
  end
30
29
 
31
- def set_application_model(app_model)
32
- @application_model = app_model
33
- end
34
-
35
30
  def name(kind = nil)
36
31
  machine_name = @name.underscore
37
32
  human_name = machine_name.humanize.downcase
38
33
 
39
34
  case kind.to_s
40
- when '' then @name
41
- when 'symbol' then ":#{machine_name}"
42
- when 'symbols' then ":#{machine_name.pluralize}"
43
- when 'variable' then machine_name
44
- when 'variables' then machine_name.pluralize
45
- when 'ivar' then "@#{machine_name}"
46
- when 'ivars' then "@#{machine_name.pluralize}"
47
- when 'human' then human_name
48
- when 'humans' then human_name.pluralize
49
- when 'class' then machine_name.classify
50
- when 'classes' then machine_name.classify.pluralize
35
+ when '' then @name ## Example
36
+ when 'symbol' then ":#{machine_name}" # :user_task
37
+ when 'symbols' then ":#{machine_name.pluralize}" # :user_tasks
38
+ when 'variable' then machine_name # user_task
39
+ when 'variables' then machine_name.pluralize # user_tasks
40
+ when 'ivar' then "@#{machine_name}" # @user_task
41
+ when 'ivars' then "@#{machine_name.pluralize}" # @user_tasks
42
+ when 'human' then human_name # user task
43
+ when 'humans' then human_name.pluralize # user tasks
44
+ when 'class' then machine_name.classify # UserTask
45
+ when 'classes' then machine_name.classify.pluralize # UserTasks
51
46
  else raise UnknownFormattingError, "Unknown name formatting: #{ kind.inspect }"
52
47
  end
53
48
  end
File without changes
@@ -0,0 +1,35 @@
1
+ # Models an association between models
2
+
3
+ require 'katapult/element'
4
+
5
+ module Katapult
6
+ class Association < Element
7
+
8
+ IncompleteAssociationError = Class.new(StandardError)
9
+
10
+ options :belongs_to
11
+
12
+ def initialize(*args)
13
+ super
14
+ validate!
15
+
16
+ self.belongs_to = belongs_to.to_s # Normalize
17
+ end
18
+
19
+ def model
20
+ application_model.get_model! name
21
+ end
22
+
23
+ def belongs_to_model
24
+ application_model.get_model! belongs_to
25
+ end
26
+
27
+ private
28
+
29
+ def validate!
30
+ belongs_to.present? or raise IncompleteAssociationError,
31
+ 'Missing :belongs_to option'
32
+ end
33
+
34
+ end
35
+ end
@@ -9,10 +9,12 @@ module Katapult
9
9
  class Attribute < Element
10
10
 
11
11
  options :type, :default, :assignable_values, :allow_blank, :skip_db
12
+ attr_accessor :model, :associated_model
12
13
 
13
14
  UnknownTypeError = Class.new(StandardError)
14
15
  MissingOptionError = Class.new(StandardError)
15
- TYPES = %i(string email password url integer money text flag datetime json plain_json)
16
+ TYPES = %i[string email password url integer money text flag datetime json
17
+ plain_json foreign_key]
16
18
 
17
19
  def initialize(*args)
18
20
  super
@@ -21,13 +23,13 @@ module Katapult
21
23
  self.type ||= :password if name.to_s =~ /password/
22
24
  self.type ||= :string
23
25
 
24
- validate
26
+ validate!
25
27
  end
26
28
 
27
29
  delegate :flag?, to: :type_inquiry
28
30
 
29
31
  def has_defaults?
30
- default and not [flag?, assignable_values].any?
32
+ !default.nil? and not [flag?, assignable_values].any?
31
33
  end
32
34
 
33
35
  def for_migration
@@ -37,13 +39,16 @@ module Katapult
37
39
  when :money then 'decimal{10,2}' # {precision,scale} = total digits, decimal places
38
40
  when :json then 'jsonb' # Indexable JSON
39
41
  when :plain_json then 'json' # Only use this if you need to
42
+ when :foreign_key then 'integer'
40
43
  else type end
41
44
 
42
45
  "#{name}:#{db_type}"
43
46
  end
44
47
 
45
48
  def test_value
46
- if assignable_values
49
+ if type == :foreign_key
50
+ associated_model.label_attr.test_value
51
+ elsif assignable_values
47
52
  assignable_values.first
48
53
 
49
54
  else
@@ -62,13 +67,17 @@ module Katapult
62
67
  end
63
68
  end
64
69
 
70
+ def assignable_values_as_list?
71
+ assignable_values.try(:to_a).present?
72
+ end
73
+
65
74
  private
66
75
 
67
76
  def type_inquiry
68
77
  @type.to_s.inquiry
69
78
  end
70
79
 
71
- def validate
80
+ def validate!
72
81
  TYPES.include?(type) or raise UnknownTypeError,
73
82
  "Attribute type :#{type} is not supported. Use one of #{TYPES.inspect}."
74
83
 
@@ -3,14 +3,11 @@ require 'generators/katapult/clearance/clearance_generator'
3
3
  module Katapult
4
4
  class Authentication < Element
5
5
 
6
- MissingUserModel = Class.new(StandardError)
7
-
8
- # attr name: The user model name
6
+ # @attr name: The user model name
9
7
  attr_accessor :system_email
10
8
 
11
9
  def ensure_user_model_attributes_present
12
- user_model = application_model.get_model(name) or raise MissingUserModel,
13
- "Could not find a model named #{ name }"
10
+ user_model = application_model.get_model!(name)
14
11
  user_attrs = user_model.attrs.map(&:name)
15
12
 
16
13
  user_model.attr(:email) unless user_attrs.include?('email')
@@ -0,0 +1,76 @@
1
+ # Models a Rails model
2
+
3
+ require 'katapult/element'
4
+ require 'katapult/elements/attribute'
5
+ require 'generators/katapult/model/model_generator'
6
+
7
+ module Katapult
8
+ class Model < Element
9
+
10
+ UnknownAttributeError = Class.new(StandardError)
11
+ MissingLabelAttributeError = Class.new(StandardError)
12
+
13
+ attr_accessor :attrs, :belongs_tos, :has_manys
14
+
15
+ def initialize(*args)
16
+ self.attrs = []
17
+ self._belongs_tos = []
18
+ self.belongs_tos = []
19
+ self.has_manys = []
20
+
21
+ super
22
+ end
23
+
24
+ # DSL
25
+ def attr(attr_name, options = {})
26
+ options[:model] = self
27
+ attrs << Attribute.new(attr_name, options)
28
+ end
29
+
30
+ # DSL
31
+ def belongs_to(model_name)
32
+ application_model.association name, belongs_to: model_name
33
+ end
34
+
35
+
36
+ def label_attr
37
+ renderable_attrs.first.presence or raise MissingLabelAttributeError
38
+ end
39
+
40
+ def label_attr?
41
+ label_attr.present?
42
+ rescue MissingLabelAttributeError
43
+ false
44
+ end
45
+
46
+ def db_fields
47
+ attrs.reject(&:skip_db)
48
+ end
49
+
50
+ def renderable_attrs
51
+ attrs.reject { |a| %w[plain_json json password].include? a.type.to_s }
52
+ end
53
+
54
+ def editable_attrs
55
+ attrs.reject { |a| %w[plain_json json].include? a.type.to_s }
56
+ end
57
+
58
+ def add_foreign_key_attrs(belongs_tos)
59
+ belongs_tos.each do |other_model|
60
+ attr "#{ other_model.name :variable }_id", type: :foreign_key,
61
+ assignable_values: "#{ other_model.name(:class) }.all.to_a",
62
+ allow_blank: true,
63
+ associated_model: other_model
64
+ end
65
+ end
66
+
67
+ def render
68
+ Generators::ModelGenerator.new(self).invoke_all
69
+ end
70
+
71
+ private
72
+
73
+ attr_accessor :_belongs_tos
74
+
75
+ end
76
+ end
@@ -2,7 +2,7 @@
2
2
  # class for the Attribute element.
3
3
 
4
4
  require 'katapult/element'
5
- require 'katapult/action'
5
+ require 'katapult/elements/action'
6
6
  require 'generators/katapult/web_ui/web_ui_generator'
7
7
 
8
8
  module Katapult
@@ -14,7 +14,6 @@ module Katapult
14
14
  RAILS_ACTIONS = %w[ index show new create edit update destroy ]
15
15
  UnknownActionError = Class.new(StandardError)
16
16
  UnknownModelError = Class.new(StandardError)
17
- MissingLabelAttrError = Class.new(StandardError)
18
17
 
19
18
  def initialize(*args)
20
19
  self.actions = []
@@ -41,8 +40,7 @@ module Katapult
41
40
 
42
41
  def model
43
42
  model_name = @model || self.name
44
- application_model.get_model(model_name) or raise UnknownModelError,
45
- "Cannot find a model named #{model_name}"
43
+ application_model.get_model! model_name
46
44
  end
47
45
 
48
46
  def params
@@ -81,16 +79,8 @@ module Katapult
81
79
  end
82
80
 
83
81
  def render
84
- validate!
85
82
  Generators::WebUIGenerator.new(self).invoke_all
86
83
  end
87
84
 
88
- private
89
-
90
- def validate!
91
- model.label_attr.present? or raise MissingLabelAttrError,
92
- 'Cannot render a WebUI without a model with a label attribute'
93
- end
94
-
95
85
  end
96
86
  end
@@ -1,7 +1,7 @@
1
- # The katapult generator base class, slightly adapted from Rails generators.
1
+ # The base class for katapult element generators
2
2
 
3
3
  require 'rails/generators'
4
- require 'katapult/generator_goodies'
4
+ require 'katapult/support/generator_goodies'
5
5
 
6
6
  module Katapult
7
7
  class Generator < Rails::Generators::NamedBase
@@ -2,7 +2,8 @@
2
2
 
3
3
  # This module is used inside the `katapult` binary and thus should not
4
4
  # require any gems in order to prevent version conflicts
5
- require_relative '../katapult/version'
5
+
6
+ require_relative '../../katapult/version'
6
7
  require 'bundler'
7
8
  require 'io/console'
8
9
 
@@ -7,8 +7,15 @@ module Katapult::GeneratorGoodies
7
7
 
8
8
  private
9
9
 
10
- def app_name
11
- File.basename(Dir.pwd)
10
+ def app_name(kind = nil)
11
+ machine_name = File.basename(Dir.pwd)
12
+ human_name = machine_name.tr('_', ' ').gsub(/\w+/, &:capitalize)
13
+
14
+ case kind.to_s
15
+ when '' then machine_name
16
+ when 'human' then human_name
17
+ else raise ArgumentError, "Unknown formatting: #{kind.inspect}"
18
+ end
12
19
  end
13
20
 
14
21
  # Override Thor method
@@ -1,7 +1,7 @@
1
1
  module Katapult
2
2
  ruby_version_path = File.expand_path('../../.ruby-version', __dir__)
3
3
 
4
- VERSION = '0.3.0'
4
+ VERSION = '0.4.0'
5
5
  RUBY_VERSION = File.read(ruby_version_path).strip
6
6
  RAILS_VERSION = '5.1.4'
7
7
  end
data/script/console CHANGED
@@ -4,11 +4,14 @@
4
4
  # Run `script/console` from the gem root to start an IRB with the gem loaded.
5
5
 
6
6
  # Remember to require classes before using them,
7
- # i.e. `require 'katapult/model'` before `Katapult::Model.new :example_name`
7
+ # i.e. `require 'katapult/elements/model'` before using `Katapult::Model`
8
+
9
+ require 'bundler/setup'
8
10
 
9
11
  irb_options = [
10
12
  '-Ilib', # add lib/ to load_path
11
- '-d', # set $DEBUG = true
13
+ # '-d', # set $DEBUG = true
14
+
12
15
  # Requires
13
16
  '-rkatapult/version',
14
17
  '-rrails',
data/script/update CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require_relative '../lib/katapult/version'
4
- require_relative '../lib/katapult/binary_util'
4
+ require_relative '../lib/katapult/support/binary_util'
5
5
 
6
6
  u = Katapult::BinaryUtil
7
7
  version_path = 'lib/katapult/version.rb'
data/spec/action_spec.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'katapult/action'
1
+ require 'katapult/elements/action'
2
2
 
3
3
  describe Katapult::Action do
4
4
 
@@ -0,0 +1,26 @@
1
+ require 'katapult/application_model'
2
+
3
+ describe Katapult::ApplicationModel do
4
+
5
+ describe '#crud' do
6
+ it 'adds a model plus a web UI with CRUD actions' do
7
+ model = <<-MODEL
8
+ crud 'user' do |user|
9
+ user.attr :age
10
+ end
11
+ MODEL
12
+
13
+ subject = described_class.parse(model)
14
+ expect(subject.models.count).to be 1
15
+ user = subject.models.first
16
+ expect(user.name).to eq 'user'
17
+ expect(user.attrs.count).to be 1
18
+ expect(user.attrs.first.name).to eq 'age'
19
+
20
+ expect(subject.web_uis.count).to be 1
21
+ web_ui = subject.web_uis.first
22
+ expect(web_ui.actions.map(&:name)).to match Katapult::WebUI::RAILS_ACTIONS
23
+ end
24
+ end
25
+
26
+ end