dm-types 0.9.11 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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,46 +1,100 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
3
-
4
- begin
5
- gem 'uuidtools', '~>1.0.7'
6
- require 'uuidtools'
7
- rescue LoadError
8
- skip_tests = true
9
- end
1
+ require 'spec_helper'
2
+
3
+ try_spec do
4
+
5
+ require 'spec/fixtures/network_node'
6
+
7
+ describe DataMapper::Types::Fixtures::NetworkNode do
8
+ describe 'with UUID set as UUID object' do
9
+ before :all do
10
+ @uuid_string = 'b0fc632e-d744-4821-afe3-4ea0701859ee'
11
+ @uuid = UUIDTools::UUID.parse(@uuid_string)
12
+ @resource = DataMapper::Types::Fixtures::NetworkNode.new(:uuid => @uuid)
13
+
14
+ @resource.save.should be_true
15
+ end
16
+
17
+ describe 'when reloaded' do
18
+ before :all do
19
+ @resource.reload
20
+ end
21
+
22
+ it 'has the same UUID string' do
23
+ @resource.uuid.to_s.should == @uuid_string
24
+ end
10
25
 
11
- describe 'DataMapper::Types::UUID' do
12
- unless skip_tests
13
- before(:all) do
14
- class UUIDTest
15
- include DataMapper::Resource
26
+ it 'returns UUID as an object' do
27
+ @resource.uuid.should be_an_instance_of(UUIDTools::UUID)
28
+ end
29
+ end
30
+ end
16
31
 
17
- property :id, Serial
18
- property :uuid, ::DataMapper::Types::UUID
32
+ describe 'with UUID set as a valid UUID string' do
33
+ before :all do
34
+ @uuid = 'b0fc632e-d744-4821-afe3-4ea0701859ee'
35
+ @resource = DataMapper::Types::Fixtures::NetworkNode.new(:uuid => @uuid)
19
36
  end
20
37
 
21
- UUIDTest.auto_migrate!
38
+ describe 'when reloaded' do
39
+ before :all do
40
+ @resource.reload
41
+ end
42
+
43
+ it 'has the same UUID string' do
44
+ @resource.uuid.to_s.should == @uuid
45
+ end
46
+
47
+ it 'returns UUID as an object' do
48
+ @resource.uuid.should be_an_instance_of(UUIDTools::UUID)
49
+ end
50
+ end
22
51
  end
23
52
 
24
- it "should be settable as a uuid" do
25
- u = UUIDTest.create(:uuid => UUID.parse('b0fc632e-d744-4821-afe3-4ea0701859ee'))
53
+ describe 'with UUID set as invalid UUID string' do
54
+ before :all do
55
+ @uuid = 'meh'
56
+ @operation = lambda do
57
+ DataMapper::Types::Fixtures::NetworkNode.new(:uuid => @uuid)
58
+ end
59
+ end
26
60
 
27
- u.uuid.should be_kind_of(UUID)
28
- u.uuid.to_s.should == 'b0fc632e-d744-4821-afe3-4ea0701859ee'
61
+ describe 'when assigned UUID' do
62
+ it 'raises ArgumentError' do
63
+ @operation.should raise_error(ArgumentError, /Invalid UUID format/)
64
+ end
65
+ end
29
66
  end
30
67
 
31
- it "should be settable as a string" do
32
- u = UUIDTest.create(:uuid => 'b0fc632e-d744-4821-afe3-4ea0701859ee')
68
+ describe 'with UUID set as a blank string' do
69
+ before :all do
70
+ @uuid = ''
71
+ @operation = lambda do
72
+ DataMapper::Types::Fixtures::NetworkNode.new(:uuid => @uuid)
73
+ end
74
+ end
33
75
 
34
- u.uuid.should be_kind_of(UUID)
35
- u.uuid.to_s.should == 'b0fc632e-d744-4821-afe3-4ea0701859ee'
76
+ describe 'when assigned UUID' do
77
+ it 'raises ArgumentError' do
78
+ @operation.should raise_error(ArgumentError, /Invalid UUID format/)
79
+ end
80
+ end
36
81
  end
