magicka 1.0.0 → 1.1.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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -0
  3. data/README.md +3 -3
  4. data/config/check_specs.yml +0 -2
  5. data/config/yardstick.yml +8 -2
  6. data/lib/magicka/aggregator/method_builder.rb +35 -28
  7. data/lib/magicka/aggregator.rb +16 -8
  8. data/lib/magicka/display.rb +1 -1
  9. data/lib/magicka/element/class_methods.rb +2 -0
  10. data/lib/magicka/element.rb +4 -2
  11. data/lib/magicka/helper/aggregator_options.rb +64 -0
  12. data/lib/magicka/helper/class_methods.rb +10 -2
  13. data/lib/magicka/helper/method_builder.rb +10 -6
  14. data/lib/magicka/helper.rb +12 -6
  15. data/lib/magicka/version.rb +1 -1
  16. data/magicka.gemspec +1 -1
  17. data/spec/dummy/app/controllers/application_controller.rb +1 -0
  18. data/spec/dummy/app/controllers/documents_controller.rb +9 -0
  19. data/spec/dummy/app/models/document.rb +5 -0
  20. data/spec/dummy/app/models/magicka/data_entry.rb +7 -0
  21. data/spec/dummy/app/models/magicka/data_table.rb +6 -0
  22. data/spec/dummy/app/views/documents/show.html.erb +6 -0
  23. data/spec/dummy/app/views/templates/display/_data_entry.html.erb +2 -0
  24. data/spec/dummy/config/environments/development.rb +1 -0
  25. data/spec/dummy/config/initializers/magicka.rb +7 -0
  26. data/spec/dummy/config/routes.rb +1 -0
  27. data/spec/dummy/db/schema.rb +5 -0
  28. data/spec/integration/yard/magicka/helper_spec.rb +33 -0
  29. data/spec/lib/magicka/aggregator/class_methods_spec.rb +352 -0
  30. data/spec/lib/magicka/aggregator/method_builder_spec.rb +29 -0
  31. data/spec/lib/magicka/aggregator_spec.rb +0 -221
  32. data/spec/lib/magicka/helper/aggregator_options_spec.rb +99 -0
  33. data/spec/lib/magicka/helper/class_methods_spec.rb +101 -0
  34. data/spec/lib/magicka/helper_spec.rb +2 -18
  35. data/spec/support/factories/document.rb +7 -0
  36. data/spec/support/factory_bot.rb +7 -0
  37. data/spec/support/models/custom_aggregator.rb +12 -0
  38. data/spec/support/models/my_element.rb +6 -0
  39. metadata +21 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 662d942d270879b97fb0ee3be36a41c4448db92ab11f2f3462fd4315a53b06d7
4
- data.tar.gz: b6dc02755727b9f84ab61dd66eb34d71a8ecac53da565594e49f69c1e632b784
3
+ metadata.gz: 6bb01a5f327547f6240b632c197db84720e4d4db15cf1c8db5670f22a71c57f7
4
+ data.tar.gz: 19b15da94bc310d043362e8f11cd10763c169c2ec37d8c04ed1f1b9fd214971c
5
5
  SHA512:
6
- metadata.gz: 7bad26b83421ea3d47a6d002aa521f754fea7df036ed89ebf457297b076ffc2118bbdaf3fe2465a8cff8e1b3f176ef02dddb0211b20e3b2ab9f0c010b1cf75f6
7
- data.tar.gz: ce04771c5649517ee7c17b54978b61137c897e0e23118aac1806b4035ab96aafba6aef857f1cc498048e4ff37b37d0eef433f0133fd871cb364b19cedab5a08a
6
+ metadata.gz: 84ff51739e85682fba655c81d69217735808c3b450d13a4d26dc9f890a5bbb04f1fc89c107f900b984f8c2d2eaccbfb5b39c3a3f2c8539427bf13b4b93cef244
7
+ data.tar.gz: 3116e9ed5c060ac7faf810c3f752cded1442bbf745e668f0044ca0a531a5f426943988f12ac7f34e75c1c60e5003ee7e1d314d404e3ca63666a2fa483c1d76f2
data/.rubocop.yml CHANGED
@@ -4,6 +4,9 @@ inherit_from: .rubocop_todo.yml
4
4
  AllCops:
