Skip to content
This repository was archived by the owner on Mar 15, 2022. It is now read-only.

Commit d44a576

Browse files
committed
Merge pull request #32 from pedroandrade/migrate-to-rspec
Migrate to RSpec
2 parents 29de448 + f628eb9 commit d44a576

27 files changed

+648
-624
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ end
99

1010
group :testing do
1111
gem 'test-unit', '~> 3.0.9'
12-
#gem 'rspec', '~> 3.0.0'
12+
gem 'rspec', '~> 3.1.0'
1313
#gem 'simplecov', '~> 0.8.2', :require => false
1414
gem 'coveralls', '~> 0.7.3', :require => false
1515
end

Rakefile

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@ require 'rake/testtask'
33
require 'rubygems/package_task'
44
require File.expand_path('../lib/ref', __FILE__)
55

6-
desc 'Default: run unit tests.'
7-
task :default => :test
6+
begin
7+
require 'rspec'
8+
require 'rspec/core/rake_task'
89

9-
desc 'RVM likes to call it tests'
10-
task :tests => :test
10+
RSpec::Core::RakeTask.new(:spec) do |t|
11+
t.rspec_opts = '--color --backtrace --format documentation'
12+
end
1113

12-
Rake::TestTask.new do |t|
13-
t.libs << 'test'
14-
t.pattern = 'test/**/*_test.rb'
15-
t.warning = true
16-
t.verbose = true
14+
task :default => :spec
15+
rescue LoadError
16+
puts 'Error loading Rspec rake tasks, probably building the gem...'
1717
end
1818

1919

20+
spec = eval(File.read(File.expand_path('../ref.gemspec', __FILE__)))
21+
2022
GEM_NAME = 'ref'
2123
EXTENSION_NAME = 'extension'
2224
JAVA_EXT_NAME = 'ref_ext'

spec/ref/mock_spec.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
require 'spec_helper'
2+
3+
describe Ref::Mock do
4+
5+
context 'gc with argument' do
6+
specify do
7+
Ref::Mock.use do
8+
obj_1 = Object.new
9+
obj_2 = Object.new
10+
11+
ref_1 = Ref::WeakReference.new(obj_1)
12+
ref_2 = Ref::WeakReference.new(obj_2)
13+
14+
Ref::Mock.gc(obj_1)
15+
16+
expect(ref_1.object).to be_nil
17+
expect(ref_2.object).to equal(obj_2)
18+
end
19+
end
20+
end
21+
22+
context 'gc with no argument' do
23+
specify do
24+
Ref::Mock.use do
25+
obj_1 = Object.new
26+
obj_2 = Object.new
27+
28+
ref_1 = Ref::WeakReference.new(obj_1)
29+
ref_2 = Ref::WeakReference.new(obj_2)
30+
31+
Ref::Mock.gc
32+
33+
expect(ref_1.object).to be_nil
34+
expect(ref_2.object).to be_nil
35+
end
36+
end
37+
end
38+
39+
end

spec/ref/reference_queue_spec.rb

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
require 'spec_helper'
2+
3+
describe Ref::ReferenceQueue do
4+
5+
let(:queue) { Ref::ReferenceQueue.new }
6+
let(:obj_1) { Object.new }
7+
let(:obj_2) { Object.new }
8+
let(:ref_1) { Ref::WeakReference.new(obj_1) }
9+
let(:ref_2) { Ref::WeakReference.new(obj_2) }
10+
11+
describe '#push' do
12+
context 'when the queue is empty' do
13+
it { expect(queue.size).to be(0) }
14+
it { expect(queue).to be_empty }
15+
end
16+
17+
context 'when the queue is not empty' do
18+
before do
19+
queue.push(ref_1)
20+
queue.push(ref_2)
21+
end
22+
23+
it { expect(queue.size).to be(2) }
24+
it { expect(queue).to_not be_empty }
25+
end
26+
end
27+
28+
describe '#shift' do
29+
context 'when the queue is not empty' do
30+
before do
31+
queue.push(ref_1)
32+
queue.push(ref_2)
33+
end
34+
it { expect(queue.shift).to be(ref_1) }
35+
end
36+
37+
context 'when the queue is empty' do
38+
it { expect(queue.shift).to be_nil }
39+
end
40+
end
41+
42+
describe '#pop' do
43+
context 'when the queue is not empty' do
44+
before do
45+
queue.push(ref_1)
46+
queue.push(ref_2)
47+
end
48+
49+
it { expect(queue.pop).to be(ref_2) }
50+
end
51+
context 'when the queue is empty' do
52+
it { expect(queue.pop).to be_nil }
53+
end
54+
end
55+
56+
context 'references are added immediately if the_object has been collected' do
57+
specify do
58+
Ref::Mock.use do
59+
ref = Ref::WeakReference.new(obj_1)
60+
Ref::Mock.gc(obj_1)
61+
queue.monitor(ref)
62+
63+
expect(ref).to equal(queue.shift)
64+
end
65+
end
66+
end
67+
68+
context 'references are added when the object has been collected' do
69+
specify do
70+
Ref::Mock.use do
71+
ref = Ref::WeakReference.new(obj_1)
72+
queue.monitor(ref)
73+
result = queue.shift
74+
expect(result).to eq nil
75+
76+
Ref::Mock.gc(obj_1)
77+
78+
object = queue.shift
79+
expect(ref.referenced_object_id).to eq object.referenced_object_id
80+
end
81+
end
82+
end
83+
end

spec/ref/soft_key_map_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
require 'spec_helper'
2+
3+
describe Ref::SoftKeyMap do
4+
it_behaves_like 'a reference key map' do
5+
let(:map_class) { Ref::SoftKeyMap }
6+
let(:reference_class) { Ref::SoftReference }
7+
end
8+
end

