magicka 0.0.1 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6013fd94f8df1865e13bd0f17ddfd37b9605fb6cb72eebb14d7fa6a4761f48fd
4
- data.tar.gz: 4ae9c53984064068371fc060aaf178a34f772940908619d4937fc4bf6345a345
3
+ metadata.gz: fb9d51d1218f32ac849193da117869a8bbc8bfa51f8cb2f8c7eb3c4845309200
4
+ data.tar.gz: e6728fa98edd29a39de7c53497e542496468006f7c5902f112b3860835f2579d
5
5
  SHA512:
6
- metadata.gz: 2bdddadc15edd651be2484b29072e04b3b717d1cd45741996a3426a069bb5e6980fd42bf34d2d813b675d392d96f1aab278a87484f82488a7255bb4414ee350e
7
- data.tar.gz: '0783b6e54e90f43e71cf6d361ee34b9ae3bb4179f87b48f96e1a47c47ae72a2e4e8fa92d2e0f5870b2649905208e1bfa3fc6efbca7e24e40b260efdc3f05c7cc'
6
+ metadata.gz: 07b9a25dd6fd4bb5d978a0d1a8f20e94320735b288ad469f31a2c31331f146f6b0f7c9ef54294d171e87732af3090e3093f7b04785a165ebf89d59f4e9ffb09a
7
+ data.tar.gz: 0da01e6080f9c53033dd44ff44f1fe37e442c27875f477d2c16005c3f17fe604a2206c3e10cf20d20b3a0732ca8ac4eb56226f3ac8294ed41604864173632e94
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- Jace
1
+ Magicka
2
2
  ====
