virtus 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +2 -2
  4. data/Changelog.md +11 -0
  5. data/Gemfile +4 -2
  6. data/Gemfile.devtools +25 -19
  7. data/README.md +56 -4
  8. data/lib/virtus.rb +26 -5
  9. data/lib/virtus/attribute/builder.rb +2 -2
  10. data/lib/virtus/attribute/collection.rb +7 -3
  11. data/lib/virtus/attribute/hash.rb +3 -3
  12. data/lib/virtus/attribute/strict.rb +1 -1
  13. data/lib/virtus/builder.rb +1 -1
  14. data/lib/virtus/configuration.rb +7 -36
  15. data/lib/virtus/instance_methods.rb +1 -0
  16. data/lib/virtus/module_extensions.rb +8 -2
  17. data/lib/virtus/support/options.rb +1 -0
  18. data/lib/virtus/support/type_lookup.rb +1 -1
  19. data/lib/virtus/version.rb +1 -1
  20. data/spec/integration/custom_attributes_spec.rb +2 -2
  21. data/spec/integration/custom_collection_attributes_spec.rb +6 -6
  22. data/spec/integration/default_values_spec.rb +8 -8
  23. data/spec/integration/defining_attributes_spec.rb +25 -18
  24. data/spec/integration/embedded_value_spec.rb +5 -5
  25. data/spec/integration/extending_objects_spec.rb +5 -5
  26. data/spec/integration/hash_attributes_coercion_spec.rb +11 -7
  27. data/spec/integration/mass_assignment_with_accessors_spec.rb +5 -5
  28. data/spec/integration/overriding_virtus_spec.rb +4 -4
  29. data/spec/integration/required_attributes_spec.rb +1 -1
  30. data/spec/integration/struct_as_embedded_value_spec.rb +4 -4
  31. data/spec/integration/using_modules_spec.rb +8 -8
  32. data/spec/integration/value_object_with_custom_constructor_spec.rb +4 -4
  33. data/spec/integration/virtus/instance_level_attributes_spec.rb +1 -1
  34. data/spec/integration/virtus/value_object_spec.rb +14 -14
  35. data/spec/shared/freeze_method_behavior.rb +1 -1
  36. data/spec/spec_helper.rb +1 -0
  37. data/spec/unit/virtus/attribute/class_methods/build_spec.rb +9 -1
  38. data/spec/unit/virtus/attribute/collection/class_methods/build_spec.rb +13 -2
  39. data/spec/unit/virtus/attribute/collection/coerce_spec.rb +21 -0
  40. data/spec/unit/virtus/attribute/hash/class_methods/build_spec.rb +14 -2
  41. data/spec/unit/virtus/attribute_set/each_spec.rb +21 -16
  42. data/spec/unit/virtus/attribute_set/element_reference_spec.rb +1 -1
  43. data/spec/unit/virtus/attribute_set/reset_spec.rb +5 -3
  44. data/spec/unit/virtus/attribute_spec.rb +4 -3
  45. data/spec/unit/virtus/attributes_reader_spec.rb +1 -1
  46. data/spec/unit/virtus/attributes_writer_spec.rb +1 -1
  47. data/spec/unit/virtus/model_spec.rb +3 -3
  48. data/spec/unit/virtus/module_spec.rb +59 -2
  49. data/spec/unit/virtus/value_object_spec.rb +2 -2
  50. data/virtus.gemspec +2 -2
  51. metadata +34 -32
@@ -61,6 +61,7 @@ module Virtus
61
61
  def define_option_method(option)
62
62
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
63
63
  def self.#{option}(value = Undefined) # def self.primitive(value = Undefined)
64
+ @#{option} = nil unless defined?(@#{option}) # @primitive = nil unless defined?(@primitive)
64
65
  return @#{option} if value.equal?(Undefined) # return @primitive if value.equal?(Undefined)
65
66
  @#{option} = value # @primitive = value
66
67
  self # self
@@ -48,7 +48,7 @@ module Virtus
48
48
 
49
49
  # @api private
50
50
  def determine_type_and_cache(class_or_name)
51
- type = case class_or_name
51
+ case class_or_name
52
52
  when singleton_class
53
53
  determine_type_from_descendant(class_or_name)
54
54
  when Class
@@ -1,3 +1,3 @@
1
1
  module Virtus
