veneer 0.2.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +12 -1
- data/README.md +55 -87
- data/Rakefile +1 -1
- data/lib/veneer.rb +6 -1
- data/lib/veneer/adapters/activerecord.rb +2 -0
- data/lib/veneer/adapters/activerecord/class_wrapper.rb +99 -5
- data/lib/veneer/adapters/activerecord/instance_wrapper.rb +4 -2
- data/lib/veneer/adapters/activerecord/pre_3.0_class_wrapper.rb +62 -1
- data/lib/veneer/adapters/activerecord/property.rb +22 -0
- data/lib/veneer/adapters/datamapper.rb +1 -0
- data/lib/veneer/adapters/datamapper/class_wrapper.rb +90 -6
- data/lib/veneer/adapters/datamapper/property.rb +25 -0
- data/lib/veneer/adapters/mongomapper.rb +1 -0
- data/lib/veneer/adapters/mongomapper/class_wrapper.rb +68 -0
- data/lib/veneer/adapters/mongomapper/property.rb +16 -0
- data/lib/veneer/base/class_wrapper.rb +110 -7
- data/lib/veneer/base/property.rb +27 -0
- data/lib/veneer/lint.rb +4 -180
- data/lib/veneer/lint/adapter.rb +282 -0
- data/lib/veneer/lint/base.rb +10 -0
- data/lib/veneer/lint/properties.rb +78 -0
- data/lib/veneer/version.rb +1 -1
- data/test/support/helpers.rb +10 -1
- data/test/test_helper.rb +3 -3
- data/test/veneer/activerecord/test_adapter.rb +80 -0
- data/test/veneer/activerecord/test_properties.rb +73 -0
- data/test/veneer/datamapper/test_adapter.rb +71 -0
- data/test/veneer/datamapper/test_properties.rb +59 -0
- data/test/veneer/{adapters/test_mongomapper.rb → mongomapper/test_adapter.rb} +35 -11
- data/test/veneer/mongomapper/test_properties.rb +56 -0
- data/test/veneer_test.rb +35 -0
- data/veneer.gemspec +2 -0
- metadata +57 -51
- data/test/veneer/adapters/test_active_record.rb +0 -56
- data/test/veneer/adapters/test_datamapper.rb +0 -56
@@ -0,0 +1,78 @@
|
|
1
|
+
module Veneer
|
2
|
+
module Lint
|
3
|
+
module Properties
|
4
|
+
include Veneer::Lint::Base
|
5
|
+
|
6
|
+
def test_should_setup_properties_mapping
|
7
|
+
assert_not_nil @properties_mapping
|
8
|
+
assert_kind_of Hash, @properties_mapping
|
9
|
+
@properties_mapping.each do |k, v|
|
10
|
+
assert_kind_of Symbol, k
|
11
|
+
assert_kind_of Class, v
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_setup_expected_primary_keys
|
16
|
+
assert_not_nil @primary_keys
|
17
|
+
assert_kind_of Array, @primary_keys
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_properties
|
21
|
+
result = Veneer(@klass).properties
|
22
|
+
assert result.kind_of?(Array)
|
23
|
+
assert result.size > 0
|
24
|
+
property = result.first
|
25
|
+
assert_kind_of Veneer::Base::Property, property
|
26
|
+
assert_kind_of Class, property.type
|
27
|
+
assert_kind_of Symbol, property.name
|
28
|
+
assert_not_nil property.primary?
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_primary_keys
|
32
|
+
wrapped = Veneer(@klass)
|
33
|
+
properties = wrapped.properties
|
34
|
+
primary_keys = wrapped.primary_keys
|
35
|
+
|
36
|
+
assert_equal @primary_keys, wrapped.primary_keys
|
37
|
+
|
38
|
+
|
39
|
+
desired_primary_keys = properties.select { |property| primary_keys.include? property.name }
|
40
|
+
assert_equal primary_keys.size, desired_primary_keys.size
|
41
|
+
|
42
|
+
desired_primary_keys.each { |key| assert key.primary? }
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_constraints
|
46
|
+
Veneer(@klass).properties.each do |property|
|
47
|
+
assert_not_nil property[:constraints]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_length
|
52
|
+
@properties_with_length.each do |name, length|
|
53
|
+
assert_equal length, property_by_name(name).constraints[:length], "Expected #{name}.length to be #{length}."
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_types_conversion
|
58
|
+
@properties_mapping.each do |name, expected_normalized_type|
|
59
|
+
assert_equal expected_normalized_type, property_by_name(name).type, "Expected #{name} to be #{expected_normalized_type}."
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_validations
|
64
|
+
@properties_with_validations.each do |name, validator_classes|
|
65
|
+
validators = Veneer(@klass).validators_on(name)
|
66
|
+
assert_equal validator_classes.size, validators.size
|
67
|
+
validators.zip(validator_classes).each do |validator, expected_class|
|
68
|
+
assert_kind_of expected_class, validator
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def property_by_name(name)
|
74
|
+
Veneer(@klass).properties.find { |prop| prop.name == name } or raise "Couldn't find property #{name}."
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/veneer/version.rb
CHANGED
data/test/support/helpers.rb
CHANGED
@@ -12,7 +12,16 @@ module Veneer
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
16
15
|
end # Helpers
|
16
|
+
|
17
|
+
module ActiveRecordHelper
|
18
|
+
class << self
|
19
|
+
def establish_connection
|
20
|
+
unless ::ActiveRecord::Base.connected?
|
21
|
+
::ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end # Migrations
|
25
|
+
end # ActiveRecordHelper
|
17
26
|
end # Test
|
18
27
|
end # Veneer
|
data/test/test_helper.rb
CHANGED
@@ -3,12 +3,12 @@ require 'test/unit'
|
|
3
3
|
require 'shoulda'
|
4
4
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
5
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
+
$LOAD_PATH.unshift(Dir.pwd)
|
6
7
|
|
8
|
+
require 'veneer'
|
7
9
|
require 'veneer/lint'
|
8
10
|
|
9
|
-
Dir[File.join(File.dirname(__FILE__),
|
10
|
-
|
11
|
-
require 'veneer'
|
11
|
+
Dir[File.join(File.dirname(__FILE__),"support", "**/*.rb")].each{|f| require f}
|
12
12
|
|
13
13
|
$validations = []
|
14
14
|
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', "..", "test_helper"))
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'active_record'
|
5
|
+
rescue LoadError
|
6
|
+
require 'activerecord'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'veneer/adapters/activerecord'
|
10
|
+
|
11
|
+
|
12
|
+
Veneer::Test::ActiveRecordHelper.establish_connection
|
13
|
+
|
14
|
+
class CreateActiveRecordFoo < ActiveRecord::Migration
|
15
|
+
|
16
|
+
def self.up
|
17
|
+
create_table :active_record_foos, :force => true do |t|
|
18
|
+
t.string :name
|
19
|
+
t.string :title
|
20
|
+
t.string :description
|
21
|
+
t.integer :integer_field
|
22
|
+
t.integer :order_field1
|
23
|
+
t.integer :belonger_id
|
24
|
+
t.text :text_field
|
25
|
+
t.float :float_field
|
26
|
+
t.decimal :decimal_field
|
27
|
+
t.datetime :datetime_field
|
28
|
+
t.timestamp :timestamp_field
|
29
|
+
t.time :time_field
|
30
|
+
t.datetime :datetime_field
|
31
|
+
t.date :date_field
|
32
|
+
t.binary :binary_field
|
33
|
+
t.boolean :boolean_field
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.down
|
38
|
+
drop_table :active_record_foos
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
CreateActiveRecordFoo.up
|
43
|
+
|
44
|
+
class ActiveRecordFoo < ActiveRecord::Base
|
45
|
+
has_many :items, :class_name => "ActiveRecordFoo", :foreign_key => 'belonger_id'
|
46
|
+
belongs_to :master, :class_name => "ActiveRecordFoo", :foreign_key => 'belonger_id'
|
47
|
+
|
48
|
+
validate :check_name
|
49
|
+
|
50
|
+
def self.veneer_spec_reset!
|
51
|
+
delete_all
|
52
|
+
end
|
53
|
+
|
54
|
+
def check_name
|
55
|
+
errors.add(:name, "Name cannot be 'invalid'") if name == "invalid"
|
56
|
+
end
|
57
|
+
|
58
|
+
def v_with_m_test
|
59
|
+
errors.add(:name, "Name cannot be v_with_m_test") if name == "v_with_m_test"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class ActiveRecordAdapterTest < ::Test::Unit::TestCase
|
64
|
+
include Veneer::Lint::Adapter
|
65
|
+
|
66
|
+
def setup
|
67
|
+
@klass = ::ActiveRecordFoo
|
68
|
+
@valid_attributes = {:name => "foo", :title => "title", :description => "description", :integer_field => 1}
|
69
|
+
@invalid_attributes = @valid_attributes.dup.merge(:name => "invalid")
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_valid_items(num)
|
73
|
+
attr = @valid_attributes
|
74
|
+
|
75
|
+
(1..num).each do |i|
|
76
|
+
ActiveRecordFoo.create(:name => "#{attr[:name]}#{i}", :title => "#{attr[:title]}#{i}", :description => "#{attr[:description]}#{i}", :integer_field => 1)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', "..", "test_helper"))
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'active_record'
|
5
|
+
rescue LoadError
|
6
|
+
require 'activerecord'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'veneer/adapters/activerecord'
|
10
|
+
|
11
|
+
|
12
|
+
Veneer::Test::ActiveRecordHelper.establish_connection
|
13
|
+
|
14
|
+
class CreateActiveRecordBar < ActiveRecord::Migration
|
15
|
+
def self.up
|
16
|
+
create_table :active_record_bars, :force => true do |t|
|
17
|
+
t.string :name
|
18
|
+
t.string :string_field
|
19
|
+
t.integer :integer_field
|
20
|
+
t.text :text_field
|
21
|
+
t.float :float_field
|
22
|
+
t.decimal :decimal_field, :precision => 5, :scale => 2
|
23
|
+
t.datetime :datetime_field
|
24
|
+
t.timestamp :timestamp_field
|
25
|
+
t.time :time_field
|
26
|
+
t.datetime :datetime_field
|
27
|
+
t.date :date_field
|
28
|
+
t.binary :binary_field
|
29
|
+
t.boolean :boolean_field
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.down
|
34
|
+
drop_table :active_record_bars
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
CreateActiveRecordBar.up
|
39
|
+
|
40
|
+
class ActiveRecordBar < ActiveRecord::Base
|
41
|
+
validates_presence_of :integer_field
|
42
|
+
end
|
43
|
+
|
44
|
+
class ActiveRecordPropertiesTest < ::Test::Unit::TestCase
|
45
|
+
include Veneer::Lint::Properties
|
46
|
+
|
47
|
+
def setup
|
48
|
+
@klass = ::ActiveRecordBar
|
49
|
+
@properties_mapping = {
|
50
|
+
:id => Integer,
|
51
|
+
:string_field => String,
|
52
|
+
:text_field => String,
|
53
|
+
:integer_field => Integer,
|
54
|
+
:float_field => Float,
|
55
|
+
:decimal_field => BigDecimal,
|
56
|
+
:datetime_field => DateTime,
|
57
|
+
:timestamp_field => DateTime,
|
58
|
+
:time_field => Time,
|
59
|
+
:date_field => Date,
|
60
|
+
:binary_field => StringIO,
|
61
|
+
:boolean_field => TrueClass
|
62
|
+
}
|
63
|
+
@primary_keys = [:id]
|
64
|
+
@properties_with_length = {
|
65
|
+
:string_field => 255,
|
66
|
+
:text_field => nil
|
67
|
+
|
68
|
+
}
|
69
|
+
@properties_with_validations = {
|
70
|
+
:integer_field => [ActiveModel::Validations::PresenceValidator]
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', "..", "test_helper"))
|
2
|
+
require 'dm-core'
|
3
|
+
require 'dm-migrations'
|
4
|
+
require 'dm-aggregates'
|
5
|
+
require 'veneer/adapters/datamapper'
|
6
|
+
|
7
|
+
DataMapper.setup(:default, 'sqlite3::memory:')
|
8
|
+
|
9
|
+
class DMFoo
|
10
|
+
include DataMapper::Resource
|
11
|
+
include ActiveModel::Validations
|
12
|
+
|
13
|
+
property :id, Serial
|
14
|
+
property :name, String
|
15
|
+
property :title, String
|
16
|
+
property :description, String
|
17
|
+
property :integer_field, Integer, :required => false
|
18
|
+
property :order_field1, Integer
|
19
|
+
property :item_id, Integer, :required => false
|
20
|
+
property :text_field, Text
|
21
|
+
property :float_field, Float
|
22
|
+
property :decimal_field, Decimal, :scale => 0, :precision => 10
|
23
|
+
property :datetime_field, DateTime
|
24
|
+
property :time_field, Time
|
25
|
+
property :date_field, Date
|
26
|
+
property :boolean_field, Boolean
|
27
|
+
property :object_field, Object
|
28
|
+
property :discriminator_field, Discriminator
|
29
|
+
|
30
|
+
validate :check_name
|
31
|
+
|
32
|
+
has n, :items, self, :child_key => [:item_id]
|
33
|
+
belongs_to :master, self, :child_key => [:item_id]
|
34
|
+
|
35
|
+
before :save do
|
36
|
+
throw :halt unless valid?
|
37
|
+
end
|
38
|
+
|
39
|
+
def check_name
|
40
|
+
errors.add(:base, "Invalid name") if name == "invalid"
|
41
|
+
end
|
42
|
+
|
43
|
+
def v_with_m_test
|
44
|
+
if name == "v_with_m_test"
|
45
|
+
[false, "name cannot be v_with_m_test"]
|
46
|
+
else
|
47
|
+
true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
DataMapper.auto_migrate!
|
53
|
+
|
54
|
+
class DataMapperAdapterTest < ::Test::Unit::TestCase
|
55
|
+
include Veneer::Lint::Adapter
|
56
|
+
|
57
|
+
def setup
|
58
|
+
@klass = ::DMFoo
|
59
|
+
@valid_attributes = {:name => "foo", :title => "title", :description => "description", :integer_field => 1}
|
60
|
+
@invalid_attributes = @valid_attributes.dup.merge(:name => "invalid")
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_valid_items(num)
|
64
|
+
attr = @valid_attributes
|
65
|
+
|
66
|
+
(1..num).each do |i|
|
67
|
+
DMFoo.create(:name => "#{attr[:name]}#{i}", :title => "#{attr[:title]}#{i}", :description => "#{attr[:description]}#{i}", :integer_field => 1)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', "..", "test_helper"))
|
2
|
+
require 'dm-core'
|
3
|
+
require 'dm-migrations'
|
4
|
+
require 'veneer/adapters/datamapper'
|
5
|
+
|
6
|
+
DataMapper.setup(:default, 'sqlite3::memory:')
|
7
|
+
|
8
|
+
class DMBar
|
9
|
+
include DataMapper::Resource
|
10
|
+
include ActiveModel::Validations
|
11
|
+
|
12
|
+
validates_presence_of :integer_field
|
13
|
+
|
14
|
+
property :id, Serial, :key => true
|
15
|
+
property :another_id, Integer, :key => true
|
16
|
+
property :string_field, String, :length => 255
|
17
|
+
property :integer_field, Integer
|
18
|
+
property :text_field, Text
|
19
|
+
property :float_field, Float
|
20
|
+
property :decimal_field, Decimal, :scale => 0, :precision => 10
|
21
|
+
property :datetime_field, DateTime
|
22
|
+
property :time_field, Time
|
23
|
+
property :date_field, Date
|
24
|
+
property :boolean_field, Boolean
|
25
|
+
property :object_field, Object
|
26
|
+
property :discriminator_field, Discriminator
|
27
|
+
end
|
28
|
+
|
29
|
+
DataMapper.auto_migrate!
|
30
|
+
|
31
|
+
class DataMapperPropertiesTest < ::Test::Unit::TestCase
|
32
|
+
include Veneer::Lint::Properties
|
33
|
+
|
34
|
+
def setup
|
35
|
+
@klass = ::DMBar
|
36
|
+
@properties_mapping = {
|
37
|
+
:id => Integer, #Serial,
|
38
|
+
:string_field => String,
|
39
|
+
:text_field => String,
|
40
|
+
:integer_field => Integer,
|
41
|
+
:float_field => Float,
|
42
|
+
:decimal_field => BigDecimal,
|
43
|
+
:datetime_field => DateTime,
|
44
|
+
:time_field => Time,
|
45
|
+
:date_field => Date,
|
46
|
+
:boolean_field => TrueClass,
|
47
|
+
:object_field => Object,
|
48
|
+
:discriminator_field => Class
|
49
|
+
}
|
50
|
+
@primary_keys = [:id, :another_id]
|
51
|
+
@properties_with_length = {
|
52
|
+
:string_field => 255,
|
53
|
+
:integer_field => nil
|
54
|
+
}
|
55
|
+
@properties_with_validations = {
|
56
|
+
:integer_field => [ActiveModel::Validations::PresenceValidator]
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__),
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', "..", "test_helper"))
|
2
2
|
require 'mongo_mapper'
|
3
3
|
|
4
4
|
require 'veneer/adapters/mongomapper'
|
@@ -13,9 +13,21 @@ class MongoFoo
|
|
13
13
|
key :name, String
|
14
14
|
key :title, String
|
15
15
|
key :description, String
|
16
|
+
key :integer_field, Integer
|
16
17
|
key :order_field1, Integer
|
18
|
+
key :float_field, Float
|
19
|
+
key :date_field, Date
|
20
|
+
key :boolean_field, Boolean
|
21
|
+
key :hash_field, Hash
|
22
|
+
key :set_field, Set
|
23
|
+
key :time_field, Time
|
24
|
+
key :object_field, Object
|
25
|
+
key :binary_field, Binary
|
17
26
|
|
18
|
-
|
27
|
+
validate :check_name, :on => :create
|
28
|
+
|
29
|
+
belongs_to :foo, :class_name => "MongoFoo"
|
30
|
+
many :foos, :class_name => "MongoFoo"
|
19
31
|
|
20
32
|
def check_name
|
21
33
|
errors.add(:name, "may not be invalid") if name == "invalid"
|
@@ -26,12 +38,12 @@ class MongoFoo
|
|
26
38
|
end
|
27
39
|
end
|
28
40
|
|
29
|
-
class
|
30
|
-
include Veneer::Lint
|
41
|
+
class MongoMapperAdapterTest < ::Test::Unit::TestCase
|
42
|
+
include Veneer::Lint::Adapter
|
31
43
|
|
32
44
|
def setup
|
33
45
|
@klass = ::MongoFoo
|
34
|
-
@valid_attributes = {:name => "foo", :title => "title", :description => "description"}
|
46
|
+
@valid_attributes = {:name => "foo", :title => "title", :description => "description", :integer_field => 1}
|
35
47
|
@invalid_attributes = @valid_attributes.dup.merge(:name => "invalid")
|
36
48
|
end
|
37
49
|
|
@@ -39,11 +51,23 @@ class MongoMapperVeneerTest < ::Test::Unit::TestCase
|
|
39
51
|
attr = @valid_attributes
|
40
52
|
|
41
53
|
(1..num).each do |i|
|
42
|
-
MongoFoo.create(:name => "#{attr[:name]}#{i}", :title => "#{attr[:title]}#{i}", :description => "#{attr[:description]}#{i}")
|
54
|
+
MongoFoo.create(:name => "#{attr[:name]}#{i}", :title => "#{attr[:title]}#{i}", :description => "#{attr[:description]}#{i}", :integer_field => 1)
|
43
55
|
end
|
44
56
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
57
|
+
|
58
|
+
def properties_mappings
|
59
|
+
{
|
60
|
+
:_id => String, #ObjectID
|
61
|
+
:name => String,
|
62
|
+
:integer_field => Integer,
|
63
|
+
:float_field => Float,
|
64
|
+
:date_field => Date,
|
65
|
+
:boolean_field => TrueClass,
|
66
|
+
:hash_field => Hash,
|
67
|
+
:set_field => Set,
|
68
|
+
:time_field => Time,
|
69
|
+
:object_field => Object,
|
70
|
+
:binary_field => StringIO
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|