37
82
 
38
- it "should be allowed to be null" do
39
- u = UUIDTest.create()
83
+ describe 'with missing UUID' do
84
+ before :all do
85
+ @uuid = nil
86
+ @resource = DataMapper::Types::Fixtures::NetworkNode.new(:uuid => @uuid)
87
+ end
40
88
 
41
- u.uuid.should be_nil
89
+ describe 'when reloaded' do
90
+ before :all do
91
+ @resource.reload
92
+ end
93
+
94
+ it 'has no UUID' do
95
+ @resource.uuid.should be_nil
96
+ end
97
+ end
42
98
  end
43
- else
44
- it 'requires the uuidtools gem to test'
45
99
  end
46
100
  end
@@ -1,37 +1,67 @@
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 ::YamlTest
7
- include DataMapper::Resource
3
+ try_spec do
8
4
 
9
- property :id, Serial
10
- property :yaml, Yaml
5
+ require 'spec/fixtures/person'
6
+ require 'spec/fixtures/invention'
7
+
8
+ describe DataMapper::Types::Fixtures::Person do
9
+ before :all do
10
+ @resource = DataMapper::Types::Fixtures::Person.new(:name => '')
11
11
  end
12
- YamlTest.auto_migrate!
13
12
 
14
- class ::SerializeMe
15
- attr_accessor :name
13
+ describe 'with no inventions information' do
14
+ before :all do
15
+ @resource.inventions = nil
16
+ end
17
+
18
+ describe 'when dumped and loaded again' do
19
+ before :all do
20
+ @resource.save.should be_true
21
+ @resource.reload
22
+ end
23
+
24
+ it 'has nil inventions list' do
25
+ @resource.inventions.should be_nil
26
+ end
27
+ end
16
28
  end
17
- end
18
29
 
19
- it "should work" do
20
- obj = SerializeMe.new
21
- obj.name = 'Hello!'
30
+ describe 'with a few items on the inventions list' do
31
+ before :all do
32
+ @input = [ 'carbon telephone transmitter', 'light bulb', 'electric grid' ].map do |name|
33
+ DataMapper::Types::Fixtures::Invention.new(name)
34
+ end
35
+ @resource.inventions = @input
36
+ end
22
37
 
23
- repository(:default) do
24
- YamlTest.create(:yaml => [1, 2, 3])
25
- YamlTest.create(:yaml => obj)
38
+ describe 'when dumped and loaded again' do
39
+ before :all do
40
+ @resource.save.should be_true
41
+ @resource.reload
42
+ end
43
+
44
+ it 'loads inventions list to the state when it was dumped/persisted with keys being strings' do
45
+ @resource.inventions.should == @input
46
+ end
47
+ end
26
48
  end
27
49
 
28
- tests = YamlTest.all
29
- tests.first.yaml.should == [1, 2, 3]
30
- tests.last.yaml.should be_kind_of(SerializeMe)
31
- tests.last.yaml.name.should == 'Hello!'
32
- end
50
+ describe 'with inventions information given as empty list' do
51
+ before :all do
52
+ @resource.inventions = []
53
+ end
33
54
 
34
- it 'should immediately typecast supplied values' do
35
- YamlTest.new(:yaml => [1, 2, 3]).yaml.should == [1, 2, 3]
55
+ describe 'when dumped and loaded again' do
56
+ before :all do
57
+ @resource.save.should be_true
58
+ @resource.reload
59
+ end
60
+
61
+ it 'has empty inventions list' do
62
+ @resource.inventions.should == []
63
+ end
64
+ end
65
+ end
36
66
  end
37
67
  end
@@ -0,0 +1,5 @@
1
+ describe "identity function", :shared => true do
2
+ it "returns value unchanged" do
3
+ @result.should == @input
4
+ end
5
+ end
data/spec/spec.opts CHANGED
@@ -1 +1,2 @@
1
1
  --colour