2
- VERSION = '1.0.2'
2
+ VERSION = '1.0.3'
3
3
  end
@@ -31,12 +31,12 @@ describe 'custom attributes' do
31
31
  specify 'allows you to define custom attributes' do
32
32
  regexp = /awesome/
33
33
  subject.expression = regexp
34
- subject.expression.should == regexp
34
+ expect(subject.expression).to eq(regexp)
35
35
  end
36
36
 
37
37
  specify 'allows you to define coercion methods' do
38
38
  subject.scream = 'welcome'
39
- subject.scream.should == 'WELCOME'
39
+ expect(subject.scream).to eq('WELCOME')
40
40
  end
41
41
 
42
42
  end
@@ -36,7 +36,7 @@ describe 'custom collection attributes' do
36
36
  shared_examples_for 'a collection' do
37
37
  it 'can be used as Virtus attributes' do
38
38
  attribute = Examples::Library.attribute_set[:books]
39
- attribute.should be_kind_of(Examples::BookCollectionAttribute)
39
+ expect(attribute).to be_kind_of(Examples::BookCollectionAttribute)
40
40
  end
41
41
 
42
42
  it 'defaults to an empty collection' do
@@ -55,18 +55,18 @@ describe 'custom collection attributes' do
55
55
 
56
56
  it 'coerces an array of attribute hashes' do
57
57
  library.books = [{ :title => 'Foo' }]
58
- books.should be_kind_of(Examples::BookCollection)
58
+ expect(books).to be_kind_of(Examples::BookCollection)
59
59
  end
60
60
 
61
61
  it 'coerces its members' do
62
62
  library.books = [{ :title => 'Foo' }]
63
- books.count.should == 1
64
- books.first.should be_kind_of(Examples::Book)
63
+ expect(books.count).to eq(1)
64
+ expect(books.first).to be_kind_of(Examples::Book)
65
65
  end
66
66
 
67
67
  def books_should_be_an_empty_collection
68
- books.should be_kind_of(Examples::BookCollection)
69
- books.count.should == 0
68
+ expect(books).to be_kind_of(Examples::BookCollection)
69
+ expect(books.count).to eq(0)
70
70
  end
71
71
  end
72
72
 
@@ -35,21 +35,21 @@ describe "default values" do
35
35
  subject { Examples::Page.new }
36
36
 
37
37
  specify 'without a default the value is nil' do
38
- subject.title.should be_nil
38
+ expect(subject.title).to be_nil
39
39
  end
40
40
 
41
41
  specify 'can be supplied with the :default option' do
42
- subject.view_count.should == 0
42
+ expect(subject.view_count).to eq(0)
43
43
  end
44
44
 
45
45
  specify "you can pass a 'callable-object' to the :default option" do
46
46
  subject.title = 'Example Blog Post'
47
- subject.slug.should == 'example-blog-post'
47
+ expect(subject.slug).to eq('example-blog-post')
48
48
  end
49
49
 
50
50
  specify 'you can set defaults for private attributes' do
51
51
  subject.title = 'Top Secret'
52
- subject.editor_title.should == 'UNPUBLISHED: Top Secret'
52
+ expect(subject.editor_title).to eq('UNPUBLISHED: Top Secret')
53
53
  end
54
54
 
55
55
  specify 'you can reset attribute to its default' do
@@ -63,25 +63,25 @@ describe "default values" do
63
63
  it 'does not duplicate the ValueObject' do
64
64
  page1 = Examples::Page.new
65
65
  page2 = Examples::Page.new
66
- page1.reference.should equal(page2.reference)
66
+ expect(page1.reference).to equal(page2.reference)
67
67
  end
68
68
  end
69
69
 
70
70
  context 'an Array' do
71
71
  specify 'without a default the value is an empty Array' do
72
- subject.revisions.should eql([])
72
+ expect(subject.revisions).to eql([])
73
73
  end
74
74
  end
75
75
 
76
76
  context 'a Hash' do
77
77
  specify 'without a default the value is an empty Hash' do
78
- subject.index.should eql({})
78
+ expect(subject.index).to eql({})
79
79
  end
80
80
  end
81
81
 
82
82
  context 'a Set' do
83
83
  specify 'without a default the value is an empty Set' do
84
- subject.authors.should eql(Set.new)
84
+ expect(subject.authors).to eql(Set.new)
85
85
  end
