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
@@ -1,33 +1,64 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
3
-
4
- describe DataMapper::Types::Flag do
5
- before(:all) do
6
- class ::Shirt
7
- include DataMapper::Resource
8
- property :id, Serial
9
- property :sizes, DM::Flag[:xs, :small, :medium, :large, :xl, :xxl]
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require 'spec/fixtures/tshirt'
6
+
7
+ describe DataMapper::Types::Fixtures::TShirt do
8
+ before do
9
+ @resource = DataMapper::Types::Fixtures::TShirt.new(
10
+ :writing => 'Fork you',
11
+ :has_picture => true,
12
+ :picture => :octocat,
13
+ :color => :white,
14
+ :size => [ :xs, :medium ]
15
+ )
10
16
  end
11
- Shirt.auto_migrate!
12
- end
13
17
 
14
- it "should save with create({:flag_field => [:flags]})" do
15
- lambda { Shirt.create(:sizes => [:medium, :large]) }.should_not raise_error
16
- repository do
17
- Shirt.get(1).sizes.should == [:medium, :large]
18
+ describe 'with multiple sizes' do
19
+ describe 'dumped and loaded' do
20
+ before do
21
+ @resource.save.should be_true
22
+ @resource.reload
23
+ end
24
+
25
+ it 'returns size as array' do
26
+ @resource.size.should == [ :xs, :medium ]
27
+ end
28
+ end
18
29
  end
19
- end
20
30
 
21
- it "should save with flag_field=[:flags]" do
22
- shirt = Shirt.new
23
- shirt.sizes = [:small, :xs]
24
- lambda { shirt.save }.should_not raise_error
25
- repository do
26
- Shirt.get(2).sizes.should == [:xs, :small]
31
+ describe 'with a single size' do
32
+ before do
33
+ @resource.size = :large
34
+ end
35
+
36
+ describe 'dumped and loaded' do
37
+ before do
38
+ @resource.save.should be_true
39
+ @resource.reload
40
+ end
41
+
42
+ it 'returns size as array with a single value' do
43
+ @resource.size.should == [:large]
44
+ end
45
+ end
27
46
  end
28
- end
29
47
 
30
- it 'should immediately typecast supplied values' do
31
- Shirt.new(:sizes => [:large, :xl]).sizes.should == [:large, :xl]
48
+ # Flag does not add any auto validations
49
+ describe 'without size' do
50
+ before do
51
+ @resource.should be_valid
52
+ @resource.size = nil
53
+ end
54
+
55
+ it 'is valid' do
56
+ @resource.should be_valid
57
+ end
58
+
59
+ it 'has no errors' do
60
+ @resource.errors.should be_blank
61
+ end
62
+ end
32
63
  end
33
64
  end
@@ -1,26 +1,151 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
- describe DataMapper::Types::IPAddress do
5
- before(:all) do
6
- class ::IPAddressTest
7
- include DataMapper::Resource
3
+ module IPAddressMatchers
4
+ def run_ipv6
5
+ simple_matcher('run IPv6') { |model| model.runs_ipv6? }
6
+ end
8
7
 
9
- property :id, Serial
10
- property :ip, IPAddress
11
- end
12
- IPAddressTest.auto_migrate!
8
+ def run_ipv4
9
+ simple_matcher('run IPv4') { |model| model.runs_ipv4? }
13
10
  end
11
+ end
12
+
13
+ try_spec do
14
+
15
+ require 'spec/fixtures/network_node'
14
16
 
15
- it "should work" do
16
- repository(:default) do
17
- IPAddressTest.create(:ip => '127.0.0.1')
17
+ describe DataMapper::Types::Fixtures::NetworkNode do
18
+ before :all do
19
+ @resource = DataMapper::Types::Fixtures::NetworkNode.new(
20
+ :node_uuid => '25a44800-21c9-11de-8c30-0800200c9a66',
21
+ :ip_address => nil,
22
+ :cidr_subnet_bits => nil
23
+ )
18
24
  end
19
25
 
