Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClientHelper / SpecHelper improvement with source generation tests #267

Merged
merged 14 commits into from
Feb 7, 2025
15 changes: 7 additions & 8 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ namespace :smithy do

spec_paths = []
include_paths = []
tmp_dirs = []
plans = []
rbs_targets = %w[Smithy Smithy::* Smithy::Client]
sig_paths = ['gems/smithy-client/sig']
Dir.glob('gems/smithy/spec/fixtures/endpoints/*/model.json') do |model_path|
test_name = model_path.split('/')[-2]
test_module = test_name.gsub('-', '').camelize
tmpdir = SpecHelper.generate([test_module], :client, { fixture: "endpoints/#{test_name}" })
tmp_dirs << [test_module.to_sym, tmpdir]
plan = SpecHelper.generate_gem(:client, fixture: "endpoints/#{test_name}", module_name: test_module)
plans << plan
tmpdir = plan.destination_root
spec_paths << "#{tmpdir}/spec"
include_paths << "#{tmpdir}/lib"
include_paths << "#{tmpdir}/spec"
Expand All @@ -51,9 +52,7 @@ namespace :smithy do

sh(env, "bundle exec rspec #{specs} #{includes}")
ensure
tmp_dirs.each do |name, tmpdir|
SpecHelper.cleanup([name], tmpdir)
end
plans.each { |plan| SpecHelper.cleanup_gem(plan) }
end

task 'spec' => %w[spec:unit spec:endpoints]
Expand Down Expand Up @@ -96,8 +95,8 @@ namespace :smithy do
task('smithy:spec:endpoints').invoke('rbs_test')
end

desc 'Run RBS spy tests for unit tests and genreated endpoint provider specs.'
task 'rbs' => ['rbs:unit', 'rbs:endpoints']
desc 'Run RBS spy tests for unit tests and generated endpoint provider specs.'
task 'rbs' => %w[rbs:unit rbs:endpoints]
end

namespace 'smithy-client' do
Expand Down
1 change: 1 addition & 0 deletions gems/smithy/lib/smithy/generators/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def gem_files

source_files.each { |file, content| e.yield file, content }
e.yield "lib/#{@gem_name}/customizations.rb", Views::Client::Customizations.new.render
rbs_files.each { |file, content| e.yield file, content }
end
end

Expand Down
8 changes: 6 additions & 2 deletions gems/smithy/lib/smithy/views/client/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ def gem_version
end

def require_plugins
@plugins.map do |plugin|
"require#{'_relative' if plugin.require_relative?} '#{plugin.require_path}'"
requires = []
@plugins.each do |plugin|
next if [email protected]_root && plugin.require_relative?

requires << "require#{'_relative' if plugin.require_relative?} '#{plugin.require_path}'"
end
requires
end

def add_plugins
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
# frozen_string_literal: true

describe 'Component: Client: Request/Response Syntax Examples' do
before(:all) do
@tmpdir = SpecHelper.generate(['ExamplesTrait'], :client)
end

after(:all) do
SpecHelper.cleanup(['ExamplesTrait'], @tmpdir)
end
describe 'Client: Request/Response Syntax Examples' do
include_context 'generated client gem', fixture: 'examples_trait'

it 'generates operation examples' do
expected = <<~EXAMPLE
Expand Down Expand Up @@ -77,7 +71,7 @@
}
end
EXAMPLE
client_file = File.join(@tmpdir, 'lib', 'examples_trait', 'client.rb')
client_file = File.join(@plan.destination_root, 'lib', 'examples_trait', 'client.rb')
expect(expected).to be_in_documentation(client_file, 'ExamplesTrait::Client', 'operation')
end
end
42 changes: 21 additions & 21 deletions gems/smithy/spec/interfaces/client/client_spec.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
# frozen_string_literal: true

describe 'Component: Client', rbs_test: true do
before(:all) do
@tmpdir = SpecHelper.generate(['Weather'], :client)
end
describe 'Client: Client' do
['generated client gem', 'generated client from source code'].each do |context|
next if ENV['SMITHY_RUBY_RBS_TEST'] && context != 'generated client gem'

after(:all) do
SpecHelper.cleanup(['Weather'], @tmpdir)
end
context context do
include_context context, fixture: 'weather'

subject { Weather::Client.new }
subject { Weather::Client.new(endpoint: 'https://example.com') }