86
86
  end
87
87
  end
@@ -19,61 +19,68 @@ describe "virtus attribute definitions" do
19
19
  end
20
20
  end
21
21
 
22
- subject { Examples::Person.new }
22
+ subject(:person) { Examples::Person.new(attributes) }
23
+
24
+ let(:attributes) { {} }
23
25
 
24
26
  specify 'virtus creates accessor methods' do
25
- subject.name = 'Peter'
26
- subject.name.should == 'Peter'
27
+ person.name = 'Peter'
28
+ expect(person.name).to eq('Peter')
27
29
  end
28
30
 
29
31
  specify 'the constructor accepts a hash for mass-assignment' do
30
32
  john = Examples::Person.new(:name => 'John', :age => 13)
31
- john.name.should == 'John'
32
- john.age.should == 13
33
+ expect(john.name).to eq('John')
34
+ expect(john.age).to eq(13)
33
35
  end
34
36
 
35
- specify 'Boolean attributes have a getter with questionmark' do
36
- subject.doctor?.should be_false
37
- subject.doctor = true
38
- subject.doctor?.should be_true
37
+ specify 'Boolean attributes have a predicate method' do
38
+ expect(person).not_to be_doctor
39
+ person.doctor = true
40
+ expect(person).to be_doctor
39
41
  end
40
42
 
41
43
  context 'with attributes' do
42
44
  let(:attributes) { {:name => 'Jane', :age => 45, :doctor => true, :salary => 4500} }
43
- subject { Examples::Person.new(attributes) }
44
45
 
45
46
  specify "#attributes returns the object's attributes as a hash" do
46
- subject.attributes.should == attributes
47
+ expect(person.attributes).to eq(attributes)
47
48
  end
48
49
 
49
50
  specify "#to_hash returns the object's attributes as a hash" do
50
- subject.to_hash.should == attributes
51
+ expect(person.to_hash).to eq(attributes)
52
+ end
53
+
54
+ specify "#to_h returns the object's attributes as a hash" do
55
+ expect(person.to_h).to eql(attributes)
51
56
  end
52
57
  end
53
58
 
54
59
  context 'inheritance' do
55
60
  specify 'inherits all the attributes from the base class' do
56
61
  fred = Examples::Manager.new(:name => 'Fred', :age => 29)
57
- fred.name.should == 'Fred'
58
- fred.age.should == 29
62
+ expect(fred.name).to eq('Fred')
63
+ expect(fred.age).to eq(29)
59
64
  end
60
65
 
61
66
  specify 'lets you add attributes to the base class at runtime' do
62
67
  frank = Examples::Manager.new(:name => 'Frank')
63
68
  Examples::Person.attribute :just_added, String
64
69
  frank.just_added = 'it works!'
65
- frank.just_added.should == 'it works!'
70
+ expect(frank.just_added).to eq('it works!')
66
71
  end
67
72
 
68
73
  specify 'lets you add attributes to the subclass at runtime' do
69
74
  person_jack = Examples::Person.new(:name => 'Jack')
70
75
  manager_frank = Examples::Manager.new(:name => 'Frank')
76
+
71
77
  Examples::Manager.attribute :just_added, String
72
78
 
73
79
  manager_frank.just_added = 'awesome!'
74
- manager_frank.just_added.should == 'awesome!'
75
- person_jack.should_not respond_to(:just_added)
76
- person_jack.should_not respond_to(:just_added=)
80
+
81
+ expect(manager_frank.just_added).to eq('awesome!')
82
+ expect(person_jack).not_to respond_to(:just_added)
83
+ expect(person_jack).not_to respond_to(:just_added=)
77
84
  end
78
85
  end
79
86
  end
@@ -33,18 +33,18 @@ describe 'embedded values' do
33
33
  end
34
34
 
35
35
  specify '#attributes returns instances of the embedded values' do
36
- subject.attributes.should == {
36
+ expect(subject.attributes).to eq({
37
37
  :name => 'the guy',
38
38
  :address => subject.address
39
- }
39
+ })
40
40
  end
41
41
 
42
42
  specify 'allows you to pass a hash for the embedded value' do
43
43
  user = Examples::User.new
44
44
  user.address = address_attributes
