veneer 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +12 -1
  3. data/README.md +55 -87
  4. data/Rakefile +1 -1
  5. data/lib/veneer.rb +6 -1
  6. data/lib/veneer/adapters/activerecord.rb +2 -0
  7. data/lib/veneer/adapters/activerecord/class_wrapper.rb +99 -5
  8. data/lib/veneer/adapters/activerecord/instance_wrapper.rb +4 -2
  9. data/lib/veneer/adapters/activerecord/pre_3.0_class_wrapper.rb +62 -1
  10. data/lib/veneer/adapters/activerecord/property.rb +22 -0
  11. data/lib/veneer/adapters/datamapper.rb +1 -0
  12. data/lib/veneer/adapters/datamapper/class_wrapper.rb +90 -6
  13. data/lib/veneer/adapters/datamapper/property.rb +25 -0
  14. data/lib/veneer/adapters/mongomapper.rb +1 -0
  15. data/lib/veneer/adapters/mongomapper/class_wrapper.rb +68 -0
  16. data/lib/veneer/adapters/mongomapper/property.rb +16 -0
  17. data/lib/veneer/base/class_wrapper.rb +110 -7
  18. data/lib/veneer/base/property.rb +27 -0
  19. data/lib/veneer/lint.rb +4 -180
  20. data/lib/veneer/lint/adapter.rb +282 -0
  21. data/lib/veneer/lint/base.rb +10 -0
  22. data/lib/veneer/lint/properties.rb +78 -0
  23. data/lib/veneer/version.rb +1 -1
  24. data/test/support/helpers.rb +10 -1
  25. data/test/test_helper.rb +3 -3
  26. data/test/veneer/activerecord/test_adapter.rb +80 -0
  27. data/test/veneer/activerecord/test_properties.rb +73 -0
  28. data/test/veneer/datamapper/test_adapter.rb +71 -0
  29. data/test/veneer/datamapper/test_properties.rb +59 -0
  30. data/test/veneer/{adapters/test_mongomapper.rb → mongomapper/test_adapter.rb} +35 -11
  31. data/test/veneer/mongomapper/test_properties.rb +56 -0
  32. data/test/veneer_test.rb +35 -0
  33. data/veneer.gemspec +2 -0
  34. metadata +57 -51
  35. data/test/veneer/adapters/test_active_record.rb +0 -56
  36. data/test/veneer/adapters/test_datamapper.rb +0 -56
@@ -0,0 +1,10 @@
1
+ module Veneer
2
+ module Lint
3
+ module Base
4
+ def test_should_setup_the_veneer_lint_class_wrapper_with_a_klass
5
+ assert_not_nil @klass, "@klass should provide a class to test Veneer with"
6
+ assert_kind_of Class, @klass
7
+ end
8
+ end
9
+ end
10
+ end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Veneer
2
- VERSION = "0.2.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -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
@@ -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__), "support", "**/*.rb")].each{|f| require f}
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__), "..", "..", "test_helper")
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
- validate_on_create :check_name
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 MongoMapperVeneerTest < ::Test::Unit::TestCase
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
- end
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