veneer 0.2.0 → 0.4.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.
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