Skip to content

Commit

Permalink
Merge pull request #321 from hatsu38/issue-319
Browse files Browse the repository at this point in the history
Implement automatic predicate method generation for ActiveHash::Enum
  • Loading branch information
kbrock authored Sep 5, 2024
2 parents a192385 + 2173c30 commit 0b3701c
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
14 changes: 14 additions & 0 deletions lib/enum/enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ def enum_accessor(*field_names)
reload
end

def enum(columns)
columns.each do |column, values|
values = values.zip(values.map(&:to_s)).to_h if values.is_a?(Array)
values.each do |method, value|
class_eval <<~METHOD, __FILE__, __LINE__ + 1
# frozen_string_literal: true
def #{method}?
#{column} == #{value.inspect}
end
METHOD
end
end
end

def insert(record)
super
set_constant(record) if defined?(@enum_accessors)
Expand Down
67 changes: 67 additions & 0 deletions spec/enum/enum_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,73 @@ class Neighborhood < ActiveHash::Base
expect(Movie::THE_INFORMANT.name).to eq('The Informant!')
expect(Movie::IN_OUT.name).to eq('In & Out')
end

describe "enum(columns)" do
it "defines a predicate method for each value in the enum" do
Article = Class.new(ActiveHash::Base) do
include ActiveHash::Enum

self.data = [
{ name: 'Article 1', status: 'draft'},
{ name: 'Article 2', status: 'published'},
{ name: 'Article 3', status: 'archived'}
]

enum_accessor :name

enum status: [:draft, :published, :archived]
end

expect(Article::ARTICLE_1.draft?).to be_truthy
expect(Article::ARTICLE_1.published?).to be_falsey
expect(Article::ARTICLE_1.archived?).to be_falsey

expect(Article::ARTICLE_2.draft?).to be_falsey
expect(Article::ARTICLE_2.published?).to be_truthy
expect(Article::ARTICLE_2.archived?).to be_falsey

expect(Article::ARTICLE_3.draft?).to be_falsey
expect(Article::ARTICLE_3.published?).to be_falsey
expect(Article::ARTICLE_3.archived?).to be_truthy
end

it "multi type data (ex: string, integer and symbol) enum" do
NotifyType = Class.new(ActiveHash::Base) do
include ActiveHash::Enum

self.data = [
{ name: 'Like', action: 'LIKE'},
{ name: 'Comment', action: 1},
{ name: 'Follow', action: :FOLLOW},
{ name: 'Mention', action: 'MENTION'}
]

enum_accessor :name

enum action: { like: 'LIKE', comment: 1, follow: :FOLLOW, mention: 'MENTION' }
end

expect(NotifyType::LIKE.like?).to be_truthy
expect(NotifyType::LIKE.comment?).to be_falsey
expect(NotifyType::LIKE.follow?).to be_falsey
expect(NotifyType::LIKE.mention?).to be_falsey

expect(NotifyType::COMMENT.like?).to be_falsey
expect(NotifyType::COMMENT.comment?).to be_truthy
expect(NotifyType::COMMENT.follow?).to be_falsey
expect(NotifyType::COMMENT.mention?).to be_falsey

expect(NotifyType::FOLLOW.like?).to be_falsey
expect(NotifyType::FOLLOW.comment?).to be_falsey
expect(NotifyType::FOLLOW.follow?).to be_truthy
expect(NotifyType::FOLLOW.mention?).to be_falsey

expect(NotifyType::MENTION.like?).to be_falsey
expect(NotifyType::MENTION.comment?).to be_falsey
expect(NotifyType::MENTION.follow?).to be_falsey
expect(NotifyType::MENTION.mention?).to be_truthy
end
end
end

context "ActiveHash with an enum_accessor set" do
Expand Down

0 comments on commit 0b3701c

Please sign in to comment.