Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Beefed up equality tests and hash calculatesion for version,

specification and requirements.  Added mutex around gem path searcher
creation.


git-svn-id: svn+ssh://rubyforge.org/var/svn/rubygems/trunk@1066 3d4018f9-ac1a-0410-99e9-8a154d859a19
  • Loading branch information...
commit d6dc09c87e1342de6ec57441a38f958713392f0a 1 parent 5e563c6
Jim Weirich jimweirich authored
27 ChangeLog
View
@@ -1,3 +1,30 @@
+2006-09-18 Jim Weirich <jim@weirichhouse.org>
+
+ * lib/rubygems/version.rb (Gem::Dependency::hash): Added hash code
+ calculation.
+ (Gem::Version::hash): Added hash code calculation.
+ (Gem::Requirement::hash): Added hash code calculation.
+
+ * test/test_specification.rb (TestSpecificationEquality): Added
+ tests for specification equality and hashing.
+
+ * test/test_remote_installer.rb
+ (TestRemoteInstaller::test_installer_has_proxy_uri): Added tests
+ for proper proxy initialization in RemoteFetcher.
+
+ * test/test_version_comparison.rb (TestVersionEquality): Added
+ tests for version equality and hashing.
+ (TestRequirementEquality): Added tests for requirement equality.
+
+ * lib/rubygems/specification.rb (Gem::Specification::hash): Added
+ a hash method and improved equality testing.
+
+2006-09-15 Jim Weirich <jim@weirichhouse.org>
+
+ * lib/rubygems.rb (Gem::OperationNotSupportedError::searcher):
+ Moved searcher initialization into Gem module and added Mutex
+ protection.
+
2006-08-22 Jim Weirich <jim@weirichhouse.org>
* lib/rubygems/remote_installer.rb (Gem::RemoteInstaller::download_gem):
10 lib/rubygems.rb
View
@@ -73,6 +73,9 @@ def active_gem_with_options(gem_name, version_requirements, options={})
#
module Gem
require 'rubygems/rubygems_version.rb'
+ require 'thread'
+
+ MUTEX = Mutex.new
class Exception < RuntimeError
end
@@ -162,6 +165,13 @@ def datadir(gem_name)
File.join(spec.full_gem_path, 'data', gem_name)
end
+ # Return the searcher object to search for matching gems.
+ def searcher
+ MUTEX.synchronize do
+ @searcher ||= Gem::GemPathSearcher.new
+ end
+ end
+
# Return the Ruby command to use to execute the Ruby interpreter.
def ruby
"ruby"
3  lib/rubygems/custom_require.rb
View
@@ -27,8 +27,7 @@ def require(path)
gem_original_require path
rescue LoadError => load_error
begin
- @gempath_searcher ||= Gem::GemPathSearcher.new
- if spec = @gempath_searcher.find(path)
+ if spec = Gem.searcher.find(path)
Gem.activate(spec.name, false, "= #{spec.version}")
gem_original_require path
else
12 lib/rubygems/specification.rb
View
@@ -516,11 +516,23 @@ def <=>(other)
# Tests specs for equality (across all attributes).
def ==(other)
+ other.kind_of?(self.class) && same_attributes?(other)
+ end
+
+ def same_attributes?(other)
@@attributes.each do |name, default|
return false unless self.send(name) == other.send(name)
end
true
end
+ private :same_attributes?
+
+ def hash
+ @@attributes.inject(0) { |hash_code, (name, default_value)|
+ n = self.send(name).hash
+ hash_code + n
+ }
+ end
# Export methods (YAML and Ruby code) ----------------------------
16 lib/rubygems/version.rb
View
@@ -54,6 +54,12 @@ def ==(other)
self.name = other.name and
self.version_requirements == other.version_requirements
end
+
+ def hash
+ fail
+ name.hash + version_requirements.hash
+ end
+
end
####################################################################
@@ -150,6 +156,10 @@ def <=>(other)
return r <=> v
end
+ def hash
+ to_ints.inject { |hash_code, n| hash_code + n }
+ end
+
# Return a new version object where the next to the last revision
# number is one greater. (e.g. 5.3.1 => 5.4)
def bump
@@ -300,7 +310,11 @@ def parse(str)
def <=>(other)
to_s <=> other.to_s
end
-
+
+ def hash
+ to_s.hash
+ end
+ public :hash
end
end
18 test/test_remote_installer.rb
View
@@ -14,6 +14,7 @@
class MockFetcher
def initialize(uri, proxy)
@uri = uri
+ @proxy = proxy
end
def size
@@ -62,8 +63,21 @@ def setup
@installer.instance_variable_set("@fetcher_class", MockFetcher)
end
- def test_create
- assert_not_nil(@installer)
+ def test_installer_has_proxy_uri
+ proxy = "http://user:pass@proxy.url"
+ @installer.instance_variable_set("@options", {:http_proxy => proxy})
+ MockFetcher.class_eval("def fetch_path(path); raise 'failed' unless @proxy == '#{proxy}'; end")
+
+ spec = Gem::Specification.new do |s|
+ s.version = "1.0.0"
+ s.name = "boo"
+ s.platform = Gem::Platform::RUBY
+ s.date = Time.now
+ s.summary = "Hello"
+ s.require_paths = ["."]
+ end
+
+ @installer.download_gem("dest_file", "source", spec)
end
# Make sure that the installer knows the proper list of places to go
42 test/test_specification.rb
View
@@ -268,6 +268,48 @@ def test_to_ruby
end
+class TestSpecificationEquality < Test::Unit::TestCase
+
+ def test_equals_is_true_on_same_specification
+ s = Gem::Specification.new
+ assert s == s
+ end
+
+ def test_specs_with_same_attributes_are_equal
+ s = Gem::Specification.new do |spec| spec.name = "ONE" end
+ t = Gem::Specification.new do |spec| spec.name = "ONE" end
+ assert (s == t)
+ assert (t == s)
+ end
+
+ def test_specs_with_same_attributes_have_same_hash_code
+ s = Gem::Specification.new do |spec| spec.name = "ONE" end
+ t = Gem::Specification.new do |spec| spec.name = "ONE" end
+ assert_equal s.hash, t.hash
+ end
+
+ def test_specs_with_different_attributes_are_not_equal
+ s = Gem::Specification.new do |spec| spec.name = "ONE" end
+ t = Gem::Specification.new do |spec| spec.name = "TWO" end
+ assert ! (s == t)
+ assert ! (t == s)
+ end
+
+ def test_specs_with_different_attributes_have_different_hash_codes
+ s = Gem::Specification.new do |spec| spec.name = "ONE" end
+ t = Gem::Specification.new do |spec| spec.name = "TWO" end
+ assert s.hash != t.hash
+ end
+
+ def test_equals_is_false_on_non_spec_objects
+ s = Gem::Specification.new
+ t = Object.new
+ assert ! (s == t)
+ assert ! (t == s)
+ end
+
+end
+
class TestComplexSpecification < Test::Unit::TestCase
def setup
58 test/test_version_comparison.rb
View
@@ -102,8 +102,36 @@ def test_bump_one_level
assert_equal "6", v.bump.to_s
end
end
-
+class TestVersionEquality < Test::Unit::TestCase
+ def test_same_versions_are_equal
+ v = Gem::Version.new("1.2")
+ u = Gem::Version.new("1.2")
+ assert v == u
+ assert u == v
+ end
+
+ def test_same_versions_have_same_hash
+ v = Gem::Version.new("1.2")
+ u = Gem::Version.new("1.2")
+ assert_equal v.hash, u.hash
+ end
+
+ def test_different_versions_are_not_equal
+ v = Gem::Version.new("1.2")
+ u = Gem::Version.new("1.3")
+ assert v != u
+ assert u != v
+ end
+
+ def test_difference3_versions_have_different_hash
+ v = Gem::Version.new("1.2")
+ u = Gem::Version.new("1.3")
+ assert_not_equal v.hash, u.hash
+ end
+
+end
+
class TestExtendedVersionComparisons < Test::Unit::TestCase
include VersionAsserts
@@ -208,3 +236,31 @@ def test_normalization
assert_equal ">= 1.0.4", dep.to_s
end
end
+
+class TestRequirementEquality < Test::Unit::TestCase
+ def test_same_requirements_are_equal
+ r = Gem::Requirement.new("= 1.2")
+ p = Gem::Requirement.new("= 1.2")
+ assert r == p
+ assert p == r
+ end
+
+ def test_same_requirements_have_same_hash_code
+ r = Gem::Requirement.new("= 1.2")
+ p = Gem::Requirement.new("= 1.2")
+ assert_equal r.hash, p.hash
+ end
+
+ def test_different_requirements_are_not_equal
+ r = Gem::Requirement.new("= 1.2")
+ p = Gem::Requirement.new("< 1.2")
+ assert r != p
+ assert p != r
+ end
+
+ def test_different_requirements_have_different_hash_codes
+ r = Gem::Requirement.new("= 1.2")
+ p = Gem::Requirement.new("< 1.2")
+ assert_not_equal r.hash, p.hash
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.