2
+ --loadby random
data/spec/spec_helper.rb CHANGED
@@ -1,31 +1,63 @@
1
- require 'pathname'
2
1
  require 'rubygems'
3
2
 
4
- gem 'rspec', '~>1.2'
5
- require 'spec'
3
+ # TODO: autovalidation hooks are needed badly,
4
+ # otherwise plugin devs will have to abuse
5
+ # alising and load order even further and it kinda makes
6
+ # me sad -- MK
6
7
 
7
- require Pathname(__FILE__).dirname.parent.expand_path + 'lib/dm-types'
8
+ # use local dm-core if running from a typical dev checkout.
9
+ lib = File.join('..', '..', 'dm-core', 'lib')
10
+ $LOAD_PATH.unshift(lib) if File.directory?(lib)
11
+ require 'dm-core'
8
12
 
9
- ENV["SQLITE3_SPEC_URI"] ||= 'sqlite3::memory:'
10
- ENV["MYSQL_SPEC_URI"] ||= 'mysql://localhost/dm_core_test'
11
- ENV["POSTGRES_SPEC_URI"] ||= 'postgres://postgres@localhost/dm_more_test'
13
+ # use local dm-validations if running from a typical dev checkout.
14
+ lib = File.join('..', 'dm-validations', 'lib')
15
+ $LOAD_PATH.unshift(lib) if File.directory?(lib)
16
+ require 'dm-validations'
12
17
 
13
- # DataMapper::Logger.new(STDOUT, :debug)
18
+ # Support running specs with 'rake spec' and 'spec'
19
+ $LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
20
+
21
+ require 'dm-types'
22
+
23
+ def load_driver(name, default_uri)
24
+ return false if ENV['ADAPTER'] != name.to_s
14
25
 
15
- def setup_adapter(name, default_uri = nil)
16
26
  begin
17
- DataMapper.setup(name, ENV["#{ENV['ADAPTER'].to_s.upcase}_SPEC_URI"] || default_uri)
18
- Object.const_set('ADAPTER', ENV['ADAPTER'].to_sym) if name.to_s == ENV['ADAPTER']
27
+ DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
28
+ DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
19
29
  true
20
- rescue Exception => e
21
- if name.to_s == ENV['ADAPTER']
22
- Object.const_set('ADAPTER', nil)
23
- warn "Could not load do_#{name}: #{e}"
24
- end
30
+ rescue LoadError => e
31
+ warn "Could not load do_#{name}: #{e}"
25
32
  false
26
33
  end
27
34
  end
28
35
 
29
36
  ENV['ADAPTER'] ||= 'sqlite3'
30
37
 
31
- setup_adapter(:default)
38
+ HAS_SQLITE3 = load_driver(:sqlite3, 'sqlite3::memory:')
39
+ HAS_MYSQL = load_driver(:mysql, 'mysql://localhost/dm_core_test')
40
+ HAS_POSTGRES = load_driver(:postgres, 'postgres://postgres@localhost/dm_core_test')
41
+
42
+
43
+ DEPENDENCIES = {
44
+ 'bcrypt' => 'bcrypt-ruby',
45
+ 'fastercsv' => 'fastercsv',
46
+ 'json' => 'json',
47
+ 'stringex' => 'stringex',
48
+ 'uuidtools' => 'uuidtools',
49
+ }
50
+
51
+ def try_spec
52
+ begin
53
+ yield
54
+ rescue NameError
55
+ # do nothing
56
+ rescue LoadError => error
57
+ raise error unless lib = error.message.match(/\Ano such file to load -- (.+)\z/)[1]
58
+
59
+ gem_location = DEPENDENCIES[lib] || raise("Unknown lib #{lib}")
60
+
61
+ warn "[WARNING] Skipping specs using #{lib}, please do: gem install #{gem_location}"
62
+ end
63
+ end
@@ -1,104 +1,147 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.parent.expand_path + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
- include DataMapper::Types
5
-
6
- begin
7
- gem 'bcrypt-ruby', '~>2.0.5'
8
- require 'bcrypt'
9
- rescue LoadError
10
- skip_tests = true
11
- end
12
-
13
- describe "DataMapper::Types::BCryptHash" do
14
- unless skip_tests
15
-
16
- before(:each) do
17
- @clear_password = "DataMapper R0cks!"
3
+ try_spec do
4
+ describe DataMapper::Types::BCryptHash do
5
+ before :all do
6
+ @clear_password = 'DataMapper R0cks!'
18
7
  @crypted_password = BCrypt::Password.create(@clear_password)
