Skip to content

Commit

Permalink
Merge pull request #1760 from Shopify/uk-improve-pipeline-testing
Browse files Browse the repository at this point in the history
This one weird trick will speed up our test runs...
  • Loading branch information
paracycle committed Jan 15, 2024
2 parents 9d243f5 + 0127bc3 commit 2c25e6a
Show file tree
Hide file tree
Showing 2 changed files with 299 additions and 380 deletions.
346 changes: 0 additions & 346 deletions spec/tapioca/cli/gem_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1136,260 +1136,6 @@ def foo(a, b, c, d, e, f, g, h); end
assert_success_status(result)
end

it "must do mixin attribution properly" do
# This is pattern is taken from the private `typed_parameters` gem.
typed_parameters = mock_gem("typed_parameters", "0.3.0") do
write!("lib/typed_parameters.rb", <<~RUBY)
require "action_controller"
module TypedParameters
end
# This dynamic mixin should be generated in the gem RBI
ActionController::Parameters.include(TypedParameters)
RUBY
end

@project.require_real_gem("actionpack", "6.1.4.4")
@project.require_mock_gem(typed_parameters)

@project.bundle_install!

response = @project.tapioca("gem actionpack typed_parameters")

assert_includes(response.out, "Compiled actionpack")
assert_includes(response.out, "Compiled typed_parameters")

actionpack_rbi = @project.read("sorbet/rbi/gems/actionpack@6.1.4.4.rbi")
# actionpack RBI should have nothing in it about `TypedParameters`
refute_includes(actionpack_rbi, "TypedParameters")

assert_project_file_equal("sorbet/rbi/gems/typed_parameters@0.3.0.rbi", <<~RBI)
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `typed_parameters` gem.
# Please instead update this file by running `bin/tapioca gem typed_parameters`.
class ActionController::Parameters
include ::TypedParameters
end
module TypedParameters; end
RBI
end

it "must do mixin attribution properly when include occurs in other gem" do
some_engine = mock_gem("some_engine", "0.0.2") do
write!("lib/some_engine.rb", <<~RUBY)
require "action_controller"
module SomeEngine
class SomeController < ActionController::Base
# This method triggers a dynamic mixin which should be attributed to this gem
# and not actionpack, even though the real `include` happens inside actionpack
helper_method :foo
end
end
RUBY
end

@project.require_real_gem("actionpack", "6.1.4.4")
@project.require_mock_gem(some_engine)
@project.bundle_install!

response = @project.tapioca("gem actionpack some_engine")

assert_includes(response.out, "Compiled actionpack")
assert_includes(response.out, "Compiled some_engine")

actionpack_rbi = @project.read("sorbet/rbi/gems/actionpack@6.1.4.4.rbi")
# actionpack RBI should have nothing in it about `SomeEngine`
refute_includes(actionpack_rbi, "SomeEngine")

expected = template(<<~RBI)
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `some_engine` gem.
# Please instead update this file by running `bin/tapioca gem some_engine`.
module SomeEngine; end
class SomeEngine::SomeController < ::ActionController::Base
private
def _layout(lookup_context, formats); end
class << self
def _helper_methods; end
def middleware_stack; end
end
end
module SomeEngine::SomeController::HelperMethods
include ::ActionController::Base::HelperMethods
<% if ruby_version(">= 3.1") %>
def foo(*args, **_arg1, &block); end
<% else %>
def foo(*args, &block); end
<% end %>
end
RBI

assert_project_file_equal("sorbet/rbi/gems/some_engine@0.0.2.rbi", expected)
end

it "must generate RBIs for constants defined in a different gem but with mixins in this gem" do
foo = mock_gem("foo", "0.0.1") do
write!("lib/foo.rb", <<~RBI)
class Foo
def baz; end
def buzz; end
end
RBI
end

bar = mock_gem("bar", "0.0.2") do
write!("lib/bar.rb", <<~RBI)
module Bar; end
Foo.prepend(Bar)
RBI
end

@project.require_mock_gem(foo)
@project.require_mock_gem(bar)
@project.bundle_install!

@project.tapioca("gem bar")

assert_project_file_equal("sorbet/rbi/gems/bar@0.0.2.rbi", <<~RBI)
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `bar` gem.
# Please instead update this file by running `bin/tapioca gem bar`.
module Bar; end
class Foo
include ::Bar
end
RBI
end

it "must not generate RBIs for constants that have dynamic mixins performed in other gems" do
bar = mock_gem("bar", "0.0.2") do
write!("lib/bar.rb", <<~RBI)
module Bar; end
RBI
end

foo = mock_gem("foo", "0.0.1") do
write!("lib/foo.rb", <<~RBI)
class Foo; end
String.prepend(Bar)
RBI
end

@project.require_mock_gem(bar)
@project.require_mock_gem(foo)
@project.bundle_install!

