enumbler 0.8.0 → 0.9.2

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: a3b8d2a2e38789cb62f2be5c895aa0fb2776b26b8efbbfe3386e88feaf041393
4
- data.tar.gz: d981a2476760ab1d0afb09bd2eb790c125cf54ba54cad3493a5865f52163648b
3
+ metadata.gz: ca8de5b8e3b88d4321e0df6108f41245142f95489930e57e6d0209c260335b3d
4
+ data.tar.gz: ab12a41dc3564dd62f78cb0583ec12ac6602ba5faf6bf890be80864096f4a65d
5
5
  SHA512:
6
- metadata.gz: 65c1b774b7fd7fe86e3038c5bfea649608708e57ef626529c933e82e31249a43716b50e54d2a822640d11d6b98321832f032dfedf2efce9a750aebc1e25fd26c
7
- data.tar.gz: c223ff2703dd5693ee9925dd4ffc025c890138962001acca6619f8c1d30b7e6056a5275fa84f5c159f163c052b8fbc546c1f9132917b93a96956c6aba9d1e72e
6
+ metadata.gz: 948e3cab58f8065ad78b67680ecc9ca0f3de53be0169ca13502a69f145af27e855707b331cf760e925859789f26f68a801ee7f6c02562d393ca6a720c30497fd
7
+ data.tar.gz: c50f6dc4282fa0ace1cdc44b97dd79f64f6a1667074bd4fe93f5ed580decfa55983b412317d3c3a4f18f83efa1ef83c16fad75177f0e575ccf0ba005f6275cf1
data/.rubocop.yml CHANGED
@@ -1,7 +1,6 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.6
3
- Exclude:
4
- - 'bin/pre_commit_rubocop.rb'
2
+ NewCops: enable
3
+ TargetRubyVersion: 2.5
5
4
 
6
5
  Layout/ArgumentAlignment:
7
6
  Enabled: true
@@ -11,16 +10,36 @@ Layout/FirstHashElementIndentation:
11
10
  Enabled: true
12
11
  EnforcedStyle: consistent
13
12
 
13
+ Layout/HashAlignment:
14
+ Enabled: true
15
+ # This allows "implicit" hash arguments (without curly braces) to be aligned
16
+ # differently.
17
+ EnforcedLastArgumentHashStyle: ignore_implicit
18
+
14
19
  Layout/LineLength:
15
20
  AllowURI: true
16
21
  Max: 119
17
22
 
23
+ Layout/MultilineMethodCallIndentation:
24
+ Enabled: true
25
+ EnforcedStyle: indented
26
+
18
27
  Lint/RaiseException:
19
28
  Enabled: true
20
29
 
21
30
  Lint/StructNewOverride:
22
31
  Enabled: true
23
32
 
33
+ Metrics:
34
+ Enabled: false
35
+
36
+ Naming/MethodParameterName:
37
+ Enabled: true
38
+ AllowedNames: [at, by, db, id, in, ip, of, on, to, tz]
39
+
40
+ Naming/PredicateName:
41
+ Enabled: true
42
+
24
43
  Style/Documentation:
25
44
  Enabled: false
26
45
 
@@ -33,6 +52,9 @@ Style/HashTransformKeys:
33
52
  Style/HashTransformValues:
34
53
  Enabled: true
35
54
 
55
+ Style/StringLiterals:
56
+ EnforcedStyle: double_quotes
57
+
36
58
  Style/TrailingCommaInHashLiteral:
37
59
  Enabled: true
38
60
  EnforcedStyleForMultiline: consistent_comma
@@ -41,5 +63,5 @@ Style/TrailingCommaInArrayLiteral:
41
63
  Enabled: true
42
64
  EnforcedStyleForMultiline: consistent_comma
43
65
 
44
- Metrics:
45
- Enabled: false
66
+ Style/TrailingCommaInArguments:
67
+ EnforcedStyleForMultiline: consistent_comma
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source 'https://rubygems.org'
3
+ source "https://rubygems.org"
4
4
 
5
5
  # Specify your gem's dependencies in enumbler.gemspec
