enumattr 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in enumattr.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'rspec'
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 aisuii
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # Enumattr
2
+
3
+ * manage constants by enum like object
4
+ * simplify [SelectableAttr](https://github.com/akm/selectable_attr)
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'enumattr'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install enumattr
19
+
20
+ ## Usage
21
+
22
+ ### defining
23
+
24
+ * `include Enumattr::Base` and declare `enum_attr_for some_attribute do ... end`
25
+ * `enum :symbol, value` in block
26
+
27
+
28
+ <pre>
29
+ class User
30
+ include Enumattr::Base
31
+
32
+ attr_accessor :status
33
+
34
+ enum_attr_for :status do
35
+ enum :active, 1
36
+ enum :suspend, 2
37
+ enum :deleted, 3
38
+ end
39
+
40
+ def initialize(status)
41
+ @status = status
42
+ end
43
+ end
44
+ </pre>
45
+
46
+ ### defined methods
47
+
48
+ #### class methods
49
+
50
+ * `SomeClass.#{some_attribute}_enums` return enum set
51
+ * `SomeClass.#{some_attribute}_keys` return key set
52
+ * `SomeClass.#{some_attribute}_values` return value set
53
+
54
+ <pre>
55
+ User.status_enums
56
+ #=&gt; #&lt;Set: {#&lt;Enumattr::Enum:0x8a8d13c @key=:active, @value=1&gt;, #&lt;Enumattr::Enum:0x8a8d100 @key=:suspend, @value=2&gt;, #&lt;Enumattr::Enum:0x8a8d0ec @key=:deleted, @value=3&gt;}&gt;
57
+
58
+ User.status_keys
59
+ #=&gt; #&lt;Set: {:active, :suspend, :deleted}&gt;
60
+
61
+ User.status_values
62
+ #=&gt; #&lt;Set: {1, 2, 3}&gt;
63
+ </pre>
64
+
65
+ * `SomeClass.#{some_attribute}_enum_by_key(:symbol)` return an enum
66
+ * `SomeClass.#{some_attribute}_value_by_key(:symbol)` return a value
67
+
68
+ <pre>
69
+ User.status_enum_by_key :active
70
+ #=&gt; #&lt;Enumattr::Enum:0x8a8d13c @key=:active, @value=1&gt;
71
+
72
+ User.status_enum_by_key :suspend
73
+ #=&gt; #&lt;Enumattr::Enum:0x8a8d100 @key=:suspend, @value=2&gt;
74
+
75
+ User.status_enum_by_key :dummy
76
+ #=&gt; nil
77
+
78
+ User.status_value_by_key :active
79
+ #=&gt; 1
80
+
81
+ User.status_value_by_key :suspend
82
+ #=&gt; 2
83
+
84
+ User.status_value_by_key :dummy
85
+ #=&gt; nil
86
+ </pre>
87
+
88
+ #### instance methods
89
+
90
+ * alias `#{some_attribute}_value` `some_attribute`
91
+ * `#{some_attribute}_key` return symbol
92
+ * `#{some_attribute}_enum` return enum
93
+
94
+ <pre>
95
+ user = User.new(1)
96
+ #=&gt; #&lt;User:0x8e17dac @status=1&gt;
97
+
98
+ user.status
99
+ #=&gt; 1
100
+
101
+ user.status_value # alias
102
+ #=&gt; 1
103
+
104
+ user.status_key
105
+ #=&gt; :active
106
+
107
+ user.status_enum
108
+ #=&gt; #&lt;Enumattr::Enum:0x8de2e68 @key=:active, @value=1&gt;
109
+ </pre>
110
+
111
+
112
+ * define query method
113
+ * `#{some_attribute}_#{some_symbol}?` return bool
114
+
115
+ <pre>
116
+ user.status_active?
117
+ #=&gt; true
118
+
119
+ user.status_suspend?
120
+ #=&gt; false
121
+
122
+ user.status_deleted?
123
+ #=&gt; false
124
+
125
+ user.status_dummy?
126
+ NoMethodError: undefined method `status_dummy?' for #&lt;User:0x8e17dac @status=1&gt;
127
+ </pre>
128
+
129
+
130
+ ## Contributing
131
+
132
+ 1. Fork it
133
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
134
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
135
+ 4. Push to the branch (`git push origin my-new-feature`)
136
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ task :default => :spec
6
+
7
+ desc "Run all specs in spec directory"
8
+ RSpec::Core::RakeTask.new(:spec)
data/enumattr.gemspec ADDED
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/enumattr/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["aisuii"]
6
+ gem.email = ["aisuiiaisuii@gmail.com"]
7
+ gem.description = %q{simple enum}
8
+ gem.summary = %q{manage constants by enum like object}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "enumattr"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Enumattr::VERSION
17
+ end
data/examples/user.rb ADDED
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ class User
4
+ include Enumattr::Base
5
+
6
+ attr_accessor :status
7
+
8
+ enum_attr_for :status do
9
+ enum :active, 1
10
+ enum :suspend, 2
11
+ enum :deleted, 3
12
+ end
13
+
14
+ def initialize(status)
15
+ @status = status
16
+ end
17
+ end
@@ -0,0 +1,82 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Enumattr
4
+ module Base
5
+ def self.included(klass)
6
+ klass.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ private
11
+ def enum_attr_for(enum_attr_name, &block)
12
+ enum_attrs[enum_attr_name] = Enums.new(&block)
13
+ define_class_methods enum_attr_name
14
+ define_instance_methods enum_attr_name
15
+ define_instance_query_methods enum_attr_name
16
+ end
17
+
18
+ def enum_attrs
19
+ @enum_attrs ||= {}
20
+ end
21
+
22
+ def define_class_methods(enum_attr_name)
23
+ enums = enum_attrs[enum_attr_name]
24
+ method_prefix = "#{enum_attr_name}_"
25
+
26
+ mod = Module.new do
27
+ define_method("#{method_prefix}enums") do
28
+ enums.enums
29
+ end
30
+
31
+ define_method("#{method_prefix}keys") do
32
+ enums.keys
33
+ end
34
+
35
+ define_method("#{method_prefix}values") do
36
+ enums.values
37
+ end
38
+
39
+ define_method("#{method_prefix}enum_by_key") do |key|
40
+ enums.enum_by_key(key)
41
+ end
42
+
43
+ define_method("#{method_prefix}value_by_key") do |key|
44
+ enum = enums.enum_by_key(key)
45
+ enum && enum.value
46
+ end
47
+ end
48
+
49
+ extend mod
50
+ end
51
+
52
+ def define_instance_methods(enum_attr_name)
53
+ enums = enum_attrs[enum_attr_name]
54
+ method_prefix = "#{enum_attr_name}_"
55
+
56
+ define_method("#{method_prefix}enum") do
57
+ value = __send__ enum_attr_name
58
+ enums.enum_by_value(value)
59
+ end
60
+
61
+ define_method("#{method_prefix}key") do
62
+ enum = __send__ "#{method_prefix}enum"
63
+ enum.key
64
+ end
65
+
66
+ alias_method :"#{method_prefix}value", enum_attr_name
67
+ end
68
+
69
+ def define_instance_query_methods(enum_attr_name)
70
+ enums = enum_attrs[enum_attr_name]
71
+ method_prefix = "#{enum_attr_name}_"
72
+
73
+ enums.enums.each do |enum|
74
+ define_method("#{method_prefix}#{enum.key}?") do
75
+ value = __send__ enum_attr_name
76
+ value == enum.value
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Enumattr
4
+ class Enum
5
+ attr_reader :key, :value
6
+
7
+ def initialize(key, value)
8
+ @key = key.to_sym
9
+ @value = value
10
+ end
11
+
12
+ def hash
13
+ @key.hash
14
+ end
15
+
16
+ def eql?(other)
17
+ @key == other.key
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'set'
3
+
4
+ module Enumattr
5
+ class Enums
6
+ def initialize(&block)
7
+ @set = Set.new
8
+ instance_eval(&block)
9
+ freeze
10
+ end
11
+
12
+ def enums
13
+ @set.clone
14
+ end
15
+
16
+ def keys
17
+ Set.new @set.map(&:key)
18
+ end
19
+
20
+ def values
21
+ Set.new @set.map(&:value)
22
+ end
23
+
24
+ def enum_by_key(key)
25
+ @set.find{|enum| enum.key == key }
26
+ end
27
+
28
+ def enum_by_value(value)
29
+ @set.find{|enum| enum.value == value }
30
+ end
31
+
32
+ private
33
+ def enum(key, value)
34
+ @set.add Enum.new(key, value)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module Enumattr
2
+ VERSION = "0.0.1"
3
+ end
data/lib/enumattr.rb ADDED
@@ -0,0 +1,8 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "enumattr/version"
3
+
4
+ module Enumattr
5
+ autoload :Base, 'enumattr/base'
6
+ autoload :Enums, 'enumattr/enums'
7
+ autoload :Enum, 'enumattr/enum'
8
+ end
@@ -0,0 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Enumattr::Enum do
5
+ let(:one_enum) { Enumattr::Enum.new(:my_key, 1) }
6
+ let(:same_key_enum) { Enumattr::Enum.new(:my_key, 2) }
7
+ let(:another_enum) { Enumattr::Enum.new(:another, 3) }
8
+
9
+ describe "getters" do
10
+ subject { one_enum }
11
+ its(:key) { should == :my_key }
12
+ its(:value) { should == 1 }
13
+ end
14
+
15
+ describe "in hash key" do
16
+ context "when hash has same key enum as hash key" do
17
+ subject do
18
+ hash = {}
19
+ hash[one_enum] = 1
20
+ hash[same_key_enum] = 2 # only value overrided
21
+ hash[another_enum] = 3
22
+ hash
23
+ end
24
+
25
+ its(:keys) { should include one_enum }
26
+ its(:keys) { should_not include same_key_enum }
27
+ its(:keys) { should include another_enum }
28
+
29
+ its(:values) { should_not include 1 }
30
+ its(:values) { should include 2 }
31
+ its(:values) { should include 3 }
32
+
33
+ it "should have 2 items" do
34
+ subject.should have(2).items
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,84 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Enumattr::Enums do
5
+ let(:enums) do
6
+ Enumattr::Enums.new do
7
+ enum :key1, 1
8
+ enum :key2, 2
9
+ enum :key3, 3
10
+ end
11
+ end
12
+
13
+ describe "#enums" do
14
+ subject { enums.enums }
15
+ it { should be_a Set }
16
+ it { should have(3).items }
17
+ it "should have Enumattr::Enum instances" do
18
+ should satisfy { |enums|
19
+ enums.all?{|item| item.is_a? Enumattr::Enum }
20
+ }
21
+ end
22
+ end
23
+
24
+ describe "#keys" do
25
+ subject { enums.keys }
26
+ it { should be_a Set }
27
+ it { should have(3).items }
28
+ it "should have Symbol instances" do
29
+ should satisfy { |keys|
30
+ keys.all?{|item| item.is_a? Symbol }
31
+ }
32
+ end
33
+ end
34
+
35
+ describe "#values" do
36
+ subject { enums.values }
37
+ it { should be_a Set }
38
+ it { should have(3).items }
39
+ it "should have Numeric instances" do
40
+ should satisfy { |values|
41
+ values.all?{|item| item.is_a? Numeric }
42
+ }
43
+ end
44
+ end
45
+
46
+ describe "find methods" do
47
+ shared_examples "#enum_by_foo(foo) each items" do
48
+ it { should be_a Enumattr::Enum }
49
+ its(:key) { should == expects[:key] }
50
+ its(:value) { should == expects[:value] }
51
+ end
52
+
53
+ samples = [
54
+ {:key => :key1, :value => 1},
55
+ {:key => :key2, :value => 2},
56
+ {:key => :key3, :value => 3},
57
+ ]
58
+
59
+ describe "#enum_by_key(key)" do
60
+ subject { enums.enum_by_key(key) }
61
+ samples.each do |sample|
62
+ context "key: #{sample[:key]}" do
63
+ let(:key) { sample[:key] }
64
+ let(:expects) { sample }
65
+
66
+ include_examples "#enum_by_foo(foo) each items"
67
+ end
68
+ end
69
+ end
70
+
71
+ describe "#enum_by_value(value)" do
72
+ subject { enums.enum_by_value(value) }
73
+
74
+ samples.each do |sample|
75
+ context "value: #{sample[:value]}" do
76
+ let(:value) { sample[:value] }
77
+ let(:expects) { sample }
78
+
79
+ include_examples "#enum_by_foo(foo) each items"
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,116 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'user'
4
+
5
+ describe User do
6
+ describe "class methods" do
7
+ describe '.status_enums as #{enum_attr_name}_enums' do
8
+ subject { described_class.status_enums }
9
+
10
+ it { should be_a Set }
11
+ it { should have(3).items }
12
+ it "should have Enum instances" do
13
+ should satisfy { |enums|
14
+ enums.all?{|item| item.is_a? Enumattr::Enum }
15
+ }
16
+ end
17
+ end
18
+
19
+ describe '.status_keys as #{enum_attr_name}_keys' do
20
+ subject { described_class.status_keys }
21
+
22
+ it { should be_a Set }
23
+ it { should have(3).items }
24
+ it "should have Symbol instances" do
25
+ should satisfy { |keys|
26
+ keys.all?{|item| item.is_a? Symbol }
27
+ }
28
+ end
29
+ end
30
+
31
+ describe '.status_values as #{enum_attr_name}_values' do
32
+ subject { described_class.status_values }
33
+
34
+ it { should be_a Set }
35
+ it { should have(3).items }
36
+ it "should have Numeric instances" do
37
+ should satisfy { |values|
38
+ values.all?{|item| item.is_a? Numeric }
39
+ }
40
+ end
41
+ end
42
+
43
+ describe '.status_enum_by_key as #{enum_attr_name}_enum_by_key' do
44
+ subject { described_class.status_enum_by_key(:active) }
45
+
46
+ it { should be_a Enumattr::Enum }
47
+ its(:key) { should == :active }
48
+ its(:value) { should == 1 }
49
+ end
50
+
51
+ describe '.status_value_by_key as #{enum_attr_name}_value_by_key' do
52
+ context "present key" do
53
+ subject { described_class.status_value_by_key(:active) }
54
+
55
+ it { should == 1 }
56
+ end
57
+
58
+ context "not present key" do
59
+ subject { described_class.status_value_by_key(:not_present_key) }
60
+
61
+ it { should be_nil }
62
+ end
63
+ end
64
+ end
65
+
66
+
67
+ describe "instance methods" do
68
+ let(:user) { User.new(1) }
69
+
70
+ describe "#status" do
71
+ subject { user.status }
72
+
73
+ it { should == 1 }
74
+ end
75
+
76
+ describe '#status_enum as #{enum_attr_name}_enum' do
77
+ subject { user.status_enum }
78
+
79
+ it { should be_a Enumattr::Enum }
80
+ its(:key) { should == :active }
81
+ its(:value) { should == 1 }
82
+ end
83
+
84
+ describe '#status_key as #{enum_attr_name}_key' do
85
+ subject { user.status_key }
86
+
87
+ it { should be_a Symbol }
88
+ it { should == :active }
89
+ end
90
+
91
+ describe '#status_value as #{enum_attr_name}_value' do
92
+ subject { user.status_value }
93
+
94
+ it { should be_a Numeric }
95
+ it { should == 1 }
96
+ end
97
+
98
+ describe '#status_active? as #{enum_attr_name}_#{status_key}?' do
99
+ subject { user.status_active? }
100
+
101
+ it { should be_true }
102
+ end
103
+
104
+ describe '#status_suspend? as #{enum_attr_name}_#{other_status_key}?' do
105
+ subject { user.status_suspend? }
106
+
107
+ it { should be_false }
108
+ end
109
+
110
+ describe '#status_deleted? as #{enum_attr_name}_#{other_status_key}?' do
111
+ subject { user.status_deleted? }
112
+
113
+ it { should be_false }
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,17 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'examples'))
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+
5
+ require 'enumattr'
6
+
7
+ # This file was generated by the `rspec --init` command. Conventionally, all
8
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
9
+ # Require this file using `require "spec_helper.rb"` to ensure that it is only
10
+ # loaded once.
11
+ #
12
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
13
+ RSpec.configure do |config|
14
+ config.treat_symbols_as_metadata_keys_with_true_values = true
15
+ config.run_all_when_everything_filtered = true
16
+ config.filter_run :focus
17
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: enumattr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - aisuii
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-27 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: simple enum
15
+ email:
16
+ - aisuiiaisuii@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - .rspec
23
+ - Gemfile
24
+ - LICENSE
25
+ - README.md
26
+ - Rakefile
27
+ - enumattr.gemspec
28
+ - examples/user.rb
29
+ - lib/enumattr.rb
30
+ - lib/enumattr/base.rb
31
+ - lib/enumattr/enum.rb
32
+ - lib/enumattr/enums.rb
33
+ - lib/enumattr/version.rb
34
+ - spec/enumattr/enum_spec.rb
35
+ - spec/enumattr/enums_spec.rb
36
+ - spec/enumattr/included_spec.rb
37
+ - spec/spec_helper.rb
38
+ homepage: ''
39
+ licenses: []
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 1.8.21
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: manage constants by enum like object
62
+ test_files:
63
+ - spec/enumattr/enum_spec.rb
64
+ - spec/enumattr/enums_spec.rb
65
+ - spec/enumattr/included_spec.rb
66
+ - spec/spec_helper.rb