3
3
  [![Code Climate](https://codeclimate.com/github/darthjee/magicka/badges/gpa.svg)](https://codeclimate.com/github/darthjee/magicka)
4
4
  [![Test Coverage](https://codeclimate.com/github/darthjee/magicka/badges/coverage.svg)](https://codeclimate.com/github/darthjee/magicka/coverage)
@@ -11,7 +11,7 @@ Jace
11
11
 
12
12
  Yard Documentation
13
13
  -------------------
14
- [https://www.rubydoc.info/gems/magicka/0.0.1](https://www.rubydoc.info/gems/magicka/0.0.1)
14
+ [https://www.rubydoc.info/gems/magicka/0.1,0](https://www.rubydoc.info/gems/magicka/0.1.0)
15
15
 
16
16
  Installation
17
17
  ---------------
@@ -1,2 +1,3 @@
1
1
  ignore:
2
2
  - lib/magicka/version.rb
3
+ - lib/magicka.rb
@@ -1,4 +1,4 @@
1
- threshold: 100
1
+ threshold: 90.6
2
2
  require_exact_threshold: false
3
3
  rules:
4
4
  ApiTag::Presence:
@@ -2,6 +2,16 @@
2
2
 
3
3
  # @api public
4
4
  # @author darthjee
5
- class Magicka
6
- autoload :VERSION, 'magicka/version'
5
+
6
+ require 'sinclair'
7
+
8
+ # @api public
9
+ # @author Darthjee
10
+ #
11
+ # module holding herlper to render inputs
12
+ module Magicka
13
+ autoload :VERSION, 'magicka/version'
14
+ autoload :Element, 'magicka/element'
15
+ autoload :Input, 'magicka/input'
16
+ autoload :MethodBuilder, 'magicka/method_builder'
7
17
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magicka
4
+ # @api public
5
+ #
6
+ # Base class for element rendering
7
+ class Element < Sinclair::Options
8
+ autoload :ClassMethods, 'magicka/element/class_methods'
9
+
10
+ skip_validation
11
+
12
+ class << self
13
+ alias with_attributes with_options
14
+
15
+ include ClassMethods
16
+ end
17
+
18
+ # @method with_attributes
19
+ # @api public
20
+ # @!visibility public
21
+ #
22
+ # Adds attribute
23
+ #
24
+ # This will affect initialization and add readers
25
+ #
26
+ # @return [Array]
27
+
28
+ # Render element HTML
29
+ def render
30
+ renderer.render partial: template, locals: locals
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :renderer
36
+ # @api private
37
+ # @private
38
+ # @method renderer
39
+ #
40
+ # Object responsible for rendering the HTML
41
+
42
+ # @api private
43
+ # @private
44
+ #
45
+ # @param (see .render)
46
+ def initialize(renderer:, **args)
47
+ @renderer = renderer
48
+ super(**args)
49
+ end
50
+
51
+ # @api private
52
+ # @private
53
+ #
54
+ # Returns hash of local variables
55
+ #
56
+ # Local variablees will be available when rendering
57
+ # the template
58
+ #
59
+ # @return [Hash]
60
+ def locals
61
+ self.class.locals.inject({}) do |hash, attribute|
62
+ hash.merge!(attribute => send(attribute))
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magicka
4
+ class Element < Sinclair::Options
5
+ # Class methods used for metaprograming of elements
6
+ module ClassMethods
7
+ # render template using the given prameters
8
+ #
9
+ # @param renderer [Object] object responsible for rendering
10
+ # the HTML
11
+ # @param args [Hash] Extra options
12
+ def render(renderer:, **args)
13
+ new(renderer: renderer, **args).render
14
+ end
15
+
16
+ # list of attributes to be used when rendering
17
+ #
18
+ # @return [Set<Symbol>]
19
+ def locals
20
+ @locals ||= superclass.try(:locals)&.dup || Set.new([])
21
+ end
22
+
23
+ private
24
+
25
+ # @api public
26
+ # @!visibility public
27
+ #
28
+ # Sets template for element type
29
+ #
30
+ # @return [Array<Sinclair::MethodDefinition>]
31
+ def template(template)
32
+ MethodBuilder
33
+ .new(self)
34
+ .add_template(template)
35
+ end
36
+
37
+ # @api public
38
+ # @!visibility public
39
+ #
40
+ # Add an attribute to locals when rendereing
41
+ #
42
+ # the attribute will be a call to the a method
43
+ # with same name
44
+ #
45
+ # @return [Set<Symbol>]
46
+ def with_locals(*args)
47
+ locals.merge(args)
48
+ end
49
+
50
+ # @api public
51
+ # @!visibility public
52
+ #
53
+ # Adds attribute and locals
54
+ #
55
+ # @return [Array]
56
+ def with_attribute_locals(*args)
57
+ with_locals(*args)
58
+ with_attributes(*args)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magicka
4
+ # Input element representing an HTML +<input/>+
5
+ class Input < Element
6
+ with_attribute_locals :field, :placeholder, :label
7
+ with_attributes :model
8
+ with_locals :ng_errors, :ng_model
9
+
10
+ template 'templates/forms/input'
11
+
12
+ private
13
+
14
+ # @api private
15
+ # @private
16
+ #
17
+ # Label to be shon near the input
18
+ #
19
+ # when no label is provided, the name of
20
+ # the field is used
21
+ #
22
+ # @return [String]
23
+ def label
24
+ @label ||= field.to_s.capitalize.gsub(/_/, ' ')
25
+ end
26
+
27
+ # @api private
28
+ # @private
29
+ #
30
+ # ng model to be represented with the input
31
+ #
32
+ # @return [String]
33
+ def ng_model
34
+ [model, field].join('.')
35
+ end
36
+
37
+ # @api private
38
+ # @private
39
+ #
40
+ # ng errors to be exposed with the input
41
+ #
42
+ # @return [String]
43
+ def ng_errors
44
+ [model, :errors, field].join('.')
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magicka
4
+ # @api private
5
+ #
6
+ # class responsible for building methods on {Magicka::Element}
7
+ class MethodBuilder < Sinclair
8
+ # adds a mehtod +#template+
9
+ #
10
+ # The method will always return the template given in the params
11
+ #
12
+ # @param template [String] path to template file
13
+ #
14
+ # @return [Array<Sinclair::MethodDefinition>]
15
+ def add_template(template)
16
+ add_method(:template) do
17
+ template
18
+ end
19
+
20
+ build
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Magicka
4
- VERSION = '0.0.1'
3
+ module Magicka
4
+ VERSION = '0.1.0'
5
5
  end
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Magicka::Element::ClassMethods do
6
+ subject(:element) { klass.new(renderer: renderer) }
7
+
8
+ let(:klass) do
9
+ Class.new(Magicka::Element)
10
+ end
11
+
12
+ let(:renderer) { instance_double('renderer') }
13
+ let(:template) { 'templates/forms/element' }
14
+ let(:locals) { {} }
15
+
16
+ describe '.with_attributes' do
17
+ it do
18
+ expect { klass.send(:with_attributes, :field) }
19
+ .to add_method(:field)
20
+ .to(klass)
21
+ end
22
+ end
23
+
24
+ describe '.template' do
25
+ it do
26
+ expect { klass.send(:template, template) }
27
+ .to add_method(:template)
28
+ .to(klass)
29
+ end
30
+
31
+ context 'when method is build as requested' do
32
+ before { klass.send(:template, template) }
33
+
34
+ it 'returns the defined template when method is called' do
35
+ expect(element.template).to eq(template)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '.render' do
41
+ before do
42
+ klass.send(:template, template)
43
+
44
+ allow(renderer)
45
+ .to receive(:render)
46
+ .with(partial: template, locals: locals)
47
+ end
48
+
49
+ it do
50
+ klass.render(renderer: renderer)
51
+
52
+ expect(renderer).to have_received(:render)
53
+ end
54
+
55
+ context 'when called with extra params' do
56
+ it do
57
+ klass.render(renderer: renderer, name: 'Name')
58
+
59
+ expect(renderer).to have_received(:render)
60
+ end
61
+ end
62
+ end
63
+
64
+ describe '.locals' do
65
+ it { expect(Magicka::Element.locals).to eq(Set.new([])) }
66
+
67
+ context 'when calling on a subclass' do
68
+ it { expect(klass.locals).to eq(Set.new([])) }
69
+ end
70
+
71
+ context 'when called on subclass' do
72
+ let(:subclass) { Class.new(klass) }
73
+
74
+ before { klass.send(:with_locals, :field, :model) }
75
+
76
+ it { expect(subclass.locals).to eq(Set.new(%i[field model])) }
77
+ end
78
+ end
79
+
80
+ describe 'with_locals' do
81
+ it do
82
+ expect { klass.send(:with_locals, :field, :model) }
83
+ .to change(klass, :locals)
84
+ .from([])
85
+ .to(%i[field model])
86
+ end
87
+
88
+ it do
89
+ expect { klass.send(:with_locals, :field, :model) }
90
+ .not_to change(Magicka::Element, :locals)
91
+ end
92
+
93
+ it do
94
+ expect { klass.send(:with_locals, :field) }
95
+ .not_to add_method(:field)
96
+ .to(klass)
97
+ end
98
+
99
+ context 'when called on subclass' do
100
+ let(:subclass) { Class.new(klass) }
101
+
102
+ before { klass.send(:with_locals, :field, :model) }
103
+
104
+ it do
105
+ expect { subclass.send(:with_locals, :error) }
106
+ .to change(subclass, :locals)
107
+ .from(%i[field model])
108
+ .to(%i[field model error])
109
+ end
110
+
111
+ it do
112
+ expect { subclass.send(:with_locals, :error) }
113
+ .not_to change(klass, :locals)
114
+ end
115
+ end
116
+ end
117
+
118
+ describe 'with_attribute_locals' do
119
+ it do
120
+ expect { klass.send(:with_attribute_locals, :field, :model) }
121
+ .to change(klass, :locals)
122
+ .from([])
123
+ .to(%i[field model])
124
+ end
125
+
126
+ it do
127
+ expect { klass.send(:with_attribute_locals, :field, :model) }
128
+ .not_to change(Magicka::Element, :locals)
129
+ end
130
+
131
+ it do
132
+ expect { klass.send(:with_attribute_locals, :field) }
133
+ .to add_method(:field)
134
+ .to(klass)
135
+ end
136
+
137
+ context 'when called on subclass' do
138
+ let(:subclass) { Class.new(klass) }
139
+
140
+ before { klass.send(:with_attribute_locals, :field, :model) }
141
+
142
+ it do
143
+ expect { subclass.send(:with_attribute_locals, :error) }
144
+ .to change(subclass, :locals)
145
+ .from(%i[field model])
146
+ .to(%i[field model error])
147
+ end
148
+
149
+ it do
150
+ expect { subclass.send(:with_attribute_locals, :error) }
151
+ .not_to change(klass, :locals)
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Magicka::Element do
6
+ subject(:element) { klass.new(renderer: renderer) }
7
+
8
+ let(:klass) do
9
+ Class.new(described_class)
10
+ end
11
+
12
+ let(:renderer) { instance_double('renderer') }
13
+ let(:template) { 'templates/forms/element' }
14
+ let(:locals) { {} }
15
+
16
+ describe '#render' do
17
+ before do
18
+ klass.send(:template, template)
19
+
20
+ allow(renderer)
21
+ .to receive(:render)
22
+ .with(partial: template, locals: locals)
23
+ end
24
+
25
+ it do
26
+ element.render
27
+
28
+ expect(renderer).to have_received(:render)
29
+ end
30
+
31
+ context 'when initialized with extra params' do
32
+ subject(:element) do
33
+ klass.new(renderer: renderer, name: 'Name')
34
+ end
35
+
36
+ it do
37
+ element.render
38
+
39
+ expect(renderer).to have_received(:render)
40
+ end
41
+ end
42
+
43
+ context 'when class have locals defined' do
44
+ subject(:element) do
45
+ klass.new(renderer: renderer, name: 'Name')
46
+ end
47
+
48
+ let(:locals) { { name: 'Name' } }
49
+
50
+ before do
51
+ klass.send(:with_attribute_locals, :name)
52
+ end
53
+
54
+ it do
55
+ element.render
56
+
57
+ expect(renderer).to have_received(:render)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Magicka::Input do
6
+ let(:renderer) { instance_double('renderer') }
7
+ let(:template) { 'templates/forms/input' }
8
+
9
+ let(:model) { :my_model }
10
+ let(:field) { :field }
11
+ let(:label) { 'Label' }
12
+ let(:placeholder) { 'Value' }
13
+
14
+ let(:locals) do
15
+ {
16
+ field: field,
17
+ label: label,
18
+ ng_errors: 'my_model.errors.field',
19
+ ng_model: 'my_model.field',
20
+ placeholder: placeholder
21
+ }
22
+ end
23
+
24
+ describe '.render' do
25
+ let(:arguments) do
26
+ {
27
+ renderer: renderer,
28
+ field: field,
29
+ label: label,
30
+ placeholder: placeholder,
31
+ model: model
32
+ }
33
+ end
34
+
35
+ before do
36
+ allow(renderer)
37
+ .to receive(:render)
38
+ .with(partial: template, locals: locals)
39
+ end
40
+
41
+ it do
42
+ described_class.render(arguments)
43
+
44
+ expect(renderer).to have_received(:render)
45
+ end
46
+
47
+ context 'when called with extra params' do
48
+ it do
49
+ described_class.render(name: 'Name', **arguments)
50
+
51
+ expect(renderer).to have_received(:render)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Magicka::MethodBuilder do
6
+ subject(:builder) { described_class.new(klass) }
7
+
8
+ let(:klass) { Class.new }
9
+ let(:instance) { klass.new }
10
+
11
+ describe '#add_template' do
12
+ let(:template) { 'path_to_template' }
13
+
14
+ it do
15
+ expect { builder.add_template(template) }
16
+ .to add_method(:template)
17
+ .to(klass)
18
+ end
19
+
20
+ context 'when method is build as requested' do
21
+ before { builder.add_template(template) }
22
+
23
+ it 'returns the defined template when method is called' do
24
+ expect(instance.template).to eq(template)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -2,12 +2,10 @@
2
2
 
3
3
  require 'simplecov'
4
4
 
5
- SimpleCov.profiles.define 'gem' do
5
+ SimpleCov.start do
6
6
  add_filter '/spec/'
7
7
  end
8
8
 
9
- SimpleCov.start 'gem'
10
-
11
9
  require 'magicka'
12
10
  require 'pry-nav'
13
11
 
@@ -20,6 +18,7 @@ require File.expand_path('spec/dummy/config/environment')
20
18
  require File.expand_path('spec/dummy/db/schema.rb')
21
19
  require 'rspec/rails'
22
20
  require 'active_support/railtie'
21
+ require 'sinclair/matchers'
23
22
 
24
23
  support_files = File.expand_path('spec/support/**/*.rb')
25
24
  Dir[support_files].sort.each { |file| require file }
@@ -34,4 +33,5 @@ RSpec.configure do |config|
34
33
  config.filter_run_excluding :integration unless ENV['ALL']
35
34
 
36
35
  config.order = 'random'
36
+ config.include Sinclair::Matchers
37
37
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magicka
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DarthJee
@@ -397,6 +397,10 @@ files:
397
397
  - config/yardstick.yml
398
398
  - docker-compose.yml
399
399
  - lib/magicka.rb
400
+ - lib/magicka/element.rb
401
+ - lib/magicka/element/class_methods.rb
402
+ - lib/magicka/input.rb
403
+ - lib/magicka/method_builder.rb
400
404
  - lib/magicka/version.rb
401
405
  - magicka.gemspec
402
406
  - magicka.jpg
@@ -461,7 +465,10 @@ files:
461
465
  - spec/dummy/storage/.keep
462
466
  - spec/integration/readme/.keep
463
467
  - spec/integration/yard/.keep
464
- - spec/lib/magicka_spec.rb
468
+ - spec/lib/magicka/element/class_methods_spec.rb
469
+ - spec/lib/magicka/element_spec.rb
470
+ - spec/lib/magicka/input_spec.rb
471
+ - spec/lib/magicka/method_builder_spec.rb
465
472
  - spec/spec_helper.rb
466
473
  - spec/support/models/.keep
467
474
  - spec/support/shared_examples/.keep
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Magicka do
6
- it 'does something' do
7
- end
8
- end