Skip to content

Commit 3c58f2a

Browse files
committed
Initial migration from async-rspec.
0 parents commit 3c58f2a

File tree

14 files changed

+573
-0
lines changed

14 files changed

+573
-0
lines changed

.editorconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
root = true
2+
3+
[*]
4+
indent_style = tab
5+
indent_size = 2
6+

.gitignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/.bundle/
2+
/.yardoc
3+
/Gemfile.lock
4+
/_yardoc/
5+
/coverage/
6+
/doc/
7+
/pkg/
8+
/spec/reports/
9+
/tmp/
10+
11+
# rspec failure tracking
12+
.rspec_status
13+
.covered.db

.rspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--format documentation
2+
--warnings
3+
--require spec_helper

.travis.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
language: ruby
2+
dist: xenial
3+
cache: bundler
4+
5+
matrix:
6+
include:
7+
- rvm: 2.3
8+
- rvm: 2.4
9+
- rvm: 2.5
10+
- rvm: 2.6
11+
- rvm: 2.6
12+
env: COVERAGE=BriefSummary,Coveralls
13+
- rvm: ruby-head
14+
- rvm: jruby-head
15+
env: JRUBY_OPTS="--debug -X+O"
16+
- rvm: truffleruby
17+
allow_failures:
18+
- rvm: ruby-head
19+
- rvm: jruby-head
20+
- rvm: truffleruby

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
source 'https://rubygems.org'
2+
3+
# Specify your gem's dependencies in rspec-memory.gemspec
4+
gemspec

