enum_table 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/CHANGELOG +3 -0
- data/Gemfile +2 -0
- data/LICENSE +20 -0
- data/README.markdown +136 -0
- data/Rakefile +1 -0
- data/enum_table.gemspec +19 -0
- data/lib/enum_table.rb +11 -0
- data/lib/enum_table/railtie.rb +13 -0
- data/lib/enum_table/record.rb +214 -0
- data/lib/enum_table/reflection.rb +52 -0
- data/lib/enum_table/schema_dumper.rb +51 -0
- data/lib/enum_table/schema_statements.rb +86 -0
- data/lib/enum_table/version.rb +11 -0
- data/test/database.yml +19 -0
- data/test/enum_table/test_record.rb +578 -0
- data/test/enum_table/test_reflection.rb +114 -0
- data/test/enum_table/test_schema_dumper.rb +75 -0
- data/test/enum_table/test_schema_statements.rb +131 -0
- data/test/test_helper.rb +53 -0
- metadata +109 -0
@@ -0,0 +1,114 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe EnumTable::Reflection do
|
4
|
+
let(:reflection) { EnumTable::Reflection.new(:gender, female: 1, male: 2) }
|
5
|
+
|
6
|
+
describe "#initialize" do
|
7
|
+
it "uses symbol values if :type is :symbol" do
|
8
|
+
reflection = EnumTable::Reflection.new(:gender, type: :symbol)
|
9
|
+
reflection.add_value 1, 'female'
|
10
|
+
reflection.value(1).must_equal(:female)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "uses string values if :type is :string" do
|
14
|
+
reflection = EnumTable::Reflection.new(:gender, type: :string)
|
15
|
+
reflection.add_value 1, :female
|
16
|
+
reflection.value(1).must_equal('female')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "raises an ArgumentError if :type is something else" do
|
20
|
+
->{ EnumTable::Reflection.new :gender, type: :other }.must_raise ArgumentError, /invalid type/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#initialize_copy" do
|
25
|
+
it "sets the same name" do
|
26
|
+
reflection = EnumTable::Reflection.new(:gender)
|
27
|
+
copy = reflection.dup
|
28
|
+
copy.name.must_equal :gender
|
29
|
+
end
|
30
|
+
|
31
|
+
it "sets the same values" do
|
32
|
+
reflection = EnumTable::Reflection.new(:gender)
|
33
|
+
reflection.add_value 1, :female
|
34
|
+
copy = reflection.dup
|
35
|
+
copy.value(1).must_equal :female
|
36
|
+
end
|
37
|
+
|
38
|
+
it "sets a separate collection of values" do
|
39
|
+
reflection = EnumTable::Reflection.new(:gender)
|
40
|
+
copy = reflection.dup
|
41
|
+
copy.add_value(1, :female)
|
42
|
+
reflection.value(1).must_be_nil
|
43
|
+
copy.value(1).must_equal :female
|
44
|
+
end
|
45
|
+
|
46
|
+
it "sets the same type" do
|
47
|
+
reflection = EnumTable::Reflection.new(:gender, type: :string)
|
48
|
+
copy = reflection.dup
|
49
|
+
copy.type.must_equal :string
|
50
|
+
end
|
51
|
+
|
52
|
+
it "sets the same id_name" do
|
53
|
+
reflection = EnumTable::Reflection.new(:gender, id_name: :status_id)
|
54
|
+
copy = reflection.dup
|
55
|
+
copy.id_name.must_equal :status_id
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#name' do
|
60
|
+
it "returns the name of the reflection" do
|
61
|
+
reflection = EnumTable::Reflection.new(:gender)
|
62
|
+
reflection.name.must_equal :gender
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#id_name' do
|
67
|
+
it "can be set with an :id_name option" do
|
68
|
+
reflection = EnumTable::Reflection.new(:gender, id_name: :gender_number)
|
69
|
+
reflection.id_name.must_equal :gender_number
|
70
|
+
end
|
71
|
+
|
72
|
+
it "is the name suffixed with '_id' by default" do
|
73
|
+
reflection = EnumTable::Reflection.new(:gender)
|
74
|
+
reflection.id_name.must_equal :gender_id
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#value' do
|
79
|
+
it "returns the value for the given id" do
|
80
|
+
reflection = EnumTable::Reflection.new(:gender)
|
81
|
+
reflection.add_value 1, :female
|
82
|
+
reflection.value(1).must_equal :female
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns nil if no value is defined for the given id" do
|
86
|
+
reflection = EnumTable::Reflection.new(:gender)
|
87
|
+
reflection.add_value 1, :female
|
88
|
+
reflection.value(2).must_be_nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#id' do
|
93
|
+
it "returns the value for the given value" do
|
94
|
+
reflection = EnumTable::Reflection.new(:gender)
|
95
|
+
reflection.add_value 1, :female
|
96
|
+
reflection.id(:female).must_equal 1
|
97
|
+
end
|
98
|
+
|
99
|
+
it "returns nil if no value is defined for the given id" do
|
100
|
+
reflection = EnumTable::Reflection.new(:gender)
|
101
|
+
reflection.add_value 1, :female
|
102
|
+
reflection.id(:male).must_be_nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "#values" do
|
107
|
+
it "returns the list of enum values" do
|
108
|
+
reflection = EnumTable::Reflection.new(:gender)
|
109
|
+
reflection.add_value 1, :female
|
110
|
+
reflection.add_value 2, :male
|
111
|
+
reflection.values.must_equal [:female, :male]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe EnumTable::SchemaDumper do
|
4
|
+
use_database
|
5
|
+
|
6
|
+
describe "#dump" do
|
7
|
+
let(:stream) { StringIO.new }
|
8
|
+
|
9
|
+
describe "when there are enum tables" do
|
10
|
+
it "does not dump the enum_tables with create_table" do
|
11
|
+
connection.create_enum_table :user_genders
|
12
|
+
ActiveRecord::SchemaDumper.dump(connection, stream)
|
13
|
+
stream.string.wont_match(/create_table.*user_genders/)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "dumps the enum tables with create_enum_table" do
|
17
|
+
connection.create_enum_table :user_genders
|
18
|
+
ActiveRecord::SchemaDumper.dump(connection, stream)
|
19
|
+
stream.string.must_match(/create_enum_table.*user_genders.*force: true/)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "populates the enum tables" do
|
23
|
+
connection.instance_eval do
|
24
|
+
create_enum_table :user_genders do |t|
|
25
|
+
t.add :female, 1
|
26
|
+
t.add :male
|
27
|
+
end
|
28
|
+
end
|
29
|
+
ActiveRecord::SchemaDumper.dump(connection, stream)
|
30
|
+
stream.string.must_include(<<-EOS.gsub(/^ *\|/, ''))
|
31
|
+
| create_enum_table "user_genders", force: true do |t|
|
32
|
+
| t.add "female", 1
|
33
|
+
| t.add "male", 2
|
34
|
+
| end
|
35
|
+
EOS
|
36
|
+
end
|
37
|
+
|
38
|
+
it "dumps custom id column attributes" do
|
39
|
+
connection.create_enum_table :user_genders do |t|
|
40
|
+
t.id type: :string, limit: 20, null: true
|
41
|
+
end
|
42
|
+
ActiveRecord::SchemaDumper.dump(connection, stream)
|
43
|
+
stream.string.must_include(<<-EOS.gsub(/^ *\|/, ''))
|
44
|
+
| create_enum_table "user_genders", force: true do |t|
|
45
|
+
| t.id type: :string, limit: 20, null: true
|
46
|
+
| end
|
47
|
+
EOS
|
48
|
+
end
|
49
|
+
|
50
|
+
it "dumps custom value column attributes" do
|
51
|
+
connection.create_enum_table :user_genders do |t|
|
52
|
+
t.value type: :binary, limit: 20, null: true
|
53
|
+
end
|
54
|
+
ActiveRecord::SchemaDumper.dump(connection, stream)
|
55
|
+
stream.string.must_include(<<-EOS.gsub(/^ *\|/, ''))
|
56
|
+
| create_enum_table "user_genders", force: true do |t|
|
57
|
+
| t.value type: :binary, limit: 20, null: true
|
58
|
+
| end
|
59
|
+
EOS
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "when there are no enum tables" do
|
64
|
+
it "populates no enum tables if there are none" do
|
65
|
+
ActiveRecord::SchemaDumper.dump(connection, stream)
|
66
|
+
stream.string.wont_include('change_enum_table')
|
67
|
+
end
|
68
|
+
|
69
|
+
it "does not populate enum_tables" do
|
70
|
+
ActiveRecord::SchemaDumper.dump(connection, stream)
|
71
|
+
stream.string.wont_include "INSERT INTO enum_tables"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe EnumTable::SchemaStatements do
|
4
|
+
use_database
|
5
|
+
|
6
|
+
describe "#create_enum_table" do
|
7
|
+
it "creates an enum table with the default name and default schema if none are given" do
|
8
|
+
connection.create_enum_table :genders
|
9
|
+
connection.tables.sort.must_equal ['enum_tables', 'genders']
|
10
|
+
connection.columns(:genders).map(&:name).must_equal ['id', 'value']
|
11
|
+
connection.columns(:genders).map(&:type).must_equal [:integer, :string]
|
12
|
+
connection.columns(:genders).map(&:null).must_equal [false, false]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "accepts :values as a Hash" do
|
16
|
+
connection.create_enum_table :genders, values: {female: 2, male: 5}
|
17
|
+
read_table('genders').must_equal [[2, 'female'], [5, 'male']]
|
18
|
+
end
|
19
|
+
|
20
|
+
it "accepts :values as an Array" do
|
21
|
+
connection.create_enum_table :genders, values: [:female, :male]
|
22
|
+
read_table('genders').must_equal [[1, 'female'], [2, 'male']]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "passes on other options to create_table" do
|
26
|
+
connection.create_table :genders
|
27
|
+
->{ connection.create_enum_table :genders }.must_raise(ActiveRecord::StatementInvalid)
|
28
|
+
connection.create_enum_table :genders, force: true
|
29
|
+
end
|
30
|
+
|
31
|
+
it "allows configuring the id column in the block" do
|
32
|
+
connection.create_enum_table :genders do |t|
|
33
|
+
t.id type: :string, limit: 20
|
34
|
+
end
|
35
|
+
column = connection.columns(:genders).find { |c| c.name == 'id' }
|
36
|
+
column.type.must_equal :string
|
37
|
+
column.limit.must_equal 20
|
38
|
+
end
|
39
|
+
|
40
|
+
it "allows configuring the type column in the block" do
|
41
|
+
connection.create_enum_table :genders do |t|
|
42
|
+
t.value type: :binary, limit: 20
|
43
|
+
end
|
44
|
+
column = connection.columns(:genders).find { |c| c.name == 'value' }
|
45
|
+
column.type.must_equal :binary
|
46
|
+
column.limit.must_equal 20
|
47
|
+
end
|
48
|
+
|
49
|
+
it "records the enum_table" do
|
50
|
+
connection.create_enum_table :genders
|
51
|
+
result = connection.execute "SELECT table_name FROM enum_tables"
|
52
|
+
result.map { |row| row[0] }.must_equal ['genders']
|
53
|
+
end
|
54
|
+
|
55
|
+
it "does not populate the table if no values are given" do
|
56
|
+
connection.create_enum_table :genders
|
57
|
+
read_table('genders').must_equal []
|
58
|
+
end
|
59
|
+
|
60
|
+
it "populates the table from values given in the block" do
|
61
|
+
connection.create_enum_table :genders do |t|
|
62
|
+
t.add :female, 1
|
63
|
+
t.add :male, 2
|
64
|
+
end
|
65
|
+
read_table('genders').must_equal [[1, 'female'], [2, 'male']]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#change_enum_table" do
|
70
|
+
before do
|
71
|
+
connection.execute "CREATE TABLE genders(id integer, value varchar(20))"
|
72
|
+
connection.execute "INSERT INTO genders (id, value) VALUES (1, 'female'), (2, 'male')"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "inserts values added in the block" do
|
76
|
+
connection.change_enum_table :genders do |t|
|
77
|
+
t.add :other, 3
|
78
|
+
end
|
79
|
+
read_table('genders').must_equal [[1, 'female'], [2, 'male'], [3, 'other']]
|
80
|
+
end
|
81
|
+
|
82
|
+
it "defaults the ID to the next available" do
|
83
|
+
connection.change_enum_table :genders do |t|
|
84
|
+
t.add :other
|
85
|
+
end
|
86
|
+
read_table('genders').must_equal [[1, 'female'], [2, 'male'], [3, 'other']]
|
87
|
+
end
|
88
|
+
|
89
|
+
it "deletes values removed in the block" do
|
90
|
+
connection.change_enum_table :genders do |t|
|
91
|
+
t.remove :male
|
92
|
+
end
|
93
|
+
read_table('genders').must_equal [[1, 'female']]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#drop_enum_table" do
|
98
|
+
it "removes the table from enum_tables if required" do
|
99
|
+
connection.create_enum_table :genders
|
100
|
+
connection.drop_enum_table :genders
|
101
|
+
result = connection.execute "SELECT table_name FROM enum_tables"
|
102
|
+
result.to_a.must_equal []
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "#enum_tables" do
|
107
|
+
it "returns the names of the enum tables" do
|
108
|
+
connection.create_enum_table :genders
|
109
|
+
connection.create_enum_table :statuses
|
110
|
+
connection.enum_tables.must_equal ['genders', 'statuses']
|
111
|
+
end
|
112
|
+
|
113
|
+
it "returns no tables if no enum tables have ever existed" do
|
114
|
+
connection.enum_tables.must_equal []
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns no tables if all enum tables have been dropped" do
|
118
|
+
connection.create_enum_table :genders
|
119
|
+
connection.drop_enum_table :genders
|
120
|
+
connection.enum_tables.must_equal []
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def read_table(name)
|
125
|
+
rows = []
|
126
|
+
connection.execute("SELECT id, value FROM #{name} ORDER BY id").each do |row|
|
127
|
+
rows << [row[0], row[1]]
|
128
|
+
end
|
129
|
+
rows
|
130
|
+
end
|
131
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
ROOT = File.expand_path('..', File.dirname(__FILE__))
|
2
|
+
$:.unshift "#{ROOT}/lib"
|
3
|
+
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'active_record'
|
6
|
+
require 'enum_table'
|
7
|
+
|
8
|
+
ADAPTER = ENV['ENUM_TABLE_ADAPTER'] || 'sqlite3'
|
9
|
+
CONFIG = YAML.load_file("#{ROOT}/test/database.yml")[ADAPTER].merge(adapter: ADAPTER)
|
10
|
+
case ADAPTER
|
11
|
+
when /sqlite/
|
12
|
+
ActiveRecord::Base.establish_connection(CONFIG)
|
13
|
+
when /postgres/
|
14
|
+
ActiveRecord::Base.establish_connection(CONFIG.merge('database' => 'postgres'))
|
15
|
+
else
|
16
|
+
ActiveRecord::Base.establish_connection(CONFIG.merge('database' => nil))
|
17
|
+
end
|
18
|
+
|
19
|
+
MiniTest::Spec.class_eval do
|
20
|
+
def recreate_database
|
21
|
+
drop_database
|
22
|
+
create_database
|
23
|
+
end
|
24
|
+
|
25
|
+
def connection
|
26
|
+
ActiveRecord::Base.connection
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_database
|
30
|
+
unless ADAPTER =~ /sqlite/
|
31
|
+
connection.create_database CONFIG['database']
|
32
|
+
end
|
33
|
+
ActiveRecord::Base.establish_connection(CONFIG)
|
34
|
+
end
|
35
|
+
|
36
|
+
def drop_database
|
37
|
+
case ADAPTER
|
38
|
+
when /sqlite/
|
39
|
+
# Nothing to do - in-memory database.
|
40
|
+
when /postgres/
|
41
|
+
# Postgres barfs if you drop the selected database.
|
42
|
+
ActiveRecord::Base.establish_connection(CONFIG.merge('database' => 'postgres'))
|
43
|
+
connection.drop_database CONFIG['database']
|
44
|
+
else
|
45
|
+
connection.drop_database CONFIG['database']
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.use_database
|
50
|
+
before { recreate_database }
|
51
|
+
after { drop_database }
|
52
|
+
end
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: enum_table
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- George Ogata
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: ritual
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.4.1
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.4.1
|
46
|
+
description:
|
47
|
+
email:
|
48
|
+
- george.ogata@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- CHANGELOG
|
55
|
+
- Gemfile
|
56
|
+
- LICENSE
|
57
|
+
- README.markdown
|
58
|
+
- Rakefile
|
59
|
+
- enum_table.gemspec
|
60
|
+
- lib/enum_table.rb
|
61
|
+
- lib/enum_table/railtie.rb
|
62
|
+
- lib/enum_table/record.rb
|
63
|
+
- lib/enum_table/reflection.rb
|
64
|
+
- lib/enum_table/schema_dumper.rb
|
65
|
+
- lib/enum_table/schema_statements.rb
|
66
|
+
- lib/enum_table/version.rb
|
67
|
+
- test/database.yml
|
68
|
+
- test/enum_table/test_record.rb
|
69
|
+
- test/enum_table/test_reflection.rb
|
70
|
+
- test/enum_table/test_schema_dumper.rb
|
71
|
+
- test/enum_table/test_schema_statements.rb
|
72
|
+
- test/test_helper.rb
|
73
|
+
homepage: http://github.com/howaboutwe/enum_table
|
74
|
+
licenses: []
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
hash: 123907201229092467
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
hash: 123907201229092467
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 1.8.24
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: Enumeration tables for ActiveRecord
|
103
|
+
test_files:
|
104
|
+
- test/database.yml
|
105
|
+
- test/enum_table/test_record.rb
|
106
|
+
- test/enum_table/test_reflection.rb
|
107
|
+
- test/enum_table/test_schema_dumper.rb
|
108
|
+
- test/enum_table/test_schema_statements.rb
|
109
|
+
- test/test_helper.rb
|