attr_encrypted 1.2.1 → 1.3.0
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/README.rdoc +2 -2
- data/Rakefile +15 -4
- data/lib/attr_encrypted.rb +45 -1
- data/lib/attr_encrypted/adapters/active_record.rb +9 -0
- data/lib/attr_encrypted/version.rb +2 -2
- data/test/active_record_test.rb +48 -52
- data/test/attr_encrypted_test.rb +33 -38
- data/test/compatibility_test.rb +126 -0
- data/test/data_mapper_test.rb +10 -5
- data/test/legacy_active_record_test.rb +116 -0
- data/test/legacy_attr_encrypted_test.rb +297 -0
- data/test/legacy_compatibility_test.rb +104 -0
- data/test/legacy_data_mapper_test.rb +52 -0
- data/test/legacy_sequel_test.rb +48 -0
- data/test/sequel_test.rb +12 -9
- data/test/test_helper.rb +26 -1
- metadata +109 -6
@@ -0,0 +1,104 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../test_helper', __FILE__)
|
3
|
+
|
4
|
+
# Test to ensure that existing representations in database do not break on
|
5
|
+
# migrating to new versions of this gem. This ensures that future versions of
|
6
|
+
# this gem will retain backwards compatibility with data generated by earlier
|
7
|
+
# versions.
|
8
|
+
class LegacyCompatibilityTest < Test::Unit::TestCase
|
9
|
+
class LegacyNonmarshallingPet < ActiveRecord::Base
|
10
|
+
PET_NICKNAME_SALT = Digest::SHA256.hexdigest('my-really-really-secret-pet-nickname-salt')
|
11
|
+
PET_NICKNAME_KEY = 'my-really-really-secret-pet-nickname-key'
|
12
|
+
PET_BIRTHDATE_SALT = Digest::SHA256.hexdigest('my-really-really-secret-pet-birthdate-salt')
|
13
|
+
PET_BIRTHDATE_KEY = 'my-really-really-secret-pet-birthdate-key'
|
14
|
+
|
15
|
+
attr_encrypted :nickname,
|
16
|
+
:key => proc { Encryptor.encrypt(:value => PET_NICKNAME_SALT, :key => PET_NICKNAME_KEY) }
|
17
|
+
attr_encrypted :birthdate,
|
18
|
+
:key => proc { Encryptor.encrypt(:value => PET_BIRTHDATE_SALT, :key => PET_BIRTHDATE_KEY) }
|
19
|
+
end
|
20
|
+
|
21
|
+
class LegacyMarshallingPet < ActiveRecord::Base
|
22
|
+
PET_NICKNAME_SALT = Digest::SHA256.hexdigest('my-really-really-secret-pet-nickname-salt')
|
23
|
+
PET_NICKNAME_KEY = 'my-really-really-secret-pet-nickname-key'
|
24
|
+
PET_BIRTHDATE_SALT = Digest::SHA256.hexdigest('my-really-really-secret-pet-birthdate-salt')
|
25
|
+
PET_BIRTHDATE_KEY = 'my-really-really-secret-pet-birthdate-key'
|
26
|
+
|
27
|
+
attr_encrypted :nickname,
|
28
|
+
:key => proc { Encryptor.encrypt(:value => PET_NICKNAME_SALT, :key => PET_NICKNAME_KEY) },
|
29
|
+
:marshal => true
|
30
|
+
attr_encrypted :birthdate,
|
31
|
+
:key => proc { Encryptor.encrypt(:value => PET_BIRTHDATE_SALT, :key => PET_BIRTHDATE_KEY) },
|
32
|
+
:marshal => true
|
33
|
+
end
|
34
|
+
|
35
|
+
def setup
|
36
|
+
ActiveRecord::Base.connection.tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
|
37
|
+
create_tables
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_nonmarshalling_backwards_compatibility
|
41
|
+
pet = LegacyNonmarshallingPet.create!(
|
42
|
+
:name => 'Fido',
|
43
|
+
:encrypted_nickname => 'uSUB6KGzta87yxesyVc3DA==',
|
44
|
+
:encrypted_birthdate => 'I3d691B2PtFXLx15kO067g=='
|
45
|
+
)
|
46
|
+
|
47
|
+
assert_equal 'Fido', pet.name
|
48
|
+
assert_equal 'Fido the Dog', pet.nickname
|
49
|
+
assert_equal '2011-07-09', pet.birthdate
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_marshalling_backwards_compatibility
|
53
|
+
# Marshalling formats changed significantly from Ruby 1.8.7 to 1.9.3.
|
54
|
+
# Also, Date class did not correctly support marshalling pre-1.9.3, so here
|
55
|
+
# we just marshal it as a string in the Ruby 1.8.7 case.
|
56
|
+
if RUBY_VERSION < '1.9.3'
|
57
|
+
pet = LegacyMarshallingPet.create!(
|
58
|
+
:name => 'Fido',
|
59
|
+
:encrypted_nickname => 'xhayxWxfkfbNyOS2w1qBMPV49Gfvs6dcZFBopMK2zQA=',
|
60
|
+
:encrypted_birthdate => 'f4ufXun4GXzahH4MQ1eTBQ=='
|
61
|
+
)
|
62
|
+
else
|
63
|
+
pet = LegacyMarshallingPet.create!(
|
64
|
+
:name => 'Fido',
|
65
|
+
:encrypted_nickname => '7RwoT64in4H+fGVBPYtRcN0K4RtriIy1EP4nDojUa8g=',
|
66
|
+
:encrypted_birthdate => 'bSp9sJhXQSp2QlNZHiujtcK4lRVBE8HQhn1y7moQ63bGJR20hvRSZ73ePAmm+wc5'
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
assert_equal 'Fido', pet.name
|
71
|
+
assert_equal 'Mummy\'s little helper', pet.nickname
|
72
|
+
|
73
|
+
# See earlier comment.
|
74
|
+
if RUBY_VERSION < '1.9.3'
|
75
|
+
assert_equal '2011-07-09', pet.birthdate
|
76
|
+
else
|
77
|
+
assert_equal Date.new(2011, 7, 9), pet.birthdate
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def create_tables
|
84
|
+
silence_stream(STDOUT) do
|
85
|
+
ActiveRecord::Schema.define(:version => 1) do
|
86
|
+
create_table :legacy_nonmarshalling_pets do |t|
|
87
|
+
t.string :name
|
88
|
+
t.string :encrypted_nickname
|
89
|
+
t.string :encrypted_birthdate
|
90
|
+
t.string :salt
|
91
|
+
end
|
92
|
+
create_table :legacy_marshalling_pets do |t|
|
93
|
+
t.string :name
|
94
|
+
t.string :encrypted_nickname
|
95
|
+
t.string :encrypted_birthdate
|
96
|
+
t.string :salt
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
|
104
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
DataMapper.setup(:default, 'sqlite3::memory:')
|
4
|
+
|
5
|
+
class LegacyClient
|
6
|
+
include DataMapper::Resource
|
7
|
+
|
8
|
+
property :id, Serial
|
9
|
+
property :encrypted_email, String
|
10
|
+
property :encrypted_credentials, Text
|
11
|
+
property :salt, String
|
12
|
+
|
13
|
+
attr_encrypted :email, :key => 'a secret key'
|
14
|
+
attr_encrypted :credentials, :key => Proc.new { |client| Encryptor.encrypt(:value => client.salt, :key => 'some private key') }, :marshal => true
|
15
|
+
|
16
|
+
def initialize(attrs = {})
|
17
|
+
super attrs
|
18
|
+
self.salt ||= Digest::SHA1.hexdigest((Time.now.to_i * rand(5)).to_s)
|
19
|
+
self.credentials ||= { :username => 'example', :password => 'test' }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
DataMapper.auto_migrate!
|
24
|
+
|
25
|
+
class LegacyDataMapperTest < Test::Unit::TestCase
|
26
|
+
|
27
|
+
def setup
|
28
|
+
LegacyClient.all.each(&:destroy)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_encrypt_email
|
32
|
+
@client = LegacyClient.new :email => 'test@example.com'
|
33
|
+
assert @client.save
|
34
|
+
assert_not_nil @client.encrypted_email
|
35
|
+
assert_not_equal @client.email, @client.encrypted_email
|
36
|
+
assert_equal @client.email, LegacyClient.first.email
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_should_marshal_and_encrypt_credentials
|
40
|
+
@client = LegacyClient.new
|
41
|
+
assert @client.save
|
42
|
+
assert_not_nil @client.encrypted_credentials
|
43
|
+
assert_not_equal @client.credentials, @client.encrypted_credentials
|
44
|
+
assert_equal @client.credentials, LegacyClient.first.credentials
|
45
|
+
assert LegacyClient.first.credentials.is_a?(Hash)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_should_encode_by_default
|
49
|
+
assert LegacyClient.attr_encrypted_options[:encode]
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
DB.create_table :legacy_humans do
|
4
|
+
primary_key :id
|
5
|
+
column :encrypted_email, :string
|
6
|
+
column :password, :string
|
7
|
+
column :encrypted_credentials, :string
|
8
|
+
column :salt, :string
|
9
|
+
end
|
10
|
+
|
11
|
+
class LegacyHuman < Sequel::Model(:legacy_humans)
|
12
|
+
attr_encrypted :email, :key => 'a secret key'
|
13
|
+
attr_encrypted :credentials, :key => Proc.new { |human| Encryptor.encrypt(:value => human.salt, :key => 'some private key') }, :marshal => true
|
14
|
+
|
15
|
+
def after_initialize(attrs = {})
|
16
|
+
self.salt ||= Digest::SHA1.hexdigest((Time.now.to_i * rand(5)).to_s)
|
17
|
+
self.credentials ||= { :username => 'example', :password => 'test' }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class LegacySequelTest < Test::Unit::TestCase
|
22
|
+
|
23
|
+
def setup
|
24
|
+
LegacyHuman.all.each(&:destroy)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_encrypt_email
|
28
|
+
@human = LegacyHuman.new :email => 'test@example.com'
|
29
|
+
assert @human.save
|
30
|
+
assert_not_nil @human.encrypted_email
|
31
|
+
assert_not_equal @human.email, @human.encrypted_email
|
32
|
+
assert_equal @human.email, LegacyHuman.first.email
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_should_marshal_and_encrypt_credentials
|
36
|
+
@human = LegacyHuman.new
|
37
|
+
assert @human.save
|
38
|
+
assert_not_nil @human.encrypted_credentials
|
39
|
+
assert_not_equal @human.credentials, @human.encrypted_credentials
|
40
|
+
assert_equal @human.credentials, LegacyHuman.first.credentials
|
41
|
+
assert LegacyHuman.first.credentials.is_a?(Hash)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_should_encode_by_default
|
45
|
+
assert LegacyHuman.attr_encrypted_options[:encode]
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/test/sequel_test.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
require File.expand_path('../test_helper', __FILE__)
|
2
2
|
|
3
|
-
DB = Sequel.sqlite
|
4
|
-
|
5
3
|
DB.create_table :humans do
|
6
4
|
primary_key :id
|
7
5
|
column :encrypted_email, :string
|
6
|
+
column :encrypted_email_salt, String
|
7
|
+
column :encrypted_email_iv, :string
|
8
8
|
column :password, :string
|
9
9
|
column :encrypted_credentials, :string
|
10
|
-
column :
|
10
|
+
column :encrypted_credentials_iv, :string
|
11
|
+
column :encrypted_credentials_salt, String
|
11
12
|
end
|
12
13
|
|
13
|
-
class Human < Sequel::Model(:humans)
|
14
|
-
|
15
|
-
|
14
|
+
class Human < Sequel::Model(:humans)
|
15
|
+
self.attr_encrypted_options[:mode] = :per_attribute_iv_and_salt
|
16
|
+
|
17
|
+
attr_encrypted :email, :key => SECRET_KEY
|
18
|
+
attr_encrypted :credentials, :key => SECRET_KEY, :marshal => true
|
16
19
|
|
17
20
|
def after_initialize(attrs = {})
|
18
|
-
self.salt ||= Digest::SHA1.hexdigest((Time.now.to_i * rand(5)).to_s)
|
19
21
|
self.credentials ||= { :username => 'example', :password => 'test' }
|
20
22
|
end
|
21
23
|
end
|
@@ -35,7 +37,8 @@ class SequelTest < Test::Unit::TestCase
|
|
35
37
|
end
|
36
38
|
|
37
39
|
def test_should_marshal_and_encrypt_credentials
|
38
|
-
|
40
|
+
|
41
|
+
@human = Human.new :credentials => { :username => 'example', :password => 'test' }
|
39
42
|
assert @human.save
|
40
43
|
assert_not_nil @human.encrypted_credentials
|
41
44
|
assert_not_equal @human.credentials, @human.encrypted_credentials
|
@@ -47,4 +50,4 @@ class SequelTest < Test::Unit::TestCase
|
|
47
50
|
assert Human.attr_encrypted_options[:encode]
|
48
51
|
end
|
49
52
|
|
50
|
-
end
|
53
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
if RUBY_VERSION >= '1.9.3'
|
2
|
+
require 'simplecov'
|
3
|
+
require 'simplecov-rcov'
|
4
|
+
|
5
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
6
|
+
SimpleCov::Formatter::HTMLFormatter,
|
7
|
+
SimpleCov::Formatter::RcovFormatter,
|
8
|
+
]
|
9
|
+
|
10
|
+
SimpleCov.start do
|
11
|
+
add_filter 'test'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
1
15
|
require 'test/unit'
|
2
16
|
require 'digest/sha2'
|
3
17
|
require 'rubygems'
|
@@ -11,4 +25,15 @@ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
11
25
|
$:.unshift(File.dirname(__FILE__))
|
12
26
|
require 'attr_encrypted'
|
13
27
|
|
14
|
-
puts "\nTesting with ActiveRecord #{ActiveRecord::VERSION::STRING rescue ENV['ACTIVE_RECORD_VERSION']}"
|
28
|
+
puts "\nTesting with ActiveRecord #{ActiveRecord::VERSION::STRING rescue ENV['ACTIVE_RECORD_VERSION']}"
|
29
|
+
|
30
|
+
DB = Sequel.sqlite
|
31
|
+
|
32
|
+
# The :after_initialize hook was removed in Sequel 4.0
|
33
|
+
# and had been deprecated for a while before that:
|
34
|
+
# http://sequel.rubyforge.org/rdoc-plugins/classes/Sequel/Plugins/AfterInitialize.html
|
35
|
+
# This plugin re-enables it.
|
36
|
+
Sequel::Model.plugin :after_initialize
|
37
|
+
|
38
|
+
SECRET_KEY = 4.times.map { Digest::SHA256.hexdigest((Time.now.to_i * rand(5)).to_s) }.join
|
39
|
+
|
metadata
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attr_encrypted
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Sean Huber
|
9
|
+
- S. Brent Faulkner
|
10
|
+
- William Monk
|
9
11
|
autorequire:
|
10
12
|
bindir: bin
|
11
13
|
cert_chain: []
|
12
|
-
date:
|
14
|
+
date: 2013-11-14 00:00:00.000000000 Z
|
13
15
|
dependencies:
|
14
16
|
- !ruby/object:Gem::Dependency
|
15
17
|
name: encryptor
|
@@ -18,7 +20,7 @@ dependencies:
|
|
18
20
|
requirements:
|
19
21
|
- - ! '>='
|
20
22
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.
|
23
|
+
version: 1.3.0
|
22
24
|
type: :runtime
|
23
25
|
prerelease: false
|
24
26
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +28,7 @@ dependencies:
|
|
26
28
|
requirements:
|
27
29
|
- - ! '>='
|
28
30
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.
|
31
|
+
version: 1.3.0
|
30
32
|
- !ruby/object:Gem::Dependency
|
31
33
|
name: activerecord
|
32
34
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,8 +93,91 @@ dependencies:
|
|
91
93
|
- - ! '>='
|
92
94
|
- !ruby/object:Gem::Version
|
93
95
|
version: '0'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: sqlite3
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: dm-sqlite-adapter
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ! '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
type: :development
|
121
|
+
prerelease: false
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
- !ruby/object:Gem::Dependency
|
129
|
+
name: rake
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - '='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: 0.9.2.2
|
136
|
+
type: :development
|
137
|
+
prerelease: false
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - '='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: 0.9.2.2
|
144
|
+
- !ruby/object:Gem::Dependency
|
145
|
+
name: simplecov
|
146
|
+
requirement: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ! '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
none: false
|
156
|
+
requirements:
|
157
|
+
- - ! '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
- !ruby/object:Gem::Dependency
|
161
|
+
name: simplecov-rcov
|
162
|
+
requirement: !ruby/object:Gem::Requirement
|
163
|
+
none: false
|
164
|
+
requirements:
|
165
|
+
- - ! '>='
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
type: :development
|
169
|
+
prerelease: false
|
170
|
+
version_requirements: !ruby/object:Gem::Requirement
|
171
|
+
none: false
|
172
|
+
requirements:
|
173
|
+
- - ! '>='
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
94
176
|
description: Generates attr_accessors that encrypt and decrypt attributes transparently
|
95
|
-
email:
|
177
|
+
email:
|
178
|
+
- shuber@huberry.com
|
179
|
+
- sbfaulkner@gmail.com
|
180
|
+
- billy.monk@gmail.com
|
96
181
|
executables: []
|
97
182
|
extensions: []
|
98
183
|
extra_rdoc_files: []
|
@@ -107,10 +192,16 @@ files:
|
|
107
192
|
- README.rdoc
|
108
193
|
- test/active_record_test.rb
|
109
194
|
- test/attr_encrypted_test.rb
|
195
|
+
- test/compatibility_test.rb
|
110
196
|
- test/data_mapper_test.rb
|
197
|
+
- test/legacy_active_record_test.rb
|
198
|
+
- test/legacy_attr_encrypted_test.rb
|
199
|
+
- test/legacy_compatibility_test.rb
|
200
|
+
- test/legacy_data_mapper_test.rb
|
201
|
+
- test/legacy_sequel_test.rb
|
111
202
|
- test/sequel_test.rb
|
112
203
|
- test/test_helper.rb
|
113
|
-
homepage: http://github.com/
|
204
|
+
homepage: http://github.com/attr_encrypted/attr_encrypted
|
114
205
|
licenses: []
|
115
206
|
post_install_message:
|
116
207
|
rdoc_options:
|
@@ -126,12 +217,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
126
217
|
- - ! '>='
|
127
218
|
- !ruby/object:Gem::Version
|
128
219
|
version: '0'
|
220
|
+
segments:
|
221
|
+
- 0
|
222
|
+
hash: -52694865588709361
|
129
223
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
224
|
none: false
|
131
225
|
requirements:
|
132
226
|
- - ! '>='
|
133
227
|
- !ruby/object:Gem::Version
|
134
228
|
version: '0'
|
229
|
+
segments:
|
230
|
+
- 0
|
231
|
+
hash: -52694865588709361
|
135
232
|
requirements: []
|
136
233
|
rubyforge_project:
|
137
234
|
rubygems_version: 1.8.23
|
@@ -141,6 +238,12 @@ summary: Encrypt and decrypt attributes
|
|
141
238
|
test_files:
|
142
239
|
- test/active_record_test.rb
|
143
240
|
- test/attr_encrypted_test.rb
|
241
|
+
- test/compatibility_test.rb
|
144
242
|
- test/data_mapper_test.rb
|
243
|
+
- test/legacy_active_record_test.rb
|
244
|
+
- test/legacy_attr_encrypted_test.rb
|
245
|
+
- test/legacy_compatibility_test.rb
|
246
|
+
- test/legacy_data_mapper_test.rb
|
247
|
+
- test/legacy_sequel_test.rb
|
145
248
|
- test/sequel_test.rb
|
146
249
|
- test/test_helper.rb
|