45
- user.address.street.should == 'Street 1/2'
46
- user.address.zipcode.should == '12345'
47
- user.address.city.name.should == 'NYC'
45
+ expect(user.address.street).to eq('Street 1/2')
46
+ expect(user.address.zipcode).to eq('12345')
47
+ expect(user.address.city.name).to eq('NYC')
48
48
  end
49
49
 
50
50
  end
@@ -21,15 +21,15 @@ describe 'I can extend objects' do
21
21
  admin.name = 'John'
22
22
  admin.age = 29
23
23
 
24
- admin.name.should eql('John')
25
- admin.age.should eql(29)
24
+ expect(admin.name).to eql('John')
25
+ expect(admin.age).to eql(29)
26
26
 
27
- admin.attributes.should eql(attributes)
27
+ expect(admin.attributes).to eql(attributes)
28
28
 
29
29
  new_attributes = { :name => 'Jane', :age => 28 }
30
30
  admin.attributes = new_attributes
31
31
 
32
- admin.name.should eql('Jane')
33
- admin.age.should eql(28)
32
+ expect(admin.name).to eql('Jane')
33
+ expect(admin.age).to eql(28)
34
34
  end
35
35
  end
@@ -23,28 +23,32 @@ describe Package do
23
23
  describe '#dimensions' do
24
24
  subject { dimensions }
25
25
 
26
- it { should have(3).keys }
26
+ it 'has 3 keys' do
27
+ expect(subject.keys.size).to eq(3)
28
+ end
27
29
  it { should have_key :width }
28
30
  it { should have_key :height }
29
31
  it { should have_key :length }
30
32
 
31
33
  it 'should be coerced to [Symbol => Float] format' do
32
- dimensions[:width].should be_eql(2.2)
33
- dimensions[:height].should be_eql(2.0)
34
- dimensions[:length].should be_eql(4.5)
34
+ expect(dimensions[:width]).to be_eql(2.2)
35
+ expect(dimensions[:height]).to be_eql(2.0)
36
+ expect(dimensions[:length]).to be_eql(4.5)
35
37
  end
36
38
  end
37
39
 
38
40
  describe '#meta_info' do
39
41
  subject { meta_info }
40
42
 
41
- it { should have(2).keys }
43
+ it 'has 2 keys' do
44
+ expect(subject.keys.size).to eq(2)
45
+ end
42
46
  it { should have_key 'from' }
43
47
  it { should have_key 'to' }
44
48
 
45
49
  it 'should be coerced to [String => String] format' do
46
- meta_info['from'].should == 'Me'
47
- meta_info['to'].should == 'You'
50
+ expect(meta_info['from']).to eq('Me')
51
+ expect(meta_info['to']).to eq('You')
48
52
  end
49
53
  end
50
54
  end
@@ -28,17 +28,17 @@ describe "mass assignment with accessors" do
28
28
  subject { Examples::Product.new(:categories => ['Office', 'Printers'], :_id => 100) }
29
29
 
30
30
  specify 'works uppon instantiation' do
31
- subject.category.should == 'Office'
32
- subject.subcategory.should == 'Printers'
31
+ expect(subject.category).to eq('Office')
32
+ expect(subject.subcategory).to eq('Printers')
33
33
  end
34
34
 
35
35
  specify 'can be set with #attributes=' do
36
36
  subject.attributes = {:categories => ['Home', 'Furniture']}
37
- subject.category.should == 'Home'
38
- subject.subcategory.should == 'Furniture'
37
+ expect(subject.category).to eq('Home')
38
+ expect(subject.subcategory).to eq('Furniture')
39
39
  end
40
40
 
41
41
  specify 'respects accessor visibility' do
42
- subject.id.should_not == 100
42
+ expect(subject.id).not_to eq(100)
43
43
  end
44
44
  end
@@ -22,11 +22,11 @@ describe 'overriding virtus behavior' do
22
22
 
23
23
  describe 'overriding an attribute getter' do
24
24
  specify 'calls the defined getter' do
25
- Examples::Article.new.title.should == '<unknown>'
25
+ expect(Examples::Article.new.title).to eq('<unknown>')
26
26
  end
27
27
 
28
28
  specify 'super can be used to access the getter defined by virtus' do
29
- Examples::Article.new(:title => 'example article').title.should == 'example article'
29
+ expect(Examples::Article.new(:title => 'example article').title).to eq('example article')
30
30
  end
31
31
  end