spec/ref/soft_reference_spec.rb

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
require 'spec_helper'
2+
3+
describe Ref::SoftReference do
4+
describe '#object' do
5+
context 'when has not garbage collected objects' do
6+
it 'gets the object' do
7+
obj = Object.new
8+
ref = Ref::SoftReference.new(obj)
9+
10+
expect(obj).to eq ref.object
11+
expect(obj.object_id).to eq ref.referenced_object_id
12+
end
13+
end
14+
15+
context 'when has a lot of objects' do
16+
# Since we can't reliably control the garbage collector, this is a brute force test.
17+
# It might not always fail if the garbage collector and memory allocator don't
18+
# cooperate, but it should fail often enough on continuous integration to
19+
# hilite any problems. Set the environment variable QUICK_TEST to "true" if you
20+
# want to make the tests run quickly.
21+
it 'get the correct object' do
22+
id_to_ref = {}
23+
(ENV["QUICK_TEST"] == "true" ? 1000 : 100000).times do |i|
24+
obj = Object.new
25+
if id_to_ref.key?(obj.object_id)
26+
ref = id_to_ref[obj.object_id]
27+
if ref.object
28+
fail "soft reference found with a live reference to an object that was not the one it was created with"
29+
break
30+
end
31+
end
32+
33+
%w(Here are a bunch of objects that are allocated and can then be cleaned up by the garbage collector)
34+
id_to_ref[obj.object_id] = Ref::SoftReference.new(obj)
35+
if i % 1000 == 0
36+
GC.start
37+
sleep(0.01)
38+
end
39+
end
40+
end
41+
end
42+
43+
context 'when references are not collected immediately' do
44+
it "the object can't be nil" do
45+
ref = Ref::SoftReference.new(Object.new)
46+
9.times{ arr = %w(allocate some memory on the heap); arr *= 100; GC.start }
47+
expect(ref.object).to_not be_nil
48+
end
49+
end
50+
end
51+
52+
describe '#inspect' do
53+
context 'when GC is called' do
54+
it 'inspects not be nil' do
55+
ref = Ref::SoftReference.new(Object.new)
56+
expect(ref.inspect).to_not be_nil
57+
GC.start
58+
GC.start
59+
expect(ref.inspect).to_not be_nil
60+
end
61+
end
62+
end
63+
end

spec/ref/soft_value_map_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
require 'spec_helper'
2+
3+
describe Ref::SoftValueMap do
4+
it_behaves_like 'a reference value map' do
5+
let(:map_class) { Ref::SoftValueMap }
6+
let(:reference_class) { Ref::SoftReference }
7+
end
8+
end

spec/ref/strong_reference_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
require 'spec_helper'
2+
3+
describe Ref::StrongReference do
4+
let(:obj) { Object.new }
5+
let(:ref) { Ref::StrongReference.new(obj) }
6+
7+
context '#object' do
8+
it { expect(obj).to equal(ref.object) }
9+
it { expect(obj.object_id).to equal(ref.referenced_object_id) }
10+
end
11+
12+
context '#inspect' do
13+
it { expect(ref.inspect).to_not be_empty }
14+
end
15+
end

spec/ref/weak_key_map_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
require 'spec_helper'
2+
3+
describe Ref::WeakKeyMap do
4+
it_behaves_like 'a reference key map' do
5+
let(:map_class) { Ref::WeakKeyMap }
6+
let(:reference_class) { Ref::WeakReference }
7+
end
8+
end

spec/ref/weak_reference_spec.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
require 'spec_helper'
2+
3+
describe Ref::WeakReference do
4+
describe '#object' do
5+
context 'when has not garbage collected objects' do
6+
it 'gets the object' do
7+
obj = Object.new
8+
ref_1 = Ref::WeakReference.new(obj)
9+
ref_2 = Ref::WeakReference.new(obj)
10+
11+
expect(obj).to eq ref_1.object
12+
expect(obj.object_id).to eq ref_1.referenced_object_id
13+
expect(obj).to eq ref_2.object
14+
expect(obj.object_id).to eq ref_2.referenced_object_id
15+
end
16+
end
17+
18+
context 'when has a lot of objects' do
19+
# Since we can't reliably control the garbage collector, this is a brute force test.
20+
# It might not always fail if the garbage collector and memory allocator don't
21+
# cooperate, but it should fail often enough on continuous integration to
22+
# hilite any problems. Set the environment variable QUICK_TEST to "true" if you
23+
# want to make the tests run quickly.
24+
it 'get the correct object' do
25+
id_to_ref = {}
26+
(ENV["QUICK_TEST"] == "true" ? 1000 : 100000).times do |i|
27+
obj = Object.new
28+
if id_to_ref.key?(obj.object_id)
29+
ref = id_to_ref[obj.object_id]
30+
if ref.object
31+
fail "weak reference found with a live reference to an object that was not the one it was created with"
32+
break
33+
end
34+
end
35+
%w(Here are a bunch of objects that are allocated and can then be cleaned up by the garbage collector)
36+
id_to_ref[obj.object_id] = Ref::WeakReference.new(obj)
37+
if i % 1000 == 0
38+
GC.start
39+
sleep(0.01)
40+
end
41+
end
42+
end
43+
end
44+
end
45+
46+
describe '#inspect' do
47+
context 'when GC is called' do
48+
it 'inspects not be nil' do
49+
ref = Ref::SoftReference.new(Object.new)
50+
expect(ref.inspect).to_not be_nil
51+
GC.start
52+
GC.start
53+
expect(ref.inspect).to_not be_nil
54+
end
55+
end
56+
end
57+
end

0 commit comments

Comments
 (0)