Skip to content

Commit

Permalink
Add basic internal testing for memory allocations (#2097)
Browse files Browse the repository at this point in the history
* Add basic internal testing for memory allocations

* add RUBY_VERSION to debug output

* fix allocation counts

* fix allocation counts

* use compile cache helper

* try using cache clearing

* try using more specific ruby version targets and ensure compilation

* add allocation counts for CI ruby versions

* use counts from CI

* move require to top of file

* try removing component from compile cache to stabilize allocations

* another stabilization attempt
  • Loading branch information
joelhawksley authored Sep 25, 2024
1 parent fe39b4d commit def1448
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 23 deletions.
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ GEM
tzinfo (~> 2.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
allocation_stats (0.1.5)
ansi (1.5.0)
appraisal (2.5.0)
bundler
Expand Down Expand Up @@ -330,6 +331,7 @@ PLATFORMS
ruby

DEPENDENCIES
allocation_stats (~> 0.1.5)
appraisal (~> 2.4)
benchmark-ips (~> 2.13.0)
better_html
Expand Down
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ nav_order: 5

## main

* Add basic internal testing for memory allocations.

*Joel Hawksley*

* Add support for request formats.

*Joel Hawksley*
Expand Down
53 changes: 30 additions & 23 deletions test/sandbox/test/rendering_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ def test_render_inline
assert_selector("div", text: "hello,world!")
end

def test_render_inline_allocations
# Stabilize compilation status ahead of testing allocations to simulate rendering
# performance with compiled component
ViewComponent::CompileCache.cache.delete(MyComponent)
MyComponent.ensure_compiled

assert_allocations("3.4.0" => 107, "3.3.5" => 116, "3.3.0" => 129, "3.2.5" => 115, "3.1.6" => 115, "3.0.7" => 125) do
render_inline(MyComponent.new)
end

assert_selector("div", text: "hello,world!")
end

def test_render_in_view_context
render_in_view_context { render(MyComponent.new) }

Expand Down Expand Up @@ -717,34 +730,28 @@ def test_collection_component_present_custom_parameter_name_with_activemodel
end

def test_component_with_invalid_parameter_names
old_cache = ViewComponent::CompileCache.cache
ViewComponent::CompileCache.cache = Set.new

exception =
assert_raises ViewComponent::ReservedParameterError do
InvalidParametersComponent.compile(raise_errors: true)
end
with_new_cache do
exception =
assert_raises ViewComponent::ReservedParameterError do
InvalidParametersComponent.compile(raise_errors: true)
end

assert_match(/InvalidParametersComponent initializer can't accept the parameter/, exception.message)
ensure
ViewComponent::CompileCache.cache = old_cache
assert_match(/InvalidParametersComponent initializer can't accept the parameter/, exception.message)
end
end

def test_component_with_invalid_named_parameter_names
old_cache = ViewComponent::CompileCache.cache
ViewComponent::CompileCache.cache = Set.new

exception =
assert_raises ViewComponent::ReservedParameterError do
InvalidNamedParametersComponent.compile(raise_errors: true)
end
with_new_cache do
exception =
assert_raises ViewComponent::ReservedParameterError do
InvalidNamedParametersComponent.compile(raise_errors: true)
end

assert_match(
/InvalidNamedParametersComponent initializer can't accept the parameter `content`/,
exception.message
)
ensure
ViewComponent::CompileCache.cache = old_cache
assert_match(
/InvalidNamedParametersComponent initializer can't accept the parameter `content`/,
exception.message
)
end
end

def test_collection_component_with_trailing_comma_attr_reader
Expand Down
9 changes: 9 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require "allocation_stats"
require "simplecov"
require "simplecov-console"
require "rails/version"
Expand Down Expand Up @@ -187,3 +188,11 @@ def capture_warnings(&block)
end
end
end

def assert_allocations(count_map, &block)
trace = AllocationStats.trace(&block)
total = trace.allocations.all.size
count = count_map[RUBY_VERSION]

assert_equal count, total, "Expected #{count} allocations, got #{total} allocations for Ruby #{RUBY_VERSION}"
end
1 change: 1 addition & 0 deletions view_component.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency "activesupport", [">= 5.2.0", "< 8.0"]
spec.add_runtime_dependency "method_source", "~> 1.0"
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
spec.add_development_dependency "allocation_stats", "~> 0.1.5"
spec.add_development_dependency "appraisal", "~> 2.4"
spec.add_development_dependency "benchmark-ips", "~> 2.13.0"
spec.add_development_dependency "better_html"
Expand Down

0 comments on commit def1448

Please sign in to comment.