8
+
19
9
  @nonstandard_type = 1
20
10
 
21
11
  class TestType
22
12
  @a = 1
23
- @b = "Hi There"
13
+ @b = 'Hi There'
24
14
  end
25
15
  @nonstandard_type2 = TestType.new
26
16
  end
27
17
 
28
- describe ".dump" do
29
- it "should return a crypted hash as a BCrypt::Password" do
30
- BCryptHash.dump(@clear_password, :property).should be_an_instance_of(BCrypt::Password)
31
- end
18
+ describe '.dump' do
19
+ describe 'when argument is a string' do
20
+ before :all do
21
+ @input = 'DataMapper'
22
+ @result = DataMapper::Types::BCryptHash.dump(@input, :property)
23
+ end
24
+
25
+ it 'returns instance of BCrypt::Password' do
26
+ @result.should be_an_instance_of(BCrypt::Password)
27
+ end
32
28
 
33
- it "should return a string that is 60 characters long" do
34
- BCryptHash.dump(@clear_password, :property).to_s.should have(60).characters
29
+ it 'returns a string that is 60 characters long' do
30
+ @result.should have(60).characters
31
+ end
35
32
  end
36
33
 
37
- it "should return nil if nil is passed" do
38
- BCryptHash.dump(nil, :property).should be_nil
34
+ describe 'when argument is nil' do
35
+ before :all do
36
+ @input = nil
37
+ @result = DataMapper::Types::BCryptHash.dump(@input, :property)
38
+ end
39
+
40
+ it 'returns nil' do
41
+ @result.should be_nil
42
+ end
39
43
  end
40
44
  end
41
45
 
42
- describe ".load" do
43
- it "should return the password as a BCrypt::Password" do
44
- BCryptHash.load(@crypted_password, :property).should be_an_instance_of(BCrypt::Password)
45
- end
46
+ describe '.load' do
47
+ describe 'when argument is a string' do
48
+ before :all do
49
+ @input = 'DataMapper'
50
+ @result = DataMapper::Types::BCryptHash.load(@crypted_password, :property)
51
+ end
52
+
53
+ it 'returns instance of BCrypt::Password' do
54
+ @result.should be_an_instance_of(BCrypt::Password)
55
+ end
46
56
 
47
- it "should return the password as a password which matches" do
48
- BCryptHash.load(@crypted_password, :property).should == @clear_password
57
+ it 'returns a string that matches original' do
58
+ @result.should == @clear_password
59
+ end
49
60
  end
50
61
 
51
- it "should return nil if given nil" do
52
- BCryptHash.load(nil, :property).should be_nil
62
+ describe 'when argument is nil' do
63
+ before :all do
64
+ @input = nil
65
+ @result = DataMapper::Types::BCryptHash.load(@input, :property)
66
+ end
67
+
68
+ it 'returns nil' do
69
+ @result.should be_nil
70
+ end
53
71
  end
54
72
  end
55
73
 
56
- describe ".typecast" do
57
- it "should return the crypted_password as a BCrypt::Password" do
58
- BCryptHash.typecast(@crypted_password, :property).should be_an_instance_of(BCrypt::Password)
59
- end
74
+ describe '.typecast' do
75
+ describe 'when argument is a string' do
76
+ before :all do
77
+ @input = 'bcrypt hash'
78
+ @result = DataMapper::Types::BCryptHash.typecast(@input, :property)
79
+ end
60
80
 
