Skip to content

Commit

Permalink
ClientHelper / SpecHelper improvement with source generation tests (#267
Browse files Browse the repository at this point in the history
)
  • Loading branch information
mullermp authored Feb 7, 2025
1 parent ecf3548 commit 5c7775e
Show file tree
Hide file tree
Showing 31 changed files with 1,127 additions and 872 deletions.
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 !@plan.destination_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

0 comments on commit 5c7775e

Please sign in to comment.