6
6
  gemspec
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- enumbler (0.8.0)
5
- activerecord (>= 5.2.3, < 6.1)
6
- activesupport (>= 5.2.3, < 6.1)
4
+ enumbler (0.9.1)
5
+ activerecord (>= 5.2.3, < 7)
6
+ activesupport (>= 5.2.3, < 7)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -170,14 +170,12 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
170
170
 
171
171
  ## Roadmap
172
172
 
173
- * We need to add in support for additional attributes/columns in the enumbled table. For example, following the `Color` concept, we may want to have a column which is `hex` and stores the colors `hex` value (e.g., `FFFFFF`). This should be supported.
174
- * Ideally, we could make this work more like a traditional `enum`; for example, overriding the `.where` method by allowing something like: `House.where(color: :blue)` instead of `House.where_color(:blue)`. But right now am in a rush and not sure how to go about doing that properly.
173
+ * Ideally, we could make this work more like a traditional `enum`; for example, overriding the `.where` method by allowing something like: `House.where(color: :blue)` instead of `House.color(:blue)`. But right now am in a rush and not sure how to go about doing that properly.
175
174
 
176
175
  ## Contributing
177
176
 
178
177
  Bug reports and pull requests are welcome on GitHub at https://github.com/linguabee/enumbler.
179
178
 
180
-
181
179
  ## License
182
180
 
183
181
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
data/bin/console CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'bundler/setup'
5
- require 'enumbler'
4
+ require "bundler/setup"
5
+ require "enumbler"
6
6
 
7
7
  # You can add fixtures and/or initialization code here to make experimenting
8
8
  # with your gem easier. You can also use a different console, if you like.
@@ -11,5 +11,5 @@ require 'enumbler'
11
11
  # require "pry"
12
12
  # Pry.start
13
13
 
14
- require 'irb'
14
+ require "irb"
15
15
  IRB.start(__FILE__)
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  # Put this file into your path and use `<file> install` to add a new hook
3
5
  # or use it as a binary to check changed files
4
6
 
5
- require 'shellwords'
7
+ require "shellwords"
6
8
 
7
9
  if ARGV == ["install"]
8
10
  exec "ln", "-sf", File.expand_path(File.basename(__FILE__), __dir__), ".git/hooks/pre-commit"
@@ -10,15 +12,23 @@ else
10
12
  raise unless ARGV == []
11
13
  end
12
14
 
13
- changed = `git status --porcelain`.
14
- split("\n").
15
- map { |l| l.split(" ", 2) }.
16
- select { |status, _| ["A", "AM", "M"].include?(status) }.
17
- map { |_, file| file.delete('"') }
15
+ changed = `git status --porcelain`
16
+ .split("\n")
17
+ .map { |l| l.split(" ", 2) }
18
+ .select { |status, _| %w[A AM M].include?(status) }
19
+ .map { |_, file| file.delete('"') }
18
20
 
19
21
  exit if changed.empty?
20
22
 
21
- parallel = ((File.read(".rubocop.yml").include?("UseCache: false") rescue false) ? "" : " --parallel")
23
+ parallel = (if begin
24
+ File.read(".rubocop.yml").include?("UseCache: false")
25
+ rescue StandardError
26
+ false
27
+ end
28
+ ""
29
+ else
30
+ " --parallel"
31
+ end)
22
32
  result = `bundle exec rubocop #{parallel} --color --force-exclusion #{changed.shelljoin}`
23
- puts result unless $?.success?
24
- exit $?.exitstatus
33
+ puts result unless $CHILD_STATUS.success?
34
+ exit $CHILD_STATUS.exitstatus
data/enumbler.gemspec CHANGED
@@ -1,42 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'lib/enumbler/version'
3
+ require_relative "lib/enumbler/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = 'enumbler'
6
+ spec.name = "enumbler"
7
7
  spec.version = Enumbler::VERSION
8
- spec.authors = ['Damon Timm']
9
- spec.email = ['damon@linguabee.com']
8
+ spec.authors = ["Damon Timm"]
9
+ spec.email = ["damon@linguabee.com"]
10
10
 