20
- IPAddressTest.first.ip.should == IPAddr.new('127.0.0.1')
21
- end
26
+ include IPAddressMatchers
27
+
28
+ describe 'with IP address fe80::ab8:e8ff:fed7:f8c9' do
29
+ before :all do
30
+ @resource.ip_address = 'fe80::ab8:e8ff:fed7:f8c9'
31
+ end
32
+
33
+ describe 'when dumped and loaded' do
34
+ before :all do
35
+ @resource.save.should be_true
36
+ @resource.reload
37
+ end
38
+
39
+ it 'is an IPv6 node' do
40
+ @resource.should run_ipv6
41
+ end
42
+ end
43
+ end
44
+
45
+ describe 'with IP address 127.0.0.1' do
46
+ before :all do
47
+ @resource.ip_address = '127.0.0.1'
48
+ end
49
+
50
+ describe 'when dumped and loaded' do
51
+ before :all do
52
+ @resource.save.should be_true
53
+ @resource.reload
54
+ end
55
+
56
+ it 'is an IPv4 node' do
57
+ @resource.should run_ipv4
58
+ end
59
+ end
60
+ end
61
+
62
+ describe 'with IP address 218.43.243.136' do
63
+ before :all do
64
+ @resource.ip_address = '218.43.243.136'
65
+ end
66
+
67
+ describe 'when dumped and loaded' do
68
+ before :all do
69
+ @resource.save.should be_true
70
+ @resource.reload
71
+ end
72
+
73
+ it 'is an IPv4 node' do
74
+ @resource.should run_ipv4
75
+ end
76
+ end
77
+ end
78
+
79
+ describe 'with IP address 221.186.184.68' do
80
+ before :all do
81
+ @resource.ip_address = '221.186.184.68'
82
+ end
83
+
84
+ describe 'when dumped and loaded' do
85
+ before :all do
86
+ @resource.save.should be_true
87
+ @resource.reload
88
+ end
89
+
90
+ it 'is an IPv4 node' do
91
+ @resource.should run_ipv4
92
+ end
93
+ end
94
+ end
22
95
 
23
- it 'should immediately typecast supplied values' do
24
- IPAddressTest.new(:ip => '10.0.0.1').ip.should == IPAddr.new('10.0.0.1')
96
+ describe 'with IP address given as CIDR' do
97
+ before :all do
98
+ @resource.ip_address = '218.43.243.0/24'
99
+ end
100
+
101
+ describe 'when dumped and loaded' do
102
+ before :all do
103
+ @resource.save.should be_true
104
+ @resource.reload
105
+ end
106
+
107
+ it 'is an IPv4 node' do
108
+ @resource.should run_ipv4
109
+ end
110
+
111
+ it 'includes IP address 218.43.243.2 in subnet hosts' do
112
+ @resource.ip_address.include?('218.43.243.2')
113
+ end
114
+ end
115
+ end
116
+
117
+ describe 'with a blank string used as IP address' do
118
+ before :all do
119
+ @resource.ip_address = ''
120
+ end
121
+
122
+ describe 'when dumped and loaded' do
123
+ before :all do
124
+ @resource.save.should be_true
125
+ @resource.reload
126
+ end
127
+
128
+ it 'has NO IP address' do
129
+ @resource.ip_address.should be_nil
130
+ end
131
+ end
132
+ end
133
+
134
+ describe 'with NO IP address' do
135
+ before :all do
136
+ @resource.ip_address = nil
137
+ end
138
+
139
+ describe 'when dumped and loaded' do
140
+ before :all do
141
+ @resource.save.should be_true
142
+ @resource.reload
143
+ end
144
+
145
+ it 'has no IP address assigned' do
146
+ @resource.ip_address.should be_nil
147
+ end
148
+ end
149
+ end
25
150
  end
26
151
  end
@@ -1,26 +1,69 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
- describe DataMapper::Types::Json do
5
- before(:all) do
6
- class ::JsonTest
7
- include DataMapper::Resource
3
+ try_spec do
8
4
 