61
- it "should match the password as a BCrypt::Password" do
62
- BCryptHash.typecast(@crypted_password, :property).should == @clear_password
63
- end
81
+ it 'casts argument to BCrypt::Password' do
82
+ @result.should be_an_instance_of(BCrypt::Password)
83
+ end
64
84
 
65
- it "should return the string value of crypted_password as a BCrypt::Password" do
66
- BCryptHash.typecast(@crypted_password.to_s, :property).should be_an_instance_of(BCrypt::Password)
85
+ it 'casts argument to value that matches input' do
86
+ @result.should == @input
87
+ end
67
88
  end
68
89
 
69
- it "should match the password as a string of the crypted_password" do
70
- BCryptHash.typecast(@crypted_password.to_s, :property).should == @clear_password
71
- end
90
+ describe 'when argument is a blank string' do
91
+ before :all do
92
+ @input = ''
93
+ @result = DataMapper::Types::BCryptHash.typecast(@input, :property)
94
+ end
72
95
 
73
- it "should return the password as a BCrypt::Password" do
74
- BCryptHash.typecast(@clear_password, :property).should be_an_instance_of(BCrypt::Password)
75
- end
96
+ it 'casts argument to BCrypt::Password' do
97
+ @result.should be_an_instance_of(BCrypt::Password)
98
+ end
76
99
 
77
- it "should match the password as clear_password" do
78
- BCryptHash.typecast(@clear_password, :property).should == @clear_password
100
+ it 'casts argument to value that matches input' do
101
+ @result.should == @input
102
+ end
79
103
  end
80
104
 
81
- it "should encrypt any type that has to_s" do
82
- BCryptHash.typecast(@nonstandard_type, :property).should be_an_instance_of(BCrypt::Password)
83
- end
105
+ describe 'when argument is integer' do
106
+ before :all do
107
+ @input = 2249
108
+ @result = DataMapper::Types::BCryptHash.typecast(@input, :property)
109
+ end
84
110
 
85
- it "should match the non-standard type" do
86
- BCryptHash.typecast(@nonstandard_type, :property).should == @nonstandard_type
87
- end
111
+ it 'casts argument to BCrypt::Password' do
112
+ @result.should be_an_instance_of(BCrypt::Password)
113
+ end
88
114
 
89
- it "should encrypt anything passed to it" do
90
- BCryptHash.typecast(@nonstandard_type2, :property).should be_an_instance_of(BCrypt::Password)
115
+ it 'casts argument to value that matches input' do
116
+ @result.should == @input
117
+ end
91
118
  end
92
119
 
93
- it "should match user-defined types" do
94
- BCryptHash.typecast(@nonstandard_type2, :property).should == @nonstandard_type2
120
+ describe 'when argument is hash' do
121
+ before :all do
122
+ @input = { :cryptic => 'obscure' }
123
+ @result = DataMapper::Types::BCryptHash.typecast(@input, :property)
124
+ end
125
+
126
+ it 'casts argument to BCrypt::Password' do
127
+ @result.should be_an_instance_of(BCrypt::Password)
128
+ end
129
+
130
+ it 'casts argument to value that matches input' do
131
+ @result.should == @input
132
+ end
95
133
  end
96
134
 
97
- it "should return nil if given nil" do
98
- BCryptHash.typecast(nil, :property).should be_nil
135
+ describe 'when argument is nil' do
136
+ before :all do
137
+ @input = nil
138
+ @result = DataMapper::Types::BCryptHash.typecast(@input, :property)
139
+ end
140
+
141
+ it 'returns nil' do
142
+ @result.should be_nil
143
+ end
99
144
  end
100
145
  end
101
- else
102
- it "requires the bcrypt-ruby gem to test"
103
146
  end
104
147
  end