11
11
  spec.summary = "Enums are terrific, but lack integrity. Let's add some!"
12
- spec.description = 'A more complete description is forthcoming.'
13
- spec.homepage = 'https://github.com/linguabee/enumbler'
14
- spec.license = 'MIT'
15
- spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
12
+ spec.description = "A more complete description is forthcoming."
13
+ spec.homepage = "https://github.com/linguabee/enumbler"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
16
16
 
17
- spec.metadata['allowed_push_host'] = 'https://rubygems.org'
17
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
18
 
19
- spec.metadata['homepage_uri'] = spec.homepage
20
- spec.metadata['source_code_uri'] = spec.homepage
21
- spec.metadata['changelog_uri'] = spec.homepage
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ spec.metadata["source_code_uri"] = spec.homepage
21
+ spec.metadata["changelog_uri"] = spec.homepage
22
22
 
23
23
  # Specify which files should be added to the gem when it is released.
24
24
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
25
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
26
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
27
  end
28
- spec.bindir = 'exe'
28
+ spec.bindir = "exe"
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
- spec.require_paths = ['lib']
31
-
32
- spec.add_dependency 'activerecord', ['>= 5.2.3', '< 6.1']
33
- spec.add_dependency 'activesupport', ['>= 5.2.3', '< 6.1']
34
-
35
- spec.add_development_dependency 'database_cleaner-active_record', '~> 1.8.0'
36
- spec.add_development_dependency 'fuubar', '~> 2.5'
37
- spec.add_development_dependency 'pry'
38
- spec.add_development_dependency 'rake', '~> 12.0'
39
- spec.add_development_dependency 'rspec', '~> 3.9.0'
40
- spec.add_development_dependency 'rubocop', '~> 0.91.0'
41
- spec.add_development_dependency 'sqlite3', '~> 1.4.0'
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_dependency "activerecord", [">= 5.2.3", "< 7"]
33
+ spec.add_dependency "activesupport", [">= 5.2.3", "< 7"]
34
+
35
+ spec.add_development_dependency "database_cleaner-active_record", "~> 1.8.0"
36
+ spec.add_development_dependency "fuubar", "~> 2.5"
37
+ spec.add_development_dependency "pry"
38
+ spec.add_development_dependency "rake", "~> 12.0"
39
+ spec.add_development_dependency "rspec", "~> 3.9.0"
40
+ spec.add_development_dependency "rubocop", "~> 0.91.0"
41
+ spec.add_development_dependency "sqlite3", "~> 1.4.0"
42
42
  end
data/lefthook.yml ADDED
@@ -0,0 +1,12 @@
1
+ # EXAMPLE USAGE
2
+ # Refer for explanation to following link:
3
+ # https://github.com/Arkweid/lefthook/blob/master/docs/full_guide.md
4
+
5
+ pre-commit:
6
+ parallel: true
7
+ commands:
8
+ rubocop:
9
+ tags: backend style
10
+ glob: "*.rb"
11
+ exclude: "application.rb|routes.rb"
12
+ run: bundle exec rubocop --force-exclusion {all_files}
data/lib/enumbler.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'enumbler/core_ext/symbol/case_equality_operator'
3
+ require "enumbler/core_ext/symbol/case_equality_operator"
4
4
 
5
- require 'enumbler/collection'
6
- require 'enumbler/enumble'
7
- require 'enumbler/enabler'
8
- require 'enumbler/version'
5
+ require "enumbler/collection"
6
+ require "enumbler/enumble"
7
+ require "enumbler/enabler"
8
+ require "enumbler/version"
9
9
 
10
- require 'active_support/concern'
11
- require 'active_support/inflector'
10
+ require "active_support/concern"
11
+ require "active_support/inflector"
12
12
 
13
13
  # The Enumbler add integrity to our enum implementation!
14
14
  module Enumbler
@@ -16,7 +16,7 @@ module Enumbler
16
16
  super
17
17
  end
18
18
 