9
- property :id, Serial
10
- property :json, Json
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 => 'Thomas Edison')
11
10
  end
12
- JsonTest.auto_migrate!
13
- end
14
11
 
15
- it "should work" do
16
- repository(:default) do
17
- JsonTest.create(:json => '[1, 2, 3]')
12
+ describe 'with no positions information' do
13
+ before :all do
14
+ @resource.positions = 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 nil positions list' do
24
+ @resource.positions.should be_nil
25
+ end
26
+ end
18
27
  end
19
28
 
20
- JsonTest.first.json.should == [1, 2, 3]
21
- end
29
+ describe 'with a few items on the positions list' do
30
+ before :all do
31
+ @resource.positions = [
32
+ { :company => 'The Death Star, Inc', :title => 'Light sabre engineer' },
33
+ { :company => 'Sane Little Company', :title => 'Chief Curiosity Officer' },
34
+ ]
35
+ end
36
+
37
+ describe 'when dumped and loaded again' do
38
+ before :all do
39
+ @resource.save.should be_true
40
+ @resource.reload
41
+ end
22
42
 
23
- it 'should immediately typecast supplied values' do
24
- JsonTest.new(:json => '[1, 2, 3]').json.should == [1, 2, 3]
43
+ it 'loads positions list to the state when it was dumped/persisted with keys being strings' do
44
+ @resource.positions.should == [
45
+ { 'company' => 'The Death Star, Inc', 'title' => 'Light sabre engineer' },
46
+ { 'company' => 'Sane Little Company', 'title' => 'Chief Curiosity Officer' },
47
+ ]
48
+ end
49
+ end
50
+ end
51
+
52
+ describe 'with positions information given as empty list' do
53
+ before :all do
54
+ @resource.positions = []
55
+ end
56
+
57
+ describe 'when dumped and loaded again' do
58
+ before :all do
59
+ @resource.save.should be_true
60
+ @resource.reload
61
+ end
62
+
63
+ it 'has empty positions list' do
64
+ @resource.positions.should == []
65
+ end
66
+ end
67
+ end
25
68
  end
26
69
  end
@@ -1,56 +1,55 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'pathname'
4
- require 'iconv'
5
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
3
+ require 'spec_helper'
6
4
 
7
- describe DataMapper::Types::Slug do
5
+ try_spec do
8
6
 
9
- before(:all) do
10
- class ::SlugTest
11
- include DataMapper::Resource
7
+ require 'spec/fixtures/article'
12
8
 
13
- property :id, Serial
14
- property :name, Slug
9
+ describe DataMapper::Types::Fixtures::Article do
10
+ describe "persisted with title and slug set to 'New DataMapper Type'" do
11
+ before :all do
12
+ @input = 'New DataMapper Type'
13
+ @resource = DataMapper::Types::Fixtures::Article.create(:title => @input, :slug => @input)
15
14
 
16
- end
17
- SlugTest.auto_migrate!
18
- end
19
-
20
- it "should create the permalink" do
21
- repository(:default) do
22
- SlugTest.create(:name => 'New DataMapper Type')
23
- end
15
+ @resource.reload
16
+ end
24
17
 
25
- SlugTest.first.name.should == "new-datamapper-type"
26
- end
18
+ it 'has slug equal to "new-datamapper-type"' do
19
+ @resource.slug.should == 'new-datamapper-type'
20
+ end
27
21
 
28
- it "should find by a slug" do
29
- repository(:default) do
30
- SlugTest.create(:name => "This Should Be a Slug")
22
+ it 'can be found by slug' do
23
+ DataMapper::Types::Fixtures::Article.first(:slug => 'new-datamapper-type').should == @resource
24
+ end
31
25
  end
32
- slug = "this-should-be-a-slug"
33
26
 
