dm-types 0.9.11 → 0.10.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 (59) hide show
  1. data/{History.txt → History.rdoc} +5 -4
  2. data/LICENSE +16 -14
  3. data/Manifest.txt +13 -3
  4. data/{README.txt → README.rdoc} +0 -0
  5. data/Rakefile +3 -4
  6. data/TODO +74 -0
  7. data/lib/dm-types.rb +15 -18
  8. data/lib/dm-types/bcrypt_hash.rb +1 -4
  9. data/lib/dm-types/comma_separated_list.rb +31 -0
  10. data/lib/dm-types/csv.rb +12 -18
  11. data/lib/dm-types/enum.rb +18 -15
  12. data/lib/dm-types/epoch_time.rb +6 -11
  13. data/lib/dm-types/file_path.rb +5 -4
  14. data/lib/dm-types/flag.rb +14 -13
  15. data/lib/dm-types/ip_address.rb +1 -0
  16. data/lib/dm-types/json.rb +5 -11
  17. data/lib/dm-types/regexp.rb +2 -3
  18. data/lib/dm-types/slug.rb +8 -17
  19. data/lib/dm-types/uri.rb +8 -14
  20. data/lib/dm-types/uuid.rb +9 -15
  21. data/lib/dm-types/version.rb +1 -1
  22. data/lib/dm-types/yaml.rb +4 -3
  23. data/spec/fixtures/article.rb +39 -0
  24. data/spec/fixtures/bookmark.rb +27 -0
  25. data/spec/fixtures/invention.rb +9 -0
  26. data/spec/fixtures/network_node.rb +40 -0
  27. data/spec/fixtures/person.rb +29 -0
  28. data/spec/fixtures/software_package.rb +37 -0
  29. data/spec/fixtures/ticket.rb +25 -0
  30. data/spec/fixtures/tshirt.rb +28 -0
  31. data/spec/integration/bcrypt_hash_spec.rb +37 -55
  32. data/spec/integration/comma_separated_list_spec.rb +89 -0
  33. data/spec/integration/enum_spec.rb +62 -42
  34. data/spec/integration/file_path_spec.rb +149 -17
  35. data/spec/integration/flag_spec.rb +56 -25
  36. data/spec/integration/ip_address_spec.rb +142 -17
  37. data/spec/integration/json_spec.rb +60 -17
  38. data/spec/integration/slug_spec.rb +39 -40
  39. data/spec/integration/uri_spec.rb +126 -21
  40. data/spec/integration/uuid_spec.rb +84 -30
  41. data/spec/integration/yaml_spec.rb +55 -25
  42. data/spec/shared/identity_function_group.rb +5 -0
  43. data/spec/spec.opts +1 -0
  44. data/spec/spec_helper.rb +49 -17
  45. data/spec/unit/bcrypt_hash_spec.rb +107 -64
  46. data/spec/unit/csv_spec.rb +111 -27
  47. data/spec/unit/enum_spec.rb +128 -87
  48. data/spec/unit/epoch_time_spec.rb +57 -32
  49. data/spec/unit/file_path_spec.rb +55 -34
  50. data/spec/unit/flag_spec.rb +102 -65
  51. data/spec/unit/ip_address_spec.rb +90 -40
  52. data/spec/unit/json_spec.rb +108 -41
  53. data/spec/unit/regexp_spec.rb +47 -17
  54. data/spec/unit/uri_spec.rb +57 -46
  55. data/spec/unit/yaml_spec.rb +91 -45
  56. data/tasks/install.rb +1 -1
  57. data/tasks/spec.rb +4 -4
  58. metadata +25 -32
  59. data/lib/dm-types/serial.rb +0 -8