19
- def respond_to_missing?(method_name, include_private = false)
19
+ def respond_to_missing?(method_name, *args, &block)
20
20
  enumble = find { |e| e.enum == method_name }
21
21
  enumble.present? || super
22
22
  end
@@ -12,7 +12,7 @@ module Enumbler
12
12
  def enumble
13
13
  @enumble = self.class.find_enumble(id)
14
14
 
15
- raise Error, 'An enumble is not defined for this record!' if @enumble.nil?
15
+ raise Error, "An enumble is not defined for this record!" if @enumble.nil?
16
16
 
17
17
  @enumble
18
18
  end
@@ -227,6 +227,8 @@ module Enumbler
227
227
  enumble =
228
228
  if arg.is_a?(Symbol)
229
229
  @enumbled_model.enumbles.find { |e| e.enum == arg }
230
+ elsif arg.is_a?(Enumbler::Enumble)
231
+ @enumbled_model.enumbles.find { |e| e.enum == arg.enum }
230
232
  elsif arg.is_a?(String)
231
233
  @enumbled_model.enumbles.find do |e|
232
234
  if case_sensitive
@@ -330,7 +332,7 @@ module Enumbler
330
332
  # longer defined (default: false)
331
333
  # @param validate [Boolean] validate on save?
332
334
  def seed_the_enumbler(delete_missing_records: false, validate: true)
333
- max_database_id = all.order('id desc').take&.id || 0
335
+ max_database_id = all.order("id desc").take&.id || 0
334
336
  max_enumble_id = @enumbles.map(&:id).max
335
337
 
336
338
  # If we are not deleting records, we just need to update each listed
@@ -375,11 +377,21 @@ module Enumbler
375
377
  method_name = "#{enumble.enum}?"
376
378
  not_method_name = "not_#{enumble.enum}?"
377
379
  alias_method_name = "is_#{enumble.enum}"
380
+ any_method_name = "any_#{enumble.enum}?"
381
+
382
+ [method_name, not_method_name, alias_method_name].each do |mname|
383
+ detect_enumbler_conflict(enumble.enum, mname)
384
+ end
385
+
386
+ [enumble.enum, any_method_name].each do |mname|
387
+ detect_enumbler_conflict(enumble.enum, mname, klass_method: true)
388
+ end
378
389
 
379
390
  const_set(enumble.enum.to_s.upcase, enumble.id)
380
391
  define_method(method_name) { id == enumble.id }
381
392
  define_method(not_method_name) { id != enumble.id }
382
393
  alias_method alias_method_name, method_name
394
+
383
395
  define_singleton_method(enumble.enum) do |attr = nil|
384
396
  return find(enumble.id) if attr.nil?
385
397
 
@@ -388,13 +400,42 @@ module Enumbler
388
400
  raise Enumbler::Error, "The attribute #{attr} is not supported on this Enumble."
389
401
  end
390
402
 
391
- define_singleton_method("any_#{enumble.enum}?") do
392
- where(id: enumble.id).exists?
403
+ define_singleton_method(any_method_name) do
404
+ exists?(id: enumble.id)
393
405
  rescue NoMethodError
394
406
  raise Enumbler::Error, "The attribute #{attr} is not supported on this Enumble."
395
407
  end
396
408
  end
397
409
 
410
+ # This idea sourced lovingly from ActiveRecord::Enum
411
+ ENUMBLER_CONFLICT_MESSAGE = <<~TEXT.squish
412
+ You tried to define the enumble :%<enum>s on the model %<klass>s, but
413
+ this will generate a %<type>s method `%<method>s`, which is already defined
414
+ by %<source>s.
415
+ TEXT
416
+
417
+ def detect_enumbler_conflict(enumble_name, method_name, klass_method: false)
418
+ if klass_method && dangerous_class_method?(method_name)
419
+ raise_conflict_error(enumble_name, method_name, type: "class")
420
+ elsif klass_method && method_defined_within?(method_name, ActiveRecord::Relation)
421
+ raise_conflict_error(enumble_name, method_name, type: "class", source: ActiveRecord::Relation.name)
422
+ elsif !klass_method && dangerous_attribute_method?(method_name)
423
+ raise_conflict_error(enumble_name, method_name)
424
+ end
425
+ end
426
+
427
+ def raise_conflict_error(enumble_name, method_name, type: "instance", source: "ActiveRecord")
428
+ raise Error,
429
+ format(
430
+ ENUMBLER_CONFLICT_MESSAGE,
431
+ enum: enumble_name,
432
+ klass: name,
433
+ type: type,
434
+ method: method_name,
435
+ source: source,
436
+ )
437
+ end
438
+
398
439
  # I accidentally forgot to provide an id one time and it was confusing as
