magicka 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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