@@ -0,0 +1,25 @@
1
+ module DataMapper
2
+ module Types
3
+ module Fixtures
4
+ class Ticket
5
+ #
6
+ # Behaviors
7
+ #
8
+
9
+ include DataMapper::Resource
10
+ include DataMapper::Validate
11
+
12
+ #
13
+ # Properties
14
+ #
15
+
16
+ property :id, Serial
17
+ property :title, String, :length => 255
18
+ property :body, Text
19
+ property :status, Enum[:unconfirmed, :confirmed, :assigned, :resolved, :not_applicable]
20
+
21
+ auto_migrate!
22
+ end # Ticket
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ module DataMapper
2
+ module Types
3
+ module Fixtures
4
+
5
+ class TShirt
6
+ #
7
+ # Behaviors
8
+ #
9
+
10
+ include ::DataMapper::Resource
11
+
12
+ #
13
+ # Properties
14
+ #
15
+
16
+ property :id, Serial
17
+ property :writing, String
18
+ property :has_picture, Boolean, :default => false
19
+ property :picture, Enum[:octocat, :fork_you, :git_down]
20
+
21
+ property :color, Enum[:white, :black, :red, :orange, :yellow, :green, :cyan, :blue, :purple]
22
+ property :size, Flag[:xs, :small, :medium, :large, :xl, :xxl]
23
+
24
+ auto_migrate!
25
+ end # Shirt
26
+ end # Fixtures
27
+ end # Types
28
+ end # DataMapper
@@ -1,59 +1,41 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
3
-
4
- begin
5
- gem 'bcrypt-ruby', '~>2.0.5'
6
- require 'bcrypt'
7
- rescue LoadError
8
- skip_tests = true
9
- end
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require 'spec/fixtures/person'
6
+
7
+ describe DataMapper::Types::Fixtures::Person do
8
+ before :all do
9
+ @resource = DataMapper::Types::Fixtures::Person.create(:password => 'DataMapper R0cks!')
10
+ DataMapper::Types::Fixtures::Person.create(:password => 'password1')
11
+
12
+ @people = DataMapper::Types::Fixtures::Person.all
13
+ @resource.reload
14
+ end
15
+
16
+ it 'persists the password on initial save' do
17
+ @resource.password.should == 'DataMapper R0cks!'
18
+ @people.last.password.should == 'password1'
19
+ end
20
+
21
+ it 'recalculates password hash on attribute update' do
22
+ @resource.attribute_set(:password, 'bcryptic obscure')
23
+ @resource.save
24
+
25
+ @resource.reload
26
+ @resource.password.should == 'bcryptic obscure'
27
+ @resource.password.should_not == 'DataMapper R0cks!'
28
+ end
29
+
30
+ it 'does not change password value on reload' do
31
+ resource = @people.last
32
+ original = resource.password.to_s
33
+ resource.reload
34
+ resource.password.to_s.should == original
35
+ end
10
36
 
11
- describe 'DataMapper::Types::BCryptHash' do
12
- unless skip_tests
13
- describe "with no options" do
14
- before(:each) do
15
- class User
16
- include DataMapper::Resource
17
-
18
- property :id, Serial
19
- property :password, BCryptHash
20
- end
21
- User.auto_migrate!
22
- User.create(:password => "DataMapper R0cks!")
23
- end
24
-
25
- it "should save a password to the DB on creation" do
26
- repository(:default) do
27
- User.create(:password => "password1")
28
- end
29
- user = User.all
30
- user[0].password.should == "DataMapper R0cks!"
31
- user[1].password.should == "password1"
32
- end
33
-
34
- it "should change the password on attribute update" do
35
- @user = User.first
36
- @user.attribute_set(:password, "D@t@Mapper R0cks!")
37
- @user.save
38
- @user.password.should_not == "DataMapper R0cks!"
39
- @user.password.should == "D@t@Mapper R0cks!"
40
- end
41
-
42
- it "should not change the password on save and reload" do
43
- @user = User.first
44
- v1 = @user.password.to_s
45
- @user.save
46
- @user.reload
47
- v2 = @user.password.to_s
48
- v1.should == v2
49
- end
50
-
51
- it "should have a cost of BCrypt::Engine::DEFAULT_COST" do
52
- @user = User.first
53
- @user.password.cost.should == BCrypt::Engine::DEFAULT_COST
54
- end
37
+ it 'uses cost of BCrypt::Engine::DEFAULT_COST' do
38
+ @resource.password.cost.should == BCrypt::Engine::DEFAULT_COST
55
39
  end
56
- else
57
- it "Needs the bcrypt-ruby gem installed"
58
40
  end
59
41
  end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require 'spec/fixtures/person'
