enum_table 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 +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
|