5
5
  TargetRubyVersion: 2.7
6
6
 
7
+ Layout/LineLength:
8
+ Max: 90
9
+
7
10
  Metrics/BlockLength:
8
11
  Exclude:
9
12
  - 'spec/**/*_spec.rb'
@@ -44,3 +47,7 @@ Style/HashTransformKeys:
44
47
 
45
48
  Style/HashTransformValues:
46
49
  Enabled: true
50
+
51
+ RSpec/DescribeClass:
52
+ Exclude:
53
+ - 'spec/integration/**/*_spec.rb'
data/README.md CHANGED
@@ -12,13 +12,13 @@ Magicka
12
12
  Magica helps creating html templates for forms and display data using js applications
13
13
  such as AngulaJS
14
14
 
15
- Current Release: [2.0.0](https://github.com/darthjee/magicka/tree/1.0.0)
15
+ Current Release: [1.1.0](https://github.com/darthjee/magicka/tree/1.1.0)
16
16
 
17
- [Next release](https://github.com/darthjee/magicka/compare/1.0.0...master)
17
+ [Next release](https://github.com/darthjee/magicka/compare/1.1.0...master)
18
18
 
19
19
  Yard Documentation
20
20
  -------------------
21
- [https://www.rubydoc.info/gems/magicka/1.0.0](https://www.rubydoc.info/gems/magicka/1.0.0)
21
+ [https://www.rubydoc.info/gems/magicka/1.1.0](https://www.rubydoc.info/gems/magicka/1.1.0)
22
22
 
23
23
  Installation
24
24
  ---------------
@@ -1,7 +1,5 @@
1
1
  ignore:
2
2
  - lib/magicka/version.rb
3
3
  - lib/magicka.rb
4
- - lib/magicka/aggregator/class_methods.rb
5
- - lib/magicka/aggregator/method_builder.rb
6
4
  - lib/magicka/helper/class_methods.rb
7
5
  - lib/magicka/helper/method_builder.rb
data/config/yardstick.yml CHANGED
@@ -15,10 +15,16 @@ rules:
15
15
  exclude: []
16
16
  ExampleTag:
17
17
  enabled: true
18
- exclude: []
18
+ exclude:
19
+ - Magicka::Aggregator#initialize
19
20
  ReturnTag:
20
21
  enabled: true
21
- exclude: []
22
+ exclude:
23
+ - Magicka::Form#button
24
+ - Magicka::Form#select
25
+ - Magicka::Form#input
26
+ - Magicka::Display#select
27
+ - Magicka::Display#input
22
28
  Summary::Presence:
23
29
  enabled: true
24
30
  exclude:
@@ -6,13 +6,23 @@ module Magicka
6
6
  #
7
7
  # Class responsible for building an {Aggregator} method
8
8
  class MethodBuilder < Sinclair
9
- # @param klass [Class.new<Aggregator>]
10
- # Aggragator class to receive the method
11
- # @param element_class [Class<Magicka::ELement>]
12
- # Class of the element to be rendered
13
- # @param method_name [String,Symbol]
14
- # Name of the method that will render the element
15
- # @param template [String] custom template file to be used
9
+ # @overload initialize(klass, element_class, method_name = nil, template: nil)
10
+ # @param element_class [Class<Magicka::Element>]
11
+ # Class of the element to be rendered
12
+ # @param klass [Class<Aggregator>]
13
+ # Aggragator class to receive the method
14
+ # @param method_name [String,Symbol]
15
+ # Name of the method that will render the element
16
+ # @param template [String] custom template file to be used
17
+ #
18
+ # @overload initialize(klass, element_class_name, method_name = nil, template: nil)
19
+ # @param element_class_name [String]
20
+ # String name of Class of the element to be rendered
21
+ # @param klass [Class<Aggregator>]
22
+ # Aggragator class to receive the method
23
+ # @param method_name [String,Symbol]
24
+ # Name of the method that will render the element
25
+ # @param template [String] custom template file to be used
16
26
  def initialize(klass, element_class, method_name = nil, template: nil)
17
27
  super(klass)
18
28
 
@@ -25,38 +35,35 @@ module Magicka
25
35
  #
26
36
  # @return [Aggregator::MethodBuilder] return self
27
37
  def prepare
28
- element_klass = element_class
29
- template_file = template
30
-
31
- add_method(method_name) do |field, model: self.model, **args|
32
- element_klass.render(
33
- renderer: renderer, field: field,
34
- model: model, template: template_file,
35
- **args
36
- )
38
+ tap do |builder|
39
+ add_method(method_name) do |field, model: self.model, **args|
40
+ builder.element_class.render(
41
+ renderer: renderer, field: field,
42
+ model: model, template: builder.template,
43
+ **args
44
+ )
45
+ end
37
46
  end
38
-
39
- self
40
47
  end
41
48
 
42
- private
43
-
44
- attr_reader :element_class, :template
45
- # @method element_class
46
- # @api private
47
- # @private
48
- #
49
49
  # Class of the element to be rendered by the method
50
50
  #
51
51
  # @return [Class<Magicka::Element>]
52
+ def element_class
53
+ return @element_class if @element_class.is_a?(Class)
54
+
55
+ @element_class = @element_class.constantize
56
+ end
52
57
 
53
58
  # @method template
54
59
  # @api private
55
- # @private
56
60
  #
57
- # template file
61
+ # Template file
58
62
  #
59
63
  # @return [String]
64
+ attr_reader :template
65
+
66
+ private
60
67
 
61
68
  # name of the method to be generated
62
69
  #
@@ -66,7 +73,7 @@ module Magicka
66
73
  # @return [String,Symbol]
67
74
  def method_name
68
75
  @method_name ||= element_class
69
- .name
76
+ .to_s
70
77
  .underscore
71
78
  .gsub(%r{.*/}, '')
72
79
  end
@@ -8,9 +8,7 @@ module Magicka
8
8
  autoload :MethodBuilder, 'magicka/aggregator/method_builder'
9
9
  autoload :ClassMethods, 'magicka/aggregator/class_methods'
10
10
 
11
- class << self
12
- include Aggregator::ClassMethods
13
- end
11
+ extend Aggregator::ClassMethods
14
12
 
15
13
  attr_reader :model
16
14
  # @method model
@@ -21,14 +19,24 @@ module Magicka
21
19
  # @return [String]
22
20
 
23
21
  # @method self.with_element(element_class, method_name = nil, template: nil)
22
+ # @api public
24
23
  #
25
24
  # Configure an {Aggregator} adding a method to render an element
26
25
  #
27
- # @param element_class [Class<Magicka::ELement>]
28
- # Class of the element to be rendered
29
- # @param method_name [String,Symbol]
30
- # Name of the method that will render the element
31
- # @param template [String] custom template file to be used
26
+ # @overload with_element(element_class, method_name = nil, template: nil)
27
+ # @param element_class [Class<Magicka::Element>]
28
+ # Class of the element to be rendered
29
+ # @param method_name [String,Symbol]
30
+ # Name of the method that will render the element
31
+ # @param template [String] custom template file to be used
32
+ #
33
+ # @overload with_element(element_class_name, method_name = nil, template: nil)
34
+ # @param element_class_name [String]
35
+ # String representation of a class of {Magicka::Element}
36
+ # of the element to be rendered
37
+ # @param method_name [String,Symbol]
38
+ # Name of the method that will render the element
39
+ # @param template [String] custom template file to be used
32
40
  #
33
41
  # @see Aggregator::ClassMethods#with_element
34
42
  # @see Aggregator::MethodBuilder
@@ -13,7 +13,7 @@ module Magicka
13
13
  # Used to not render a button when using
14
14
  # display and not form
15
15
  #
16
- # #return [NilClass]
16
+ # @return [NilClass]
17
17
  def button(**_args); end
18
18
 
19
19
  # @method input(field, model: self.model, **options)
@@ -11,6 +11,8 @@ module Magicka
11
11
  # @param renderer [Object] object responsible for rendering
12
12
  # the HTML
13
13
  # @param args [Hash] Extra options
14
+ #
15
+ # @return (see Magicka::Element#render)
14
16
  def render(renderer:, **args)
15
17
  new(renderer: renderer, **args).render
16
18
  end
@@ -42,12 +42,14 @@ module Magicka
42
42
 
43
43
  private
44
44
 
45
- attr_reader :renderer
46
45
  # @api private
47
46
  # @private
48
47
  # @method renderer
49
48
  #
50
49
  # Object responsible for rendering the HTML
50
+ #
51
+ # @return [ActionView::Base]
52
+ attr_reader :renderer
51
53
 
52
54
  # @api private
53
55
  # @private
@@ -73,7 +75,7 @@ module Magicka
73
75
  end
74
76
  end
75
77
 
76
- # @api public
78
+ # @api private
77
79
  # @private
78
80
  #
79
81
  # Returns template file location
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magicka
4
+ module Helper
5
+ # @api private
6
+ #
7
+ # Options when generating {Helper} aggregator methods
8
+ #
9
+ # This is used when calling {Helper.with Helper.with}
10
+ class AggregatorOptions < Sinclair::Options
11
+ with_options :aggregator, :type, :config_block
12
+
13
+ # @method config_block
14
+ # @api private
15
+ #
16
+ # Block to be used when configuring a new aggregator class
17
+ #
18
+ # @return [Proc]
19
+
20
+ # Returns the ready to use aggregator class
21
+ #
22
+ # @return [Class<Aggregator>]
23
+ def configured_aggregator
24
+ @configured_aggregator ||= configure_aggregator
25
+ end
26
+
27
+ # Type of the aggregator
28
+ #
29
+ # Type of aggregator will be used when defining the helper method
30
+ #
31
+ # @return [Symbol]
32
+ def type
33
+ @type ||= aggregator.type
34
+ end
35
+
36
+ private
37
+
38
+ # @private
39
+ # Configure the aggregator class by running {#config_block}
40
+ #
41
+ # @return [Class<Aggregator>]
42
+ def configure_aggregator
43
+ klass = aggregator_class
44
+ return klass unless config_block
45
+
46
+ klass.instance_eval(&config_block)
47
+ klass
48
+ end
49
+
50
+ # @private
51
+ # Return the aggregator class
52
+ #
53
+ # When aggregator class is defined as a String, this is then used to
54
+ # return the correct class
55
+ #
56
+ # @return [Class<Aggregator>]
57
+ def aggregator_class
58
+ return aggregator if aggregator.is_a?(Class)
59
+
60
+ aggregator.constantize
61
+ end
62
+ end
63
+ end
64
+ end
@@ -5,8 +5,16 @@ module Magicka
5
5
  # Class methods for {Magicka::Helper}
6
6
  module ClassMethods
7
7
  # (see Magicka::Helper.with)
8
- def with(aggregator_class, type = aggregator_class.type)
9
- MethodBuilder.new(self).build_aggregator(aggregator_class, type)
8
+ def with(aggregator, type = nil, &block)
9
+ options = AggregatorOptions.new(
10
+ aggregator: aggregator,
11
+ type: type,
12
+ config_block: block
13
+ )
14
+
15
+ MethodBuilder.build(self, options) do
16
+ build_aggregator
17
+ end
10
18
  end
11
19
  end
12
20
  end
@@ -2,15 +2,19 @@
2
2
 
3
3
  module Magicka
4
4
  module Helper
5
+ # @api private
6
+ #
5
7
  # Builds methods for {Magicka::Helper}
6
8
  class MethodBuilder < Sinclair
7
- # (see Magicka::Helper.with)
8
- def build_aggregator(aggregator_class, type = aggregator_class.type)
9
- add_method("magicka_#{type}") do |model, &block|
10
- block.call(aggregator_class.new(self, model))
11
- end
9
+ # Build aggregator helper method
10
+ #
11
+ # @return [Array<MethodDefinition>]
12
+ def build_aggregator
13
+ opts = options
12
14
 
13
- build
15
+ add_method("magicka_#{opts.type}") do |model, &block|
16
+ block.call(opts.configured_aggregator.new(self, model))
17
+ end
14
18
  end
15
19
  end
16
20
  end
@@ -1,19 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Magicka
4
+ # @api public
5
+ #
4
6
  # Helper module to be used on rails
5
7
  module Helper
6
- autoload :ClassMethods, 'magicka/helper/class_methods'
7
- autoload :MethodBuilder, 'magicka/helper/method_builder'
8
+ autoload :AggregatorOptions, 'magicka/helper/aggregator_options'
9
+ autoload :ClassMethods, 'magicka/helper/class_methods'
10
+ autoload :MethodBuilder, 'magicka/helper/method_builder'
8
11
 
9
- class << self
10
- include Helper::ClassMethods
11
- end
12
+ extend Helper::ClassMethods
12
13
 
13
14
  with Form
14
15
  with Display
15
16
 
16
- # @method self.with(aggregator_class, type = aggregator_class.type)
17
+ # @method self.with(aggregator_class, type = aggregator_class.type, &config_block)
18
+ # @api public
17
19
  #
18
20
  # Adds a helper method magicka_+type+
19
21
  #
@@ -23,10 +25,13 @@ module Magicka
23
25
  # Agragator to be initialized
24
26
  # @param type [String,Symbol] type of aggregator,
25
27
  # this will define the method name
28
+ # @param config_block [Proc] block to be evaluated and configure the aggregator
29
+ # when it is first used
26
30
  #
27
31
  # @return [Array<NilClass>]
28
32
 
29
33
  # @method magicka_form(model)
34
+ # @api public
30
35
  #
31
36
  # Execute a block with an aggregator focused on a model
32
37
  #
@@ -41,6 +46,7 @@ module Magicka
41
46
  # @return [String]
42
47
 
43
48
  # @method magicka_display(model)
49
+ # @api public
44
50
  #
45
51
  # Execute a block with an aggregator focused on a model
46
52
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Magicka
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
data/magicka.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |gem|
20
20
  gem.require_paths = ['lib']
21
21
 
22
22
  gem.add_runtime_dependency 'activesupport', '~> 7.0.x'
23
- gem.add_runtime_dependency 'sinclair', '>= 2.0.0'
23
+ gem.add_runtime_dependency 'sinclair', '>= 2.0.1'
24
24
 
25
25
  gem.add_development_dependency 'actionpack', '7.0.4.3'
26
26
  gem.add_development_dependency 'activerecord', '7.0.4.3'
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ApplicationController < ActionController::Base
4
+ helper Magicka::Helper
4
5
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DocumentsController < ApplicationController
4
+ def show
5
+ document = Document.find(params[:id])
6
+
7
+ render :show, locals: { document: document }
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Document < ActiveRecord::Base
4
+ validates :name, presence: true
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magicka
4
+ class DataEntry < Magicka::Text
5
+ with_locals :model
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magicka
4
+ class DataTable < Aggregator
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ <dt>
2
+ <%= magicka_data_table(document) do |table| %>
3
+ <%= table.data_entry(:name) %>
4
+ <%= table.data_entry(:reference) %>
5
+ <% end %>
6
+ </dt>
@@ -0,0 +1,2 @@
1
+ <dh><%= label %></dh>
2
+ <dd><%= model.public_send(field) %></dd><br />
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Rails.application.configure do
4
+ config.hosts << 'www.example.com'
4
5
  # Settings specified here will take precedence over
5
6
  # those in config/application.rb.
6
7
 
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'magicka'
4
+
5
+ Magicka::Helper.with('Magicka::DataTable', :data_table) do
6
+ with_element(Magicka::DataEntry)
7
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Rails.application.routes.draw do
4
+ resources :documents
4
5
  end
@@ -2,4 +2,9 @@
2
2
 
3
3
  ActiveRecord::Schema.define do
4
4
  self.verbose = false
5
+
6
+ create_table :documents, force: true do |t|
7
+ t.string :name
8
+ t.string :reference
9
+ end
5
10
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'yard for Magicka::Helper' do
6
+ describe '.with' do
7
+ describe 'when passing only an aggregator' do
8
+ let(:document) { create(:document) }
9
+
10
+ let(:expected_body) do
11
+ [
12
+ '<dh>Name</dh>',
13
+ "<dd>#{document.name}</dd><br />",
14
+ '',
15
+ '<dh>Reference</dh>',
16
+ "<dd>#{document.reference}</dd>"
17
+ ].join(" *\n *")
18
+ end
19
+
20
+ before { get "/documents/#{document.id}" }
21
+
22
+ it do
23
+ expect(response.status).to eq(200)
24
+ end
25
+
26
+ it do
27
+ expect(response.body).to match(
28
+ Regexp.new(expected_body)
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end