6
+
7
+ describe DataMapper::Types::Fixtures::Person do
8
+ before :all do
9
+ @resource = DataMapper::Types::Fixtures::Person.new(:name => '')
10
+ end
11
+
12
+ describe 'with no interests information' do
13
+ before :all do
14
+ @resource.interests = nil
15
+ end
16
+
17
+ describe 'when dumped and loaded again' do
18
+ before :all do
19
+ @resource.save.should be_true
20
+ @resource.reload
21
+ end
22
+
23
+ it 'has no interests' do
24
+ @resource.interests.should == nil
25
+ end
26
+ end
27
+ end
28
+
29
+ describe 'with no interests information' do
30
+ before :all do
31
+ @resource.interests = []
32
+ end
33
+
34
+ describe 'when dumped and loaded again' do
35
+ before :all do
36
+ @resource.save.should be_true
37
+ @resource.reload
38
+ end
39
+
40
+ it 'has empty interests list' do
41
+ @resource.interests.should == []
42
+ end
43
+ end
44
+ end
45
+
46
+ describe 'with interests information given as a Hash' do
47
+ it 'raises ArgumentError' do
48
+ lambda do
49
+ @resource.interests = { :hash => 'value' }
50
+ @resource.save
51
+ end.should raise_error(ArgumentError, /must be a string, an array or nil/)
52
+ end
53
+ end
54
+
55
+ describe 'with a few items on the interests list' do
56
+ before :all do
57
+ @input = 'fire, water, fire, a whole lot of other interesting things, ,,,'
58
+ @resource.interests = @input
59
+ end
60
+
61
+ describe 'when dumped and loaded again' do
62
+ before :all do
63
+ @resource.save.should be_true
64
+ @resource.reload
65
+ end
66
+
67
+ it 'includes "fire" in interests' do
68
+ @resource.interests.should include('fire')
69
+ end
70
+
71
+ it 'includes "water" in interests' do
72
+ @resource.interests.should include('water')
73
+ end
74
+
75
+ it 'includes "a whole lot of other interesting things" in interests' do
76
+ @resource.interests.should include('a whole lot of other interesting things')
77
+ end
78
+
79
+ it 'has blank entries removed' do
80
+ @resource.interests.any? { |i| i.blank? }.should be_false
81
+ end
82
+
83
+ it 'has duplicates removed' do
84
+ @resource.interests.select { |i| i == 'fire' }.size.should == 1
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -1,57 +1,77 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
- describe DataMapper::Types::Enum do
5
- before(:all) do
6
- class ::Bug
7
- include DataMapper::Resource
3
+ try_spec do
8
4
 
9
- property :id, Integer, :serial => true
10
- property :status, Enum[:crit, :warn, :info, :unknown]
5
+ require 'spec/fixtures/ticket'
6
+
7
+ describe DataMapper::Types::Fixtures::Ticket do
8
+ describe 'that is dumped and then loaded' do
9
+ before :all do
10
+ @resource = DataMapper::Types::Fixtures::Ticket.new(
11
+ :title => "Can't order by aggregated fields",
12
+ :id => 789,
13
+ :body => "I'm trying to use the aggregate method and sort the results by a summed field, but it doesn't work.",
14
+ :status => 'confirmed'
15
+ )
16
+
17
+ @resource.save.should be_true
18
+ @resource.reload
19
+ end
20
+
21
+ it 'preserves property value' do
22
+ @resource.status.should == :confirmed
23
+ end
11
24
  end
12
- Bug.auto_migrate!
13
- end
14
25
 
15
- it "should work" do
16
- repository(:default) do
17
- Bug.create(:status => :crit)
18
- Bug.create(:status => :warn)
26
+ describe 'that is supplied a matching enumeration value' do
27
+ before :all do
28
+ @resource = DataMapper::Types::Fixtures::Ticket.new(:status => :assigned)
29
+ end
30
+
31
+ it 'typecasts it for outside reader' do
32
+ @resource.status.should == :assigned
33
+ end
19
34
  end
20
35
 