34
- slugged = SlugTest.first(:name => slug)
35
- slugged.should_not be_nil
36
- slugged.name.should == slug
37
- end
27
+ [
28
+ ['Iñtërnâtiônàlizætiøn', 'internationalizaetion' ],
29
+ ["This is Dan's Blog", 'this-is-dans-blog'],
30
+ ['This is My Site, and Blog', 'this-is-my-site-and-blog'],
31
+ ['Google searches for holy grail of Python performance', 'google-searches-for-holy-grail-of-python-performance'],
32
+ ['iPhone dev: Creating length-controlled data sources', 'iphone-dev-creating-length-controlled-data-sources'],
33
+ ["Review: Nintendo's New DSi -- A Quantum Leap Forward", 'review-nintendos-new-dsi-a-quantum-leap-forward'],
34
+ ["Arriva BraiVe, è l'auto-robot che si 'guida' da sola'", 'arriva-braive-e-lauto-robot-che-si-guida-da-sola'],
35
+ ["La ley antipiratería reduce un 33% el tráfico online en Suecia", 'la-ley-antipirateria-reduce-un-33-percent-el-trafico-online-en-suecia'],
36
+ ["L'Etat américain du Texas s'apprête à interdire Windows Vista", 'letat-americain-du-texas-sapprete-a-interdire-windows-vista']
37
+ ].each do |title, slug|
38
+ describe "persisted with title '#{title}'" do
39
+ before :all do
40
+ @resource = DataMapper::Types::Fixtures::Article.new(:title => title)
41
+ @resource.save.should be_true
42
+ @resource.reload
43
+ end
38
44
 
39
- [
40
- ["Iñtërnâtiônàlizætiøn", "internationalizaetion" ],
41
- ["Hello World", "hello-world"],
42
- ["This is Dan's Blog", "this-is-dans-blog"],
43
- ["This is My Site, and Blog", "this-is-my-site-and-blog"]
44
- ].each do |name, slug|
45
+ it "has slug equal to '#{slug}'" do
46
+ @resource.slug.should == slug
47
+ end
45
48
 
46
- it "should sluggify #{name}" do
47
- repository(:default) do
48
- SlugTest.create(:name => name)
49
+ it 'can be found by slug' do
50
+ DataMapper::Types::Fixtures::Article.first(:slug => slug).should == @resource
49
51
  end
50
- SlugTest.first(:name => slug).should_not be_nil
51
52
  end
52
53
  end
53
-
54
-
55
-
54
+ end
56
55
  end
@@ -1,31 +1,136 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
- describe DataMapper::Types::URI do
5
- before(:all) do
6
- class ::URITest
7
- include DataMapper::Resource
3
+ try_spec do
8
4
 
9
- property :id, Integer, :serial => true
10
- property :uri, DM::URI
5
+ require 'spec/fixtures/bookmark'
6
+
7
+ describe DataMapper::Types::Fixtures::Bookmark do
8
+ describe 'without URI' do
9
+ before :all do
10
+ @uri = nil
11
+ @resource = DataMapper::Types::Fixtures::Bookmark.new(
12
+ :title => 'Check this out',
13
+ :uri => @uri,
14
+ :shared => false,
15
+ :tags => %w[ misc ]
16
+ )
17
+
18
+ @resource.save.should be_true
19
+ end
20
+
21
+ it 'can be found by uri' do
22
+ DataMapper::Types::Fixtures::Bookmark.first(:uri => @uri).should == @resource
23
+ end
24
+
25
+ describe 'when reloaded' do
26
+ before :all do
27
+ @resource.reload
28
+ end
29
+
30
+ it 'has no uri' do
31
+ @resource.uri.should be_nil
32
+ end
33
+ end
11
34
  end
12
- URITest.auto_migrate!
13
- end
14
35
 