399
440
  # the last argument became the hash of options. This should help.
400
441
  def validate_id_is_numeric(enum, id)
@@ -411,11 +452,17 @@ module Enumbler
411
452
 
412
453
  return if unsupported_attrs.blank?
413
454
 
455
+ ActiveRecord::Migration.check_pending!
456
+
414
457
  raise Enumbler::Error,
415
458
  "The model #{self} does not support the attribute(s): #{unsupported_attrs.keys.map(&:to_s).to_sentence}"
459
+ rescue ActiveRecord::PendingMigrationError
460
+ warn "[Enumbler Warning] => The model #{self} does not currently support the attribute(s): #{unsupported_attrs.keys.map(&:to_s).to_sentence}." \
461
+ " You have a pending migration which hopefully would remedy this! If not, you need to add a migration for this attibrute or" \
462
+ " remove it from the Enumbler."
416
463
  rescue ActiveRecord::StatementInvalid
417
464
  warn "[Enumbler Warning] => Unable to find a table for #{self}."\
418
- 'This is to be expected if there is a pending migration; however, if there is not then something is amiss.'
465
+ "This is to be expected if there is a pending migration; however, if there is not then something is amiss."
419
466
  end
420
467
  end
421
468
  end
@@ -11,7 +11,7 @@ module Enumbler
11
11
  @label_column_name = label_column_name
12
12
  @label = (label_col_specified? ? attributes[label_column_name] : label) || enum.to_s.dasherize
13
13
  @additional_attributes = attributes || {}
14
- @additional_attributes.merge!({ label: label }) if label_col_specified?
14
+ @additional_attributes.merge!({ label: label }) unless label.nil?
15
15
  end
16
16
 
17
17
  def ==(other)
@@ -21,7 +21,6 @@ module Enumbler
21
21
 
22
22
  def attributes
23
23
  hash = { id: id, label_column_name => label }
24
- hash.merge!({ label: @additional_attributes[:label] }) if label_col_specified?
25
24
  @additional_attributes.merge(hash)
26
25
  end
27
26
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Enumbler
4
- VERSION = '0.8.0'
4
+ VERSION = "0.9.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enumbler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damon Timm
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-26 00:00:00.000000000 Z
11
+ date: 2021-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: 5.2.3
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6.1'
22
+ version: '7'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: 5.2.3
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6.1'
32
+ version: '7'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: activesupport
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +39,7 @@ dependencies:
39
39
  version: 5.2.3
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: '6.1'
42
+ version: '7'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -49,7 +49,7 @@ dependencies:
49
49
  version: 5.2.3
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
- version: '6.1'
52
+ version: '7'
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: database_cleaner-active_record
55
55
  requirement: !ruby/object:Gem::Requirement
@@ -169,6 +169,7 @@ files:
169
169
  - bin/pre_commit_rubocop.rb
170
170
  - bin/setup
171
171
  - enumbler.gemspec
172
+ - lefthook.yml
172
173
  - lib/enumbler.rb
173
174
  - lib/enumbler/collection.rb
174
175
  - lib/enumbler/core_ext/symbol/case_equality_operator.rb
@@ -198,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
199
  - !ruby/object:Gem::Version
199
200
  version: '0'
200
201
  requirements: []
201
- rubygems_version: 3.1.2
202
+ rubygems_version: 3.1.6
202
203
  signing_key:
203
204
  specification_version: 4
204
205
  summary: Enums are terrific, but lack integrity. Let's add some!