21
- bugs = Bug.all
22
- bugs[0].status.should == :crit
23
- bugs[1].status.should == :warn
24
- end
36
+ describe '#get' do
37
+ before :all do
38
+ @resource = DataMapper::Types::Fixtures::Ticket.new(
39
+ :title => '"sudo make install" of drizzle fails because it tries to chown mysql',
40
+ :id => 257497,
41
+ :body => "Note that at the very least, there should be a check to see whether or not the user is created before chown'ing a file to the user.",
42
+ :status => 'confirmed'
43
+ )
44
+ @resource.save.should be_true
45
+ end
25
46
 
26
- it 'should immediately typecast supplied values' do
27
- Bug.new(:status => :crit).status.should == :crit
28
- end
47
+ it 'supports queries with equality operator on enumeration property' do
48
+ DataMapper::Types::Fixtures::Ticket.all(:status => :confirmed).
49
+ should include(@resource)
50
+ end
29
51
 
30
- describe "with finders" do
31
- before(:all) do
32
- @info = Bug.create(:status => :info)
33
- end
34
- it "should work with equality opeand" do
35
- Bug.all(:status => [:info, :unknown]).entries.should == [@info]
36
- end
37
- it "should work with inequality operand" do
38
- Bug.all(:status.not => [:crit, :warn]).entries.should == [@info]
52
+ it 'supports queries with inequality operator on enumeration property' do
53
+ DataMapper::Types::Fixtures::Ticket.all(:status.not => :confirmed).
54
+ should_not include(@resource)
55
+ end
39
56
  end
40
- end
41
57
 
42
- if defined?(Validate)
43
- describe 'with validation' do
44
- it "should accept crit status" do
45
- bug = Bug.new
46
- bug.status = :crit
47
- bug.should be_valid
58
+ describe 'with value unknown to enumeration property' do
59
+ before :all do
60
+ @resource = DataMapper::Types::Fixtures::Ticket.new(:status => :undecided)
61
+ end
62
+
63
+ # TODO: consider sharing shared spec exampels with dm-validations,
64
+ # which has 'invalid model' shared group
65
+ it 'is invalid (auto validation for :within kicks in)' do
66
+ @resource.should_not be_valid
67
+ end
68
+
69
+ it 'has errors' do
70
+ @resource.errors.should_not be_empty
48
71
  end
49
72
 
50
- it "should not accept blah status" do
51
- bug = Bug.new
52
- bug.status = :blah
53
- bug.should_not be_valid
54
- bug.errors.on(:status).should_not be_empty
73
+ it 'has a meaningful error message on invalid property' do
74
+ @resource.errors.on(:status).should include('Status must be one of unconfirmed, confirmed, assigned, resolved, not_applicable')
55
75
  end
56
76
  end
57
77
  end
@@ -1,26 +1,158 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
- describe DataMapper::Types::FilePath do
5
- before(:all) do
6
- class ::FilePathTest
7
- include DataMapper::Resource
3
+ try_spec do
8
4
 
9
- property :id, Integer, :serial => true
10
- property :path, FilePath
5
+ require 'spec/fixtures/software_package'
6
+
7
+ describe DataMapper::Types::Fixtures::SoftwarePackage do
8
+ describe 'with source path at /var/cache/apt/archives/linux-libc-dev_2.6.28-11.40_i386.deb' do
9
+ before :all do
10
+ @source_path = '/var/cache/apt/archives/linux-libc-dev_2.6.28-11.40_i386.deb'
11
+ @resource = DataMapper::Types::Fixtures::SoftwarePackage.new(:source_path => @source_path)
12
+ end
13
+
14
+ describe 'when is a new record' do
15
+ before :all do
16
+ end
17
+
18
+ it 'points to original path' do
19
+ @resource.source_path.to_s.should == @source_path
20
+ end
21
+
22
+ it 'responds to :directory?' do
23
+ @resource.source_path.should respond_to(:directory?)
24
+ end
25
+
26
+ it 'responds to :file?' do
27
+ @resource.source_path.should respond_to(:file?)
28
+ end
29
+
30
+ it 'responds to :dirname' do
31
+ @resource.source_path.should respond_to(:dirname)
32
+ end
33
+
34
+ it 'responds to :absolute?' do
35
+ @resource.source_path.should respond_to(:absolute?)
36
+ end
37
+
38
+ it 'responds to :readable?' do
39
+ @resource.source_path.should respond_to(:readable?)
40
+ end
41
+
42
+ it 'responds to :size' do
43
+ @resource.source_path.should respond_to(:size)
44
+ end
45
+ end
11
46
  end