15
- it "should work" do
16
- repository(:default) do
17
- URITest.create(:uri => 'http://localhost')
36
+ describe 'with a blank URI' do
37
+ before :all do
38
+ @uri = ''
39
+ @resource = DataMapper::Types::Fixtures::Bookmark.new(
40
+ :title => 'Check this out',
41
+ :uri => @uri,
42
+ :shared => false,
43
+ :tags => %w[ misc ]
44
+ )
45
+
46
+ @resource.save.should be_true
47
+ end
48
+
49
+ it 'can be found by uri' do
50
+ DataMapper::Types::Fixtures::Bookmark.first(:uri => @uri).should == @resource
51
+ end
52
+
53
+ describe 'when reloaded' do
54
+ before :all do
55
+ @resource.reload
56
+ end
57
+
58
+ it 'is loaded as URI object' do
59
+ @resource.uri.should be_an_instance_of(Addressable::URI)
60
+ end
61
+
62
+ it 'has the same original URI' do
63
+ @resource.uri.to_s.should == @uri
64
+ end
65
+ end
18
66
  end
19
67
 
20
- URITest.first.uri.should == Addressable::URI.parse('http://localhost')
21
- end
68
+ describe 'with invalid URI' do
69
+ before :all do
70
+ @uri = 'this is def. not URI'
71
+ @resource = DataMapper::Types::Fixtures::Bookmark.new(
72
+ :title => 'Check this out',
73
+ :uri => @uri,
74
+ :shared => false,
75
+ :tags => %w[ misc ]
76
+ )
77
+ end
22
78
 
23
- it 'should immediately typecast supplied values' do
24
- URITest.new(:uri => 'http://localhost').uri.should == Addressable::URI.parse('http://localhost')
25
- end
79
+ it 'is perfectly valid (URI type does not provide auto validations)' do
80
+ @resource.save.should be_true
81
+ end
82
+ end
26
83
 
27
- it "should correctly typecast nil values" do
28
- URITest.new(:uri => nil).uri.should == nil
29
- end
84
+ %w[
85
+ http://apple.com
86
+ http://www.apple.com
87
+ http://apple.com/
88
+ http://apple.com/iphone
89
+ http://www.google.com/search?client=safari&rls=en-us&q=LED&ie=UTF-8&oe=UTF-8
90
+ http://books.google.com
91
+ http://books.google.com/
92
+ http://db2.clouds.megacorp.net:8080
93
+ https://github.com
94
+ https://github.com/
95
+ http://www.example.com:8088/never/ending/path/segments/
96
+ http://db2.clouds.megacorp.net:8080/resources/10
97
+ http://www.example.com:8088/never/ending/path/segments
98
+ http://books.google.com/books?id=uSUJ3VhH4BsC&printsec=frontcover&dq=subject:%22+Linguistics+%22&as_brr=3&ei=DAHPSbGQE5rEzATk1sShAQ&rview=1
99
+ http://books.google.com:80/books?uid=14472359158468915761&rview=1
100
+ http://books.google.com/books?id=Ar3-TXCYXUkC&printsec=frontcover&rview=1
101
+ http://books.google.com/books/vp6ae081e454d30f89b6bca94e0f96fc14.js
102
+ http://www.google.com/images/cleardot.gif
103
+ http://books.google.com:80/books?id=Ar3-TXCYXUkC&printsec=frontcover&rview=1#PPA5,M1
104
+ http://www.hulu.com/watch/64923/terminator-the-sarah-connor-chronicles-to-the-lighthouse
105
+ http://hulu.com:80/browse/popular/tv
106
+ http://www.hulu.com/watch/62475/the-simpsons-gone-maggie-gone#s-p1-so-i0
107
+ ].each do |uri|
108
+ describe "with URI set to '#{uri}'" do
109
+ before :all do
110
+ @resource = DataMapper::Types::Fixtures::Bookmark.new(
111
+ :title => 'Check this out',
112
+ :uri => uri,
113
+ :shared => false,
114
+ :tags => %w[ misc ]
115
+ )
30
116
 
117
+ @resource.save.should be_true
118
+ end
119
+
120
+ it 'can be found by uri' do
121
+ DataMapper::Types::Fixtures::Bookmark.first(:uri => uri).should_not be_blank
122
+ end
123
+
124
+ describe 'when reloaded' do
125
+ before :all do
126
+ @resource.reload
127
+ end
128
+
129
+ it 'has the same original URI' do
130
+ @resource.uri.to_s.should eql(uri)
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
31
136
  end