# it 'adds the HTTP plugin' do
# expect(Weather::Client.plugins).to include(Smithy::Client::Plugins::NetHTTP)
# end
it 'loads plugins' do
expect(Weather::Client.plugins).to include(Smithy::Client::Plugins::NetHTTP)
end

it 'has operation methods' do
expect(subject).to respond_to(:get_city, :get_current_time, :get_forecast, :list_cities)
end
it 'has operation methods' do
expect(subject).to respond_to(:get_city, :get_current_time, :get_forecast, :list_cities)
end

it 'builds input for operations' do
input = subject.send(:build_input, :get_city, { id: 1 })
expect(input).to be_a(Smithy::Client::Input)
end
it 'builds input for operations' do
input = subject.send(:build_input, :get_city, { id: 1 })
expect(input).to be_a(Smithy::Client::Input)
end

# it 'can call operations' do
# subject.get_city(id: 1)
# end
# it 'can call operations' do
# subject.get_city(city_id: '1')
# end
end
end
end
22 changes: 5 additions & 17 deletions gems/smithy/spec/interfaces/client/client_syntax_example_spec.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
# frozen_string_literal: true

describe 'Component: Client: Request/Response Syntax Examples' do
before(:all) do
@tmpdir = SpecHelper.generate(['SyntaxExamples'], :client)
end

after(:all) do
SpecHelper.cleanup(['SyntaxExamples'], @tmpdir)
end
describe 'Client: Client Request/Response Syntax Examples' do
include_context 'generated client gem', fixture: 'syntax_examples'

it 'generates request and response syntax examples' do
expected = <<~EXAMPLE
Expand Down Expand Up @@ -129,18 +123,12 @@
}
}
EXAMPLE
client_file = File.join(@tmpdir, 'lib', 'syntax_examples', 'client.rb')
client_file = File.join(@plan.destination_root, 'lib', 'syntax_examples', 'client.rb')
expect(expected).to be_in_documentation(client_file, 'SyntaxExamples::Client', 'operation')
end

context 'recursive shapes' do
before(:all) do
@tmpdir = SpecHelper.generate(['Recursive'], :client)
end

after(:all) do
SpecHelper.cleanup(['Recursive'], @tmpdir)
end
include_context 'generated client gem', fixture: 'recursive'

it 'handles recursive shapes' do
expected = <<~EXAMPLE
Expand All @@ -164,7 +152,7 @@
}
}
EXAMPLE
client_file = File.join(@tmpdir, 'lib', 'recursive', 'client.rb')
client_file = File.join(@plan.destination_root, 'lib', 'recursive', 'client.rb')
expect(expected).to be_in_documentation(client_file, 'Recursive::Client', 'operation')
end
end
Expand Down
34 changes: 2 additions & 32 deletions gems/smithy/spec/interfaces/client/customizations_spec.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,5 @@
# frozen_string_literal: true

describe 'Component: Customizations' do
before(:all) do
@tmpdir = SpecHelper.generate(['Weather'], :client)
end

after(:all) do
SpecHelper.cleanup(['Weather'], @tmpdir)
end

subject { Weather::Client.new(endpoint: 'https://example.com') }

it 'should have a customizations file' do
expect(File).to exist(File.join(@tmpdir, 'lib', 'weather', 'customizations.rb'))
end

it 'should require the customizations file' do
expect(require('weather/customizations')).to eq(false)
end

it 'does not overwrite an existing customizations file' do
customization = <<~RUBY
module Weather
# @api private
module Customizations; end
end
RUBY
customizations_file = File.join(@tmpdir, 'lib', 'weather', 'customizations.rb')
expect(File.read(customizations_file)).to_not include(customization)
File.write(customizations_file, customization)
SpecHelper.generate(['Weather'], :client, destination_root: @tmpdir)
expect(File.read(customizations_file)).to include(customization)
end
describe 'Client: Customizations' do
include_examples 'customizations', 'generated client gem'
end
114 changes: 57 additions & 57 deletions gems/smithy/spec/interfaces/client/endpoint_parameters_spec.rb
Original file line number Diff line number Diff line change
@@ -1,71 +1,71 @@
# frozen_string_literal: true