@project.tapioca("gem bar")

assert_project_file_equal("sorbet/rbi/gems/bar@0.0.2.rbi", <<~RBI)
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `bar` gem.
# Please instead update this file by running `bin/tapioca gem bar`.
module Bar; end
RBI
end

it "must generate RBIs for constants that have dynamic mixins performed in the gem" do
bar = mock_gem("bar", "0.0.2") do
write!("lib/bar.rb", <<~RBI)
class Bar
def bar; end
end
RBI
end

foo = mock_gem("foo", "0.0.1") do
write!("lib/foo.rb", <<~RBI)
module Foo; end
class Baz < Bar; end
Bar.prepend(Foo)
RBI
end

@project.require_mock_gem(bar)
@project.require_mock_gem(foo)
@project.bundle_install!

@project.tapioca("gem bar foo")

assert_project_file_equal("sorbet/rbi/gems/foo@0.0.1.rbi", <<~RBI)
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `foo` gem.
# Please instead update this file by running `bin/tapioca gem foo`.
class Bar
include ::Foo
end
class Baz < ::Bar; end
module Foo; end
RBI
end

it "must generate RBIs for foreign constants whose singleton class overrides #inspect" do
bar = mock_gem("bar", "0.0.2") do
write!("lib/bar.rb", <<~RBI)
class Bar
def self.inspect
"Override!"
end
end
RBI
end

foo = mock_gem("foo", "0.0.1") do
write!("lib/foo.rb", <<~RBI)
module Foo; end
Bar.singleton_class.include(Foo)
RBI
end

@project.require_mock_gem(bar)
@project.require_mock_gem(foo)
@project.bundle_install!

result = @project.tapioca("gem foo")
assert_empty_stderr(result)

assert_project_file_equal("sorbet/rbi/gems/foo@0.0.1.rbi", <<~RBI)
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `foo` gem.
# Please instead update this file by running `bin/tapioca gem foo`.
class Bar
extend ::Foo
end
module Foo; end
RBI
end

it "must not load engines in the application" do
@project.write!("config/application.rb", <<~RB)
require "rails"
Expand Down Expand Up @@ -1586,98 +1332,6 @@ class Application < Rails::Application
assert_includes(turbo_streams_rbi, "module Turbo::Streams; end")
assert_includes(turbo_streams_rbi, "module Turbo::Streams::ActionHelper")
end

it "generates documentation only for the gem that defines it" do
foo = mock_gem("foo", "0.0.2") do
write!("lib/foo.rb", <<~RB)
# Most objects are cloneable
class Object
def foo; end
end
RB
end
bar = mock_gem("bar", "0.0.2") do
write!("lib/bar.rb", <<~RB)
class Object
def bar; end
end
RB
end
baz = mock_gem("baz", "0.0.2") do
write!("lib/baz.rb", <<~RB)
def baz; end
RB
end

@project.require_mock_gem(foo)
@project.require_mock_gem(bar)
@project.require_mock_gem(baz)
@project.bundle_install!

result = @project.tapioca("gem bar foo baz --doc")

foo_rbi = @project.read("sorbet/rbi/gems/foo@0.0.2.rbi")
bar_rbi = @project.read("sorbet/rbi/gems/bar@0.0.2.rbi")
baz_rbi = @project.read("sorbet/rbi/gems/baz@0.0.2.rbi")

documentation = <<~RBI
# Most objects are cloneable
RBI

assert_includes(foo_rbi, documentation)
refute_includes(bar_rbi, documentation)
refute_includes(baz_rbi, documentation)

assert_empty_stderr(result)
assert_success_status(result)
end

it "does not generate RBI if namespace contains alias from different gem" do
foo = mock_gem("foo", "0.0.1") do
write!("lib/foo.rb", <<~RB)
module Foo; end
F = Foo
RB
end

bar = mock_gem("bar", "0.0.1") do
write!("lib/bar.rb", <<~RB)
module Foo
module Bar; end
end
F::B = Foo::Bar
RB
end

@project.require_mock_gem(foo, require: false)
@project.require_mock_gem(bar, require: false)

@project.bundle_install!
@project.tapioca("gem foo bar")

assert_project_file_equal("sorbet/rbi/gems/foo@0.0.1.rbi", <<~RBI)
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `foo` gem.
# Please instead update this file by running `bin/tapioca gem foo`.
F = Foo
module Foo; end
RBI

assert_project_file_equal("sorbet/rbi/gems/bar@0.0.1.rbi", <<~RBI)
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `bar` gem.
# Please instead update this file by running `bin/tapioca gem bar`.
module Foo; end
Foo::B = Foo::Bar
module Foo::Bar; end
RBI
end
end

describe "sync" do
Expand Down

0 comments on commit 2c25e6a

Please sign in to comment.