magicka 1.1.0 → 1.2.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +6 -9
  3. data/.github/copilot-instructions.md +229 -0
  4. data/.github/magicka-usage.md +394 -0
  5. data/.github/sinclair-usage.md +492 -0
  6. data/.gitignore +1 -1
  7. data/.rubocop.yml +12 -2
  8. data/.rubocop_todo.yml +12 -0
  9. data/Dockerfile +2 -2
  10. data/Gemfile +33 -0
  11. data/Makefile +21 -0
  12. data/README.md +6 -7
  13. data/Rakefile +3 -0
  14. data/lib/magicka/aggregator/class_methods.rb +3 -1
  15. data/lib/magicka/aggregator.rb +3 -1
  16. data/lib/magicka/element/class_methods.rb +3 -3
  17. data/lib/magicka/form_element.rb +1 -1
  18. data/lib/magicka/version.rb +1 -1
  19. data/magicka.gemspec +3 -31
  20. data/magicka.jpg +0 -0
  21. data/spec/dummy/app/models/document.rb +1 -1
  22. data/spec/dummy/bin/setup +0 -4
  23. data/spec/dummy/bin/update +0 -4
  24. data/spec/dummy/config/environments/development.rb +1 -1
  25. data/spec/dummy/config/environments/production.rb +2 -2
  26. data/spec/dummy/config/puma.rb +3 -3
  27. data/spec/integration/yard/magicka/helper_spec.rb +1 -1
  28. data/spec/lib/magicka/aggregator/class_methods_spec.rb +1 -1
  29. data/spec/lib/magicka/aggregator_spec.rb +1 -1
  30. data/spec/lib/magicka/button_spec.rb +1 -1
  31. data/spec/lib/magicka/display_spec.rb +1 -1
  32. data/spec/lib/magicka/element/class_methods_spec.rb +1 -1
  33. data/spec/lib/magicka/element_spec.rb +1 -1
  34. data/spec/lib/magicka/form_element_spec.rb +1 -1
  35. data/spec/lib/magicka/form_spec.rb +1 -1
  36. data/spec/lib/magicka/input_spec.rb +1 -1
  37. data/spec/lib/magicka/select_spec.rb +1 -1
  38. data/spec/lib/magicka/text_spec.rb +1 -1
  39. data/spec/spec_helper.rb +7 -1
  40. metadata +12 -372