describe 'Component: EndpointParameters', rbs_test: true do
before(:all) do
@tmpdir = SpecHelper.generate(['EndpointBindings'], :client, fixture: 'endpoints/endpoint-bindings')
end
describe 'Client: EndpointParameters', rbs_test: true do
['generated client gem', 'generated client from source code'].each do |context|
next if ENV['SMITHY_RUBY_RBS_TEST'] && context != 'generated client gem'

after(:all) do
SpecHelper.cleanup(['EndpointBindings'], @tmpdir)
end
context context do
include_context context, fixture: 'endpoints/endpoint-bindings', module_name: 'EndpointBindings'

subject { EndpointBindings::EndpointParameters.new }
subject { EndpointBindings::EndpointParameters.new }

describe '#initialize' do
it 'initializes with default values' do
expect(subject.baz).to eq('baz')
expect(subject.boolean_param).to eq(true)
expect(subject.endpoint).to be_nil
expect(subject.bar).to be_nil
end
end
describe '#initialize' do
it 'initializes with default values' do
expect(subject.baz).to eq('baz')
expect(subject.boolean_param).to eq(true)
expect(subject.endpoint).to be_nil
expect(subject.bar).to be_nil
end
end

describe '.create' do
let(:config) do
client = EndpointBindings::Client.new(bar: 'config_bar', endpoint: 'config_endpoint', boolean_param: false)
client.config
end
describe '.create' do
let(:config) do
client = EndpointBindings::Client.new(bar: 'config_bar', endpoint: 'config_endpoint', boolean_param: false)
client.config
end

context 'no_bindings_operation' do
it 'creates with default values and values from config' do
context = double(config: config, operation_name: :no_bindings_operation, params: {})
parameters = EndpointBindings::EndpointParameters.create(context)
expect(parameters.baz).to eq('baz')
expect(parameters.endpoint).to eq('config_endpoint')
expect(parameters.bar).to eq('config_bar')
expect(parameters.boolean_param).to eq(false)
end
end
context 'no_bindings_operation' do
it 'creates with default values and values from config' do
context = double(config: config, operation_name: :no_bindings_operation, params: {})
parameters = EndpointBindings::EndpointParameters.create(context)
expect(parameters.baz).to eq('baz')
expect(parameters.endpoint).to eq('config_endpoint')
expect(parameters.bar).to eq('config_bar')
expect(parameters.boolean_param).to eq(false)
end
end

context 'static_context_operation' do
it 'creates with values from StaticContextParams' do
context = double(config: config, operation_name: :static_context_operation, params: {})
parameters = EndpointBindings::EndpointParameters.create(context)
expect(parameters.bar).to eq('static-context')
end
end
context 'static_context_operation' do
it 'creates with values from StaticContextParams' do
context = double(config: config, operation_name: :static_context_operation, params: {})
parameters = EndpointBindings::EndpointParameters.create(context)
expect(parameters.bar).to eq('static-context')
end
end

context 'context_params_operation' do
it 'creates with values from operation params' do
params = { bar: 'operation-bar' }
context = double(config: config, operation_name: :context_params_operation, params: params)
parameters = EndpointBindings::EndpointParameters.create(context)
expect(parameters.bar).to eq('operation-bar')
end
end
context 'context_params_operation' do
it 'creates with values from operation params' do
params = { bar: 'operation-bar' }
context = double(config: config, operation_name: :context_params_operation, params: params)
parameters = EndpointBindings::EndpointParameters.create(context)
expect(parameters.bar).to eq('operation-bar')
end
end

context 'operation_context_params_operation' do
it 'creates with values from operation params' do
params = {
nested: { bar: 'nested-bar', baz: 'nested-baz' },
boolean_param: false
}
context = double(config: config, operation_name: :operation_context_params_operation, params: params)
context 'operation_context_params_operation' do
it 'creates with values from operation params' do
params = {
nested: { bar: 'nested-bar', baz: 'nested-baz' },
boolean_param: false
}
context = double(config: config, operation_name: :operation_context_params_operation, params: params)

parameters = EndpointBindings::EndpointParameters.create(context)
expect(parameters.bar).to eq('nested-bar')
expect(parameters.baz).to eq('nested-baz')
expect(parameters.boolean_param).to eq(false)
parameters = EndpointBindings::EndpointParameters.create(context)
expect(parameters.bar).to eq('nested-bar')
expect(parameters.baz).to eq('nested-baz')
expect(parameters.boolean_param).to eq(false)
end
end
end
end
end
Expand Down
Loading