32
32
 
@@ -34,13 +34,13 @@ describe 'overriding virtus behavior' do
34
34
  specify 'calls the defined setter' do
35
35
  article = Examples::Article.new(:title => "can't be changed")
36
36
  article.title = 'this will never be assigned'
37
- article.title.should == "can't be changed"
37
+ expect(article.title).to eq("can't be changed")
38
38
  end
39
39
 
40
40
  specify 'super can be used to access the setter defined by virtus' do
41
41
  article = Examples::Article.new(:title => 'example article')
42
42
  article.title = 'my new title'
43
- article.title.should == 'my new title'
43
+ expect(article.title).to eq('my new title')
44
44
  end
45
45
  end
46
46
  end
@@ -13,7 +13,7 @@ describe 'Using required attributes' do
13
13
  end
14
14
 
15
15
  it 'raises coercion error when required attribute is nil' do
16
- expect { Examples::User.new(:name => nil) }.to raise_error(Virtus::CoercionError)
16
+ expect { Examples::User.new(:name => nil) }.to raise_error(Virtus::CoercionError, "Failed to coerce attribute `name' from nil into String")
17
17
  end
18
18
 
19
19
  it 'does not raise coercion error when not required attribute is nil' do
@@ -19,10 +19,10 @@ describe 'Using Struct as an embedded value attribute' do
19
19
  end
20
20
 
21
21
  specify 'initialize a struct object with correct attributes' do
22
- subject.top_left.x.should be(3)
23
- subject.top_left.y.should be(5)
22
+ expect(subject.top_left.x).to be(3)
23
+ expect(subject.top_left.y).to be(5)
24
24
 
25
- subject.bottom_right.x.should be(8)
26
- subject.bottom_right.y.should be(7)
25
+ expect(subject.bottom_right.x).to be(8)
26
+ expect(subject.bottom_right.y).to be(7)
27
27
  end
28
28
  end
@@ -33,15 +33,15 @@ describe 'I can define attributes within a module' do
33
33
  end
34
34
 
35
35
  specify 'including a module with attributes into a class' do
36
- Examples::User.attribute_set[:name].should be_instance_of(Virtus::Attribute)
37
- Examples::User.attribute_set[:gamer].should be_instance_of(Virtus::Attribute::Boolean)
36
+ expect(Examples::User.attribute_set[:name]).to be_instance_of(Virtus::Attribute)
37
+ expect(Examples::User.attribute_set[:gamer]).to be_instance_of(Virtus::Attribute::Boolean)
38
38
 
39
- Examples::Admin.attribute_set[:name].should be_instance_of(Virtus::Attribute)
40
- Examples::Admin.attribute_set[:age].should be_instance_of(Virtus::Attribute)
39
+ expect(Examples::Admin.attribute_set[:name]).to be_instance_of(Virtus::Attribute)
40
+ expect(Examples::Admin.attribute_set[:age]).to be_instance_of(Virtus::Attribute)
41
41
 
42
42
  user = Examples::Admin.new(:name => 'Piotr', :age => 29)
43
- user.name.should eql('Piotr')
44
- user.age.should eql(29)
43
+ expect(user.name).to eql('Piotr')
44
+ expect(user.age).to eql(29)
45
45
  end
46
46
 
47
47
  specify 'including a module with attributes into an instance' do
@@ -49,7 +49,7 @@ describe 'I can define attributes within a module' do
49
49
  moderator.extend(Examples::Name, Examples::Age)
50
50
 
51
51
  moderator.attributes = { :name => 'John', :age => 21 }
52
- moderator.name.should eql('John')
53
- moderator.age.should eql(21)
52
+ expect(moderator.name).to eql('John')
53
+ expect(moderator.age).to eql(21)
54
54
  end
55
55
  end
@@ -33,10 +33,10 @@ describe "Defining a ValueObject with a custom constructor" do
33
33
  end
34
34
 
35
35
  specify "initialize a value object attribute with correct attributes" do
36
- subject.top_left.x.should be(3)
37
- subject.top_left.y.should be(4)
36
+ expect(subject.top_left.x).to be(3)
37
+ expect(subject.top_left.y).to be(4)
38
38
 
39
- subject.bottom_right.x.should be(5)
40
- subject.bottom_right.y.should be(8)
39
+ expect(subject.bottom_right.x).to be(5)
40
+ expect(subject.bottom_right.y).to be(8)
41
41
  end