12
- FilePathTest.auto_migrate!
13
- end
14
47
 
15
- it "should work" do
16
- repository(:default) do
17
- FilePathTest.create(:path => '/usr')
48
+ describe 'with destination path at /usr/local' do
49
+ before :all do
50
+ @destination_path = '/usr/local'
51
+ @resource = DataMapper::Types::Fixtures::SoftwarePackage.new(:destination_path => @destination_path)
52
+ end
53
+
54
+ describe 'when saved and reloaded' do
55
+ before :all do
56
+ @resource.save.should be_true
57
+ @resource.reload
58
+ end
59
+
60
+ it 'points to original path' do
61
+ @resource.destination_path.to_s.should == @destination_path
62
+ end
63
+
64
+ it 'responds to :directory?' do
65
+ @resource.destination_path.should respond_to(:directory?)
66
+ end
67
+
68
+ it 'responds to :file?' do
69
+ @resource.destination_path.should respond_to(:file?)
70
+ end
71
+
72
+ it 'responds to :dirname' do
73
+ @resource.destination_path.should respond_to(:dirname)
74
+ end
75
+
76
+ it 'responds to :absolute?' do
77
+ @resource.destination_path.should respond_to(:absolute?)
78
+ end
79
+
80
+ it 'responds to :readable?' do
81
+ @resource.destination_path.should respond_to(:readable?)
82
+ end
83
+
84
+ it 'responds to :size' do
85
+ @resource.destination_path.should respond_to(:size)
86
+ end
87
+ end
18
88
  end
19
89
 
20
- FilePathTest.first.path.should == Pathname.new('/usr')
21
- end
90
+ describe 'with no (nil) source path' do
91
+ before :all do
92
+ @source_path = nil
93
+ @resource = DataMapper::Types::Fixtures::SoftwarePackage.new(:source_path => @source_path)
94
+ end
95
+
96
+ describe 'when saved and reloaded' do
97
+ before :all do
98
+ @resource.save.should be_true
99
+ @resource.reload
100
+ end
101
+
102
+ it 'has nil source path' do
103
+ @resource.source_path.should be_nil
104
+ end
105
+ end
106
+ end
107
+
108
+ describe 'with a blank source path' do
109
+ before :all do
110
+ @source_path = ''
111
+ @resource = DataMapper::Types::Fixtures::SoftwarePackage.new(:source_path => @source_path)
112
+ end
113
+
114
+ describe 'when saved and reloaded' do
115
+ before :all do
116
+ @resource.save.should be_true
117
+ @resource.reload
118
+ end
22
119
 
23
- it 'should immediately typecast supplied values' do
24
- FilePathTest.new(:path => '/usr').path.should == Pathname.new('/usr')
120
+ it 'has nil source path' do
121
+ @resource.source_path.should be_nil
122
+ end
123
+ end
124
+ end
125
+
126
+ describe 'with a source path assigned to an empty array' do
127
+ before :all do
128
+ @source_path = []
129
+ @resource = DataMapper::Types::Fixtures::SoftwarePackage.new(:source_path => @source_path)
130
+ end
131
+
132
+ describe 'when saved and reloaded' do
133
+ before :all do
134
+ @resource.save.should be_true
135
+ @resource.reload
136
+ end
137
+
138
+ it 'has nil source path' do
139
+ @resource.source_path.should be_nil
140
+ end
141
+ end
142
+ end
143
+
144
+ describe 'with a source path assigned to a Hash' do
145
+ before :all do
146
+ @source_path = { :guitar => 'Joe Satriani' }
147
+ end
148
+
149
+ describe 'when instantiated' do
150
+ it 'raises an exception' do
151
+ lambda do
152
+ DataMapper::Types::Fixtures::SoftwarePackage.new(:source_path => @source_path)
153
+ end.should raise_error(TypeError)
154
+ end
155
+ end
156
+ end
25
157
  end
26
158
  end