README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# RSpec::Memory
2+
3+
Make assertions about memory usage.
4+
5+
[![Build Status](https://travis-ci.com/socketry/rspec-memory.svg)](https://travis-ci.com/socketry/rspec-memory)
6+
7+
## Installation
8+
9+
Add this line to your application's Gemfile:
10+
11+
```ruby
12+
gem 'rspec-memory'
13+
```
14+
15+
And then execute:
16+
17+
$ bundle
18+
19+
Or install it yourself as:
20+
21+
$ gem install rspec-memory
22+
23+
Finally, add this require statement to the top of `spec/spec_helper.rb`
24+
25+
```ruby
26+
require 'async/rspec'
27+
```
28+
29+
## Usage
30+
31+
Allocating large amounts of objects can lead to memery problems. `RSpec::Memory` adds a `limit_allocations` matcher, which tracks the number of allocations and memory size for each object type and allows you to specify expected limits.
32+
33+
```ruby
34+
RSpec.describe "memory allocations" do
35+
include_context RSpec::Memory
36+
37+
it "limits allocation counts" do
38+
expect do
39+
6.times{String.new}
40+
end.to limit_allocations(String => 10) # 10 strings can be allocated
41+
end
42+
43+
it "limits allocation counts (hash)" do
44+
expect do
45+
6.times{String.new}
46+
end.to limit_allocations(String => {count: 10}) # 10 strings can be allocated
47+
end
48+
49+
it "limits allocation size" do
50+
expect do
51+
6.times{String.new("foo")}
52+
end.to limit_allocations(String => {size: 1024}) # 1 KB of strings can be allocated
53+
end
54+
end
55+
```
56+
57+
## Contributing
58+
59+
1. Fork it
60+
2. Create your feature branch (`git checkout -b my-new-feature`)
61+
3. Commit your changes (`git commit -am 'Add some feature'`)
62+
4. Push to the branch (`git push origin my-new-feature`)
63+
5. Create new Pull Request
64+
65+
## License
66+
67+
Released under the MIT license.
68+
69+
Copyright, 2017, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
70+
71+
Permission is hereby granted, free of charge, to any person obtaining a copy
72+
of this software and associated documentation files (the "Software"), to deal
73+
in the Software without restriction, including without limitation the rights
74+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
75+
copies of the Software, and to permit persons to whom the Software is
76+
furnished to do so, subject to the following conditions:
77+
78+
The above copyright notice and this permission notice shall be included in
79+
all copies or substantial portions of the Software.
80+
81+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
82+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
83+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
84+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
85+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
86+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
87+
THE SOFTWARE.

Rakefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
require "bundler/gem_tasks"
2+
require "rspec/core/rake_task"
3+
4+
RSpec::Core::RakeTask.new(:test)
5+
6+
task :default => :test

lib/rspec/memory.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in
11+
# all copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
# THE SOFTWARE.
20+
21+
require_relative 'memory/matchers/limit_allocations'
22+
23+
RSpec.shared_context RSpec::Memory do
24+
include RSpec::Memory::Matchers
25+
end
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2+
# Copyright, 2018, by Janko Marohnić.
3+
#
4+
# Permission is hereby granted, free of charge, to any person obtaining a copy
5+
# of this software and associated documentation files (the "Software"), to deal
6+
# in the Software without restriction, including without limitation the rights
7+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
# copies of the Software, and to permit persons to whom the Software is
9+
# furnished to do so, subject to the following conditions:
10+
#
11+
# The above copyright notice and this permission notice shall be included in
12+
# all copies or substantial portions of the Software.
13+
#
14+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+
# THE SOFTWARE.
21+
22+
require_relative '../trace'
23+
24+
require 'rspec/expectations'
25+
26+
module RSpec
27+
module Memory
28+
module Matchers
29+
class LimitAllocations
30+
include ::RSpec::Matchers::Composable
31+
32+
def initialize(allocations = {}, count: nil, size: nil)
33+
@count = count
34+
@size = size
35+
36+
@allocations = {}
37+
@errors = []
38+
39+
allocations.each do |klass, count|
40+
self.of(klass, count: count)
41+
end
42+
end
43+
44+
def supports_block_expectations?
45+
true
46+
end
47+
48+
def of(klass, **limits)
49+
@allocations[klass] = limits
50+
51+
return self
52+
end
53+
54+
private def check(value, limit)
55+
case limit
56+
when Range
57+
unless limit.include? value
58+
yield "expected within #{limit}"
59+
end
60+
when Integer
61+
unless value == limit
62+
yield "expected exactly #{limit}"
63+
end
64+
end
65+
end
66+
67+
def matches?(given_proc)
68+
return true unless trace = Trace.capture(@allocations.keys, &given_proc)
69+
70+
if @count or @size
71+
# If the spec specifies a total limit, we have a limit which we can enforce which takes all allocations into account:
72+
total = trace.total
73+
74+
check(total.count, @count) do |expected|
75+
@errors << "allocated #{total.count} instances, #{total.size} bytes, #{expected} instances"
76+
end if @count
77+
78+
check(total.size, @size) do |expected|
79+
@errors << "allocated #{total.count} instances, #{total.size} bytes, #{expected} bytes"
80+
end if @size
81+
else
82+
# Otherwise unspecified allocations are considered an error:
83+
trace.ignored.each do |klass, allocation|
84+
@errors << "allocated #{allocation.count} #{klass} instances, #{allocation.size} bytes, but it was not specified"
85+
end
86+
end
87+
88+
trace.allocated.each do |klass, allocation|
89+
next unless acceptable = @allocations[klass]
90+
91+
check(allocation.count, acceptable[:count]) do |expected|
92+
@errors << "allocated #{allocation.count} #{klass} instances, #{allocation.size} bytes, #{expected} instances"
93+
end
94+
95+
check(allocation.size, acceptable[:size]) do |expected|
96+
@errors << "allocated #{allocation.count} #{klass} instances, #{allocation.size} bytes, #{expected} bytes"
97+
end
98+
end
99+
100+
return @errors.empty?
101+
end
102+
103+
def failure_message
104+
"exceeded allocation limit: #{@errors.join(', ')}"
105+
end
106+
end
107+
108+
def limit_allocations(*args)
109+
LimitAllocations.new(*args)
110+
end
111+
end
112+
end
113+
end

0 commit comments

Comments
 (0)