42
42
  end
@@ -17,7 +17,7 @@ describe Virtus, 'instance level attributes' do
17
17
  it 'allows setting the attribute value on the instance' do
18
18
  attribute
19
19
  subject.name = 'foo'
20
- subject.name.should eql('foo')
20
+ expect(subject.name).to eql('foo')
21
21
  end
22
22
  end
23
23
  end
@@ -26,21 +26,21 @@ describe Virtus::ValueObject do
26
26
 
27
27
  describe 'initialization' do
28
28
  it 'sets the attribute values provided to Class.new' do
29
- class_under_test.new(:latitude => 10000.001).latitude.should == 10000.001
30
- subject.latitude.should eql(attribute_values[:latitude])
29
+ expect(class_under_test.new(:latitude => 10000.001).latitude).to eq(10000.001)
30
+ expect(subject.latitude).to eql(attribute_values[:latitude])
31
31
  end
32
32
  end
33
33
 
34
34
  describe 'writer visibility' do
35
35
  it 'attributes are configured for private writers' do
36
- class_under_test.attribute_set[:latitude].public_reader?.should be(true)
37
- class_under_test.attribute_set[:longitude].public_writer?.should be(false)
36
+ expect(class_under_test.attribute_set[:latitude].public_reader?).to be(true)
37
+ expect(class_under_test.attribute_set[:longitude].public_writer?).to be(false)
38
38
  end
39
39
 
40
40
  it 'writer methods are set to private' do
41
41
  private_methods = class_under_test.private_instance_methods
42
42
  private_methods.map! { |m| m.to_s }
43
- private_methods.should include('latitude=', 'longitude=', 'attributes=')
43
+ expect(private_methods).to include('latitude=', 'longitude=', 'attributes=')
44
44
  end
45
45
 
46
46
  it 'attempts to call attribute writer methods raises NameError' do
@@ -52,48 +52,48 @@ describe Virtus::ValueObject do
52
52
  describe 'equality' do
53
53
  describe '#==' do
54
54
  it 'returns true for different objects with the same state' do
55
- subject.should == instance_with_equal_state
55
+ expect(subject).to eq(instance_with_equal_state)
56
56
  end
57
57
 
58
58
  it 'returns false for different objects with different state' do
59
- subject.should_not == instance_with_different_state
59
+ expect(subject).not_to eq(instance_with_different_state)
60
60
  end
61
61
  end
62
62
 
63
63
  describe '#eql?' do
64
64
  it 'returns true for different objects with the same state' do
65
- subject.should eql(instance_with_equal_state)
65
+ expect(subject).to eql(instance_with_equal_state)
66
66
  end
67
67
 
68
68
  it 'returns false for different objects with different state' do
69
- subject.should_not eql(instance_with_different_state)
69
+ expect(subject).not_to eql(instance_with_different_state)
70
70
  end
71
71
  end
72
72
 
73
73
  describe '#equal?' do
74
74
  it 'returns false for different objects with the same state' do
75
- subject.should_not equal(instance_with_equal_state)
75
+ expect(subject).not_to equal(instance_with_equal_state)
76
76
  end
77
77
 
78
78
  it 'returns false for different objects with different state' do
79
- subject.should_not equal(instance_with_different_state)
79
+ expect(subject).not_to equal(instance_with_different_state)
80
80
  end
81
81
  end
82
82
 
83
83
  describe '#hash' do
84
84
  it 'returns the same value for different objects with the same state' do
85
- subject.hash.should eql(instance_with_equal_state.hash)
85
+ expect(subject.hash).to eql(instance_with_equal_state.hash)
86
86
  end
87
87
 
88
88
  it 'returns different values for different objects with different state' do
89
- subject.hash.should_not eql(instance_with_different_state.hash)
89
+ expect(subject.hash).not_to eql(instance_with_different_state.hash)
90
90
  end
91
91
  end
92
92
  end
93
93
 
94
94
  describe '#inspect' do
95
95
  it 'includes the class name and attribute values' do
96
- subject.inspect.should == '#<GeoLocation latitude=10.0 longitude=20.0>'
96
+ expect(subject.inspect).to eq('#<GeoLocation latitude=10.0 longitude=20.0>')
97
97
  end
98
98
  end
99
99
  end