@@ -0,0 +1,492 @@
1
+ # Sinclair – Usage Guide for Dependent Projects
2
+
3
+ This document describes how to use the **sinclair** gem in your project.
4
+ Copy this file into your project's `.github/` directory so that GitHub Copilot
5
+ is aware of the patterns and conventions Sinclair provides.
6
+
7
+ **Current release**: 3.1.0
8
+ **Docs**: <https://www.rubydoc.info/gems/sinclair/3.1.0>
9
+
10
+ ---
11
+
12
+ ## Installation
13
+
14
+ Add to your `Gemfile`:
15
+
16
+ ```ruby
17
+ gem 'sinclair'
18
+ ```
19
+
20
+ then run:
21
+
22
+ ```bash
23
+ bundle install
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Features Overview
29
+
30
+ | Feature | Class / Module | Purpose |
31
+ |---|---|---|
32
+ | Method builder | `Sinclair` | Add instance/class methods dynamically |
33
+ | Configuration | `Sinclair::Configurable` + `Sinclair::Config` | Read-only config with defaults |
34
+ | Options | `Sinclair::Options` | Validated parameter objects |
35
+ | Env variables | `Sinclair::EnvSettable` | Read ENV vars via class methods |
36
+ | Equality | `Sinclair::Comparable` | Attribute-based `==` |
37
+ | Plain models | `Sinclair::Model` | Quick data-model classes |
38
+ | Type casting | `Sinclair::Caster` | Extensible type transformations |
39
+ | RSpec matchers | `Sinclair::Matchers` | Test method-builder behaviour |
40
+
41
+ ---
42
+
43
+ ## 1. Sinclair – Dynamic Method Builder
44
+
45
+ `Sinclair` lets you add instance and class methods to any class at runtime.
46
+ Methods are queued with `add_method` / `add_class_method` and created only
47
+ when `build` is called.
48
+
49
+ ### Stand-alone usage
50
+
51
+ ```ruby
52
+ class Clazz; end
53
+
54
+ builder = Sinclair.new(Clazz)
55
+ builder.add_method(:twenty, '10 + 10') # string-based
56
+ builder.add_method(:eighty) { 4 * twenty } # block-based
57
+ builder.add_class_method(:one_hundred) { 100 }
58
+ builder.build
59
+
60
+ instance = Clazz.new
61
+ instance.twenty # => 20
62
+ instance.eighty # => 80
63
+ Clazz.one_hundred # => 100
64
+ ```
65
+
66
+ ### Block DSL (`Sinclair.build`)
67
+
68
+ ```ruby
69
+ Sinclair.build(MyClass) do
70
+ add_method(:random_number) { Random.rand(10..20) }
71
+ add_class_method(:static_value) { 42 }
72
+ end
73
+ ```
74
+
75
+ ### String method with parameters
76
+
77
+ ```ruby
78
+ Sinclair.build(MyClass) do
79
+ add_class_method(
80
+ :power, 'a ** b + c',
81
+ parameters: [:a],
82
+ named_parameters: [:b, { c: 15 }]
83
+ )
84
+ end
85
+
86
+ MyClass.power(10, b: 2) # => 115
87
+ MyClass.power(10, b: 2, c: 0) # => 100
88
+ ```
89
+
90
+ ### Call-based method (delegates to the class itself)
91
+
92
+ ```ruby
93
+ builder = Sinclair.new(MyClass)
94
+ builder.add_class_method(:attr_accessor, :number, type: :call)
95
+ builder.build
96
+
97
+ MyClass.number # => nil
98
+ MyClass.number = 10
99
+ MyClass.number # => 10
100
+ ```
101
+
102
+ ### Caching results
103
+
104
+ ```ruby
105
+ builder.add_method(:expensive, cached: true) { slow_computation }
106
+ # equivalent to: @expensive ||= slow_computation
107
+
108
+ builder.add_method(:nullable, cached: :full) { may_return_nil }
109
+ # caches even nil / false values
110
+ ```
111
+
112
+ ### Extending the builder
113
+
114
+ Subclass `Sinclair` to create domain-specific builders:
115
+
116
+ ```ruby
117
+ class ValidationBuilder < Sinclair
118
+ delegate :expected, to: :options_object
119
+
120
+ def add_validation(field)
121
+ add_method("#{field}_valid?", "#{field}.is_a?(#{expected})")
122
+ end
123
+ end
124
+
125
+ module Validatable
126
+ extend ActiveSupport::Concern
127
+
128
+ class_methods do
129
+ def validate(*fields, expected_class)
130
+ builder = ValidationBuilder.new(self, expected: expected_class)
131
+ fields.each { |f| builder.add_validation(f) }
132
+ builder.build
133
+ end
134
+ end
135
+ end
136
+
137
+ class MyModel
138
+ include Validatable
139
+ validate :name, String
140
+ validate :age, Integer
141
+ end
142
+ ```
143
+
144
+ ---
145
+
146
+ ## 2. Sinclair::Configurable – Application Configuration
147
+
148
+ `Sinclair::Configurable` adds a read-only `config` object to any class or
149
+ module. Settings can only be changed through `configure`.
150
+
151
+ ### Inline attributes
152
+
153
+ ```ruby
154
+ module MyApp
155
+ extend Sinclair::Configurable
156
+
157
+ configurable_with :host, port: 80, debug: false
158
+ end
159
+
160
+ MyApp.configure(port: 5555) do |config|
161
+ config.host 'example.com'
162
+ end
163
+
164
+ MyApp.config.host # => 'example.com'
165
+ MyApp.config.port # => 5555
166
+
167
+ MyApp.reset_config
168
+ MyApp.config.host # => nil
169
+ MyApp.config.port # => 80
170
+
171
+ # Convert to Options object (useful for passing around)
172
+ MyApp.as_options(host: 'other').host # => 'other'
173
+ ```
174
+
175
+ ### Custom config class
176
+
177
+ ```ruby
178
+ class ServerConfig < Sinclair::Config
179
+ config_attributes :host, :port
180
+
181
+ def url
182
+ @port ? "http://#{@host}:#{@port}" : "http://#{@host}"
183
+ end
184
+ end
185
+
186
+ class Client
187
+ extend Sinclair::Configurable
188
+ configurable_by ServerConfig
189
+ end
190
+
191
+ Client.configure { host 'api.example.com' }
192
+ Client.config.url # => 'http://api.example.com'
193
+
194
+ Client.configure { port 8080 }
195
+ Client.config.url # => 'http://api.example.com:8080'
196
+ ```
197
+
198
+ ---
199
+
200
+ ## 3. Sinclair::Options – Validated Option Objects
201
+
202
+ `Sinclair::Options` creates structured option/parameter value objects with
203
+ defaults and validation against unknown keys.
204
+
205
+ ```ruby
206
+ class ConnectionOptions < Sinclair::Options
207
+ with_options :timeout, :retries, port: 443, protocol: 'https'
208
+ end
209
+
210
+ opts = ConnectionOptions.new(timeout: 30, protocol: 'http')
211
+ opts.timeout # => 30
212
+ opts.retries # => nil
213
+ opts.port # => 443 (default)
214
+ opts.protocol # => 'http'
215
+ opts.to_h # => { timeout: 30, retries: nil, port: 443, protocol: 'http' }
216
+
217
+ ConnectionOptions.new(unknown_key: 1)
218
+ # raises Sinclair::Exception::InvalidOptions
219
+ ```
220
+
221
+ Call `skip_validation` in the class body to allow unknown keys:
222
+
223
+ ```ruby
224
+ class LooseOptions < Sinclair::Options
225
+ with_options :name
226
+ skip_validation
227
+ end
228
+ ```
229
+
230
+ ---
231
+
232
+ ## 4. Sinclair::EnvSettable – Environment Variable Access
233
+
234
+ `EnvSettable` exposes environment variables as class-level methods, with
235
+ optional prefix and default values.
236
+
237
+ ```ruby
238
+ class ServiceClient
239
+ extend Sinclair::EnvSettable
240
+
241
+ settings_prefix 'SERVICE'
242
+ with_settings :username, :password, port: 80, hostname: 'my-host.com'
243
+ end
244
+
245
+ ENV['SERVICE_USERNAME'] = 'my-login'
246
+ ENV['SERVICE_HOSTNAME'] = 'host.com'
247
+
248
+ ServiceClient.username # => 'my-login'
249
+ ServiceClient.hostname # => 'host.com'
250
+ ServiceClient.port # => 80 (default – ENV var not set)
251
+ ServiceClient.password # => nil (ENV var not set, no default)
252
+ ```
253
+
254
+ ### Type casting
255
+
256
+ ```ruby
257
+ class AppConfig
258
+ extend Sinclair::EnvSettable
259
+
260
+ settings_prefix 'APP'
261
+ setting_with_options :timeout, type: :integer, default: 30
262
+ setting_with_options :debug, type: :boolean
263
+ setting_with_options :rate, type: :float
264
+ end
265
+
266
+ ENV['APP_TIMEOUT'] = '60'
267
+ AppConfig.timeout # => 60 (Integer)
268
+ ```
269
+
270
+ ---
271
+
272
+ ## 5. Sinclair::Comparable – Attribute-based Equality
273
+
274
+ Include `Sinclair::Comparable` and declare which attributes are used for `==`.
275
+
276
+ ```ruby
277
+ class Person
278
+ include Sinclair::Comparable
279
+
280
+ comparable_by :name
281
+ attr_reader :name, :age
282
+
283
+ def initialize(name:, age:)
284
+ @name = name
285
+ @age = age
286
+ end
287
+ end
288
+
289
+ p1 = Person.new(name: 'Alice', age: 30)
290
+ p2 = Person.new(name: 'Alice', age: 25)
291
+
292
+ p1 == p2 # => true (only :name is compared)
293
+ ```
294
+
295
+ ---
296
+
297
+ ## 6. Sinclair::Model – Quick Plain-Ruby Models
298
+
299
+ `Sinclair::Model` generates reader/writer methods, a keyword-argument
300
+ initializer, and equality (via `Sinclair::Comparable`) in one call.
301
+
302
+ There are two ways to define a model:
303
+
304
+ - **`initialize_with`** – called inside the class body; adds methods to the current class.
305
+ - **`.for`** – class method that returns a new anonymous subclass; useful when inheriting inline.
306
+
307
+ ### Basic model (initialize_with)
308
+
309
+ ```ruby
310
+ class Human < Sinclair::Model
311
+ initialize_with :name, :age, { gender: :undefined }, **{}
312
+ end
313
+
314
+ h1 = Human.new(name: 'John', age: 22)
315
+ h2 = Human.new(name: 'John', age: 22)
316
+
317
+ h1.name # => 'John'
318
+ h1.gender # => :undefined
319
+ h1 == h2 # => true
320
+
321
+ h1.name = 'Jane' # setter generated by default
322
+ ```
323
+
324
+ ### Disabling writers or equality (initialize_with)
325
+
326
+ ```ruby
327
+ class Tv < Sinclair::Model
328
+ initialize_with :brand, :model, writter: false, comparable: false
329
+ end
330
+
331
+ tv1 = Tv.new(brand: 'Sony', model: 'X90L')
332
+ tv2 = Tv.new(brand: 'Sony', model: 'X90L')
333
+
334
+ tv1 == tv2 # => false (comparable disabled)
335
+ ```
336
+
337
+ ### Using .for (inline subclassing)
338
+
339
+ ```ruby
340
+ class Car < Sinclair::Model.for(:brand, :model, writter: false)
341
+ end
342
+
343
+ car = Car.new(brand: :ford, model: :T)
344
+
345
+ car.brand # => :ford
346
+ car.model # => :T
347
+ ```
348
+
349
+ ### Using .for with default values
350
+
351
+ ```ruby
352
+ class Job < Sinclair::Model.for({ state: :starting }, writter: true)
353
+ end
354
+
355
+ job = Job.new
356
+
357
+ job.state # => :starting
358
+ job.state = :done
359
+ job.state # => :done
360
+ ```
361
+
362
+ Options accepted by both `initialize_with` and `.for`:
363
+
364
+ | Option | Default | Description |
365
+ |---|---|---|
366
+ | `writter:` | `true` | Generate setter methods |
367
+ | `comparable:` | `true` | Include field in `==` comparison |
368
+
369
+ ---
370
+
371
+ ## 7. Sinclair::Caster – Type Casting
372
+
373
+ `Sinclair::Caster` provides a registry of named type casters.
374
+
375
+ ```ruby
376
+ class MyCaster < Sinclair::Caster
377
+ cast_with(:upcase, :upcase)
378
+ cast_with(:log) { |value, base: 10| Math.log(value.to_f, base) }
379
+ end
380
+
381
+ MyCaster.cast('hello', :upcase) # => 'HELLO'
382
+ MyCaster.cast(100, :log) # => 2.0
383
+ MyCaster.cast(16, :log, base: 2) # => 4.0
384
+ ```
385
+
386
+ ### Class-based casting
387
+
388
+ ```ruby
389
+ class TypeCaster < Sinclair::Caster
390
+ master_caster!
391
+
392
+ cast_with(Integer, :to_i)
393
+ cast_with(Float, :to_f)
394
+ cast_with(String, :to_s)
395
+ end
396
+
397
+ TypeCaster.cast('42', Integer) # => 42
398
+ TypeCaster.cast(3, Float) # => 3.0
399
+ ```
400
+
401
+ ---
402
+
403
+ ## 8. Sinclair::Matchers – RSpec Matchers
404
+
405
+ Include `Sinclair::Matchers` in your RSpec configuration to gain matchers for
406
+ testing that a builder adds or changes methods.
407
+
408
+ ### Setup
409
+
410
+ ```ruby
411
+ # spec/spec_helper.rb
412
+ RSpec.configure do |config|
413
+ config.include Sinclair::Matchers
414
+ end
415
+ ```
416
+
417
+ ### Available matchers
418
+
419
+ ```ruby
420
+ # Checks that build adds an instance method
421
+ expect { builder.build }.to add_method(:name).to(instance)
422
+ expect { builder.build }.to add_method(:name).to(klass)
423
+
424
+ # Checks that build adds a class method
425
+ expect { builder.build }.to add_class_method(:count).to(klass)
426
+
427
+ # Checks that build changes an existing instance method
428
+ expect { builder.build }.to change_method(:value).on(instance)
429
+
430
+ # Checks that build changes an existing class method
431
+ expect { builder.build }.to change_class_method(:count).on(klass)
432
+ ```
433
+
434
+ ### Example spec
435
+
436
+ ```ruby
437
+ RSpec.describe MyBuilder do
438
+ let(:klass) { Class.new }
439
+ let(:instance) { klass.new }
440
+ let(:builder) { MyBuilder.new(klass) }
441
+
442
+ it 'adds a greeting method to instances' do
443
+ expect { builder.build }.to add_method(:greet).to(instance)
444
+ end
445
+
446
+ it 'adds a factory class method' do
447
+ expect { builder.build }.to add_class_method(:create).to(klass)
448
+ end
449
+ end
450
+ ```
451
+
452
+ ---
453
+
454
+ ## Complete Example
455
+
456
+ ```ruby
457
+ # Combining multiple Sinclair features in one class
458
+
459
+ class ApiClient
460
+ extend Sinclair::Configurable
461
+ extend Sinclair::EnvSettable
462
+ include Sinclair::Comparable
463
+
464
+ # --- Configuration (set programmatically) ---
465
+ configurable_with :timeout, retries: 3
466
+
467
+ # --- Environment variables ---
468
+ settings_prefix 'API'
469
+ with_settings :api_key, :secret, base_url: 'https://api.example.com'
470
+
471
+ # --- Equality based on base_url ---
472
+ comparable_by :base_url
473
+
474
+ attr_reader :base_url
475
+
476
+ def initialize(base_url: self.class.base_url)
477
+ @base_url = base_url
478
+ end
479
+ end
480
+
481
+ # Wire up at boot time
482
+ ENV['API_API_KEY'] = 'secret-key'
483
+ ApiClient.configure(timeout: 60)
484
+
485
+ client1 = ApiClient.new
486
+ client2 = ApiClient.new
487
+
488
+ client1 == client2 # => true
489
+ ApiClient.config.timeout # => 60
490
+ ApiClient.config.retries # => 3
491
+ ApiClient.api_key # => 'secret-key'
492
+ ```
data/.gitignore CHANGED
@@ -9,4 +9,4 @@ measurement/
9
9
  rubycritic/
10
10
  spec/dummy/log/*
11
11
  spec/dummy/tmp/*
12
- spec/dummy/db/*.sqlite3
12
+ spec/dummy/db/*
data/.rubocop.yml CHANGED
@@ -1,8 +1,15 @@
1
- require: rubocop-rspec
1
+ plugins:
2
+ - rubocop-rspec
3
+ - rubocop-factory_bot
4
+ - rubocop-rails
5
+ - rubocop-rake
6
+ - rubocop-rspec_rails
7
+
2
8
  inherit_from: .rubocop_todo.yml
3
9
 
4
10
  AllCops:
5
- TargetRubyVersion: 2.7
11
+ TargetRubyVersion: 3.3
12
+ NewCops: enable
6
13
 
7
14
  Layout/LineLength:
8
15
  Max: 90
@@ -51,3 +58,6 @@ Style/HashTransformValues:
51
58
  RSpec/DescribeClass:
52
59
  Exclude:
53
60
  - 'spec/integration/**/*_spec.rb'
61
+
62
+ Gemspec/RequireMFA:
63
+ Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -0,0 +1,12 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2026-03-10 17:40:58 UTC using RuboCop version 1.85.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 65
10
+ # Configuration parameters: AllowSubject.
11
+ RSpec/MultipleMemoizedHelpers:
12
+ Max: 10
data/Dockerfile CHANGED
@@ -1,6 +1,6 @@
1
- FROM darthjee/scripts:0.3.1 as scripts
1
+ FROM darthjee/scripts:0.6.0 as scripts
2
2
 
3
- FROM darthjee/rails_gems:1.2.0 as base
3
+ FROM darthjee/rails_gems:2.1.0 as base
4
4
 
5
5
  COPY --chown=app:app ./ /home/app/app/
6
6
 
data/Gemfile CHANGED
@@ -3,3 +3,36 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
+
7
+ gem 'activerecord', '7.2.2.1'
8
+ gem 'bundler', '>= 2.5.13'
9
+ gem 'factory_bot', '6.5.6'
10
+ gem 'nokogiri', '1.19.1'
11
+ gem 'pry', '0.14.2'
12
+ gem 'pry-nav', '1.0.0'
13
+ gem 'rails', '7.2.2.1'
14
+ gem 'rails-controller-testing', '1.0.5'
15
+ gem 'rake', '13.2.1'
16
+ gem 'reek', '6.5.0'
17
+ gem 'rspec', '3.13.2'
18
+ gem 'rspec-core', '3.13.6'
19
+ gem 'rspec-expectations', '3.13.5'
20
+ gem 'rspec-mocks', '3.13.8'
21
+ gem 'rspec-rails', '8.0.3'
22
+ gem 'rspec-support', '3.13.7'
23
+ gem 'rubocop', '1.85.1'
24
+ gem 'rubocop-factory_bot', '2.28.0'
25
+ gem 'rubocop-rails', '2.34.3'
26
+ gem 'rubocop-rake', '0.7.1'
27
+ gem 'rubocop-rspec', '3.9.0'
28
+ gem 'rubocop-rspec_rails', '2.32.0'
29
+ gem 'rubycritic', '5.0.0'
30
+ gem 'shoulda-matchers', '6.5.0'
31
+ gem 'simplecov', '0.22.0'
32
+ gem 'simplecov-html', '0.13.2'
33
+ gem 'simplecov-lcov', '0.9.0'
34
+ gem 'sprockets-rails', '3.5.2'
35
+ gem 'sqlite3', '1.4.2'
36
+ gem 'tzinfo-data', '1.2026.1'
37
+ gem 'yard', '0.9.38'
38
+ gem 'yardstick', '0.9.9'
data/Makefile ADDED
@@ -0,0 +1,21 @@
1
+ .PHONY: build dev tests
2
+
3
+ PROJECT?=magicka
4
+ IMAGE?=$(PROJECT)
5
+ BASE_IMAGE?=$(DOCKER_ID_USER)/$(PROJECT)-base
6
+ DOCKER_FILE_BASE=Dockerfile.$(PROJECT)-base
7
+
8
+ all:
9
+ @echo "Usage:"
10
+ @echo " make build\n Build docker image for $(PROJECT)"
11
+ @echo " make dev\n Run development environment for $(PROJECT)"
12
+ @echo " make tests\n Run tests for $(PROJECT)"
13
+
14
+ build:
15
+ docker build -f Dockerfile.$(PROJECT) . -t $(IMAGE) -t $(PUSH_IMAGE):latest
16
+
17
+ tests:
18
+ docker-compose run $(PROJECT)_tests /bin/bash
19
+
20
+ dev:
21
+ docker-compose run $(PROJECT) /bin/bash
data/README.md CHANGED
@@ -1,10 +1,9 @@
1
1
  Magicka
2
2
  ====
3
- [![Code Climate](https://codeclimate.com/github/darthjee/magicka/badges/gpa.svg)](https://codeclimate.com/github/darthjee/magicka)
4
- [![Test Coverage](https://codeclimate.com/github/darthjee/magicka/badges/coverage.svg)](https://codeclimate.com/github/darthjee/magicka/coverage)
5
- [![Issue Count](https://codeclimate.com/github/darthjee/magicka/badges/issue_count.svg)](https://codeclimate.com/github/darthjee/magicka)
3
+ [![CircleCI](https://dl.circleci.com/status-badge/img/gh/darthjee/magicka/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/darthjee/magicka/tree/main)
4
+ [![Codacy Badge](https://app.codacy.com/project/badge/Grade/f0d549e6d2ed47c5b1c5451bcb250ff2)](https://app.codacy.com/gh/darthjee/magicka/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
5
+ [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/f0d549e6d2ed47c5b1c5451bcb250ff2)](https://app.codacy.com/gh/darthjee/magicka/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage)
6
6
  [![Gem Version](https://badge.fury.io/rb/magicka.svg)](https://badge.fury.io/rb/magicka)
7
- [![Codacy Badge](https://api.codacy.com/project/badge/Grade/9836de08612e46b889c7978be2b72a14)](https://www.codacy.com/manual/darthjee/magicka?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=darthjee/magicka&amp;utm_campaign=Badge_Grade)
8
7
  [![Inline docs](http://inch-ci.org/github/darthjee/magicka.svg?branch=master)](http://inch-ci.org/github/darthjee/magicka)
9
8
 
10
9
  ![magicka](https://raw.githubusercontent.com/darthjee/magicka/master/magicka.jpg)
@@ -12,13 +11,13 @@ Magicka
12
11
  Magica helps creating html templates for forms and display data using js applications
13
12
  such as AngulaJS
14
13
 
15
- Current Release: [1.1.0](https://github.com/darthjee/magicka/tree/1.1.0)
14
+ **Current Release**: [1.2.0](https://github.com/darthjee/magicka/tree/1.2.0)
16
15
 
17
- [Next release](https://github.com/darthjee/magicka/compare/1.1.0...master)
16
+ **Next release**: [1.3.0](https://github.com/darthjee/magicka/compare/1.2.0...master)
18
17
 
19
18
  Yard Documentation
20
19
  -------------------
21
- [https://www.rubydoc.info/gems/magicka/1.1.0](https://www.rubydoc.info/gems/magicka/1.1.0)
20
+ [https://www.rubydoc.info/gems/magicka/1.2.0](https://www.rubydoc.info/gems/magicka/1.2.0)
22
21
 
23
22
  Installation
24
23
  ---------------
data/Rakefile CHANGED
@@ -8,5 +8,8 @@ require './config/rubycritc'
8
8
 
9
9
  RSpec::Core::RakeTask.new
10
10
 
11
+ desc 'run rspec'
11
12
  task default: :spec
13
+
14
+ desc 'run rspec'
12
15
  task test: :spec
@@ -36,7 +36,9 @@ module Magicka
36
36
  #
37
37
  # @return [Symbol]
38
38
  def default_type
39
- name&.demodulize&.underscore&.to_sym
39
+ return unless name
40
+
41
+ name.demodulize.underscore.to_sym
40
42
  end
41
43
  end
42
44
  end
@@ -11,6 +11,7 @@ module Magicka
11
11
  extend Aggregator::ClassMethods
12
12
 
13
13
  attr_reader :model
14
+
14
15
  # @method model
15
16
  # @api public
16
17
  #
@@ -95,7 +96,7 @@ module Magicka
95
96
  #
96
97
  # @return [TrueClass,FalseClass]
97
98
  def equal?(other)
98
- return unless other.class == self.class
99
+ return false unless other.class == self.class
99
100
 
100
101
  other.renderer == renderer &&
101
102
  other.model == model
@@ -106,6 +107,7 @@ module Magicka
106
107
  protected
107
108
 
108
109
  attr_reader :renderer
110
+
109
111
  # @method renderer
110
112
  # @private
111
113
  # @api private
@@ -63,9 +63,9 @@ module Magicka
63
63
  # Adds attribute and locals
64
64
  #
65
65
  # @return [Array]
66
- def with_attribute_locals(*args)
67
- with_locals(*args)
68
- with_attributes(*args)
66
+ def with_attribute_locals(*)
67
+ with_locals(*)
68
+ with_attributes(*)
69
69
  end
70
70
  end
71
71
  end