RSpec matchers for Apiwork.
Add to your Gemfile:
gem'apiwork-rspec',group: :testInclude the matchers in your spec_helper.rb or rails_helper.rb:
RSpec.configuredo |config|
config.includeApiwork::RSpec::Matchersendit{is_expected.tohave_key_format(:camel)}it{is_expected.tohave_path_format(:kebab)}it{is_expected.tohave_raises(:bad_request,:internal_server_error)}it{is_expected.tohave_export(:openapi)}it{is_expected.tohave_export(:typescript)}it{is_expected.tohave_resource(:invoices)}it{is_expected.tohave_resource(:invoices).with_only(:index,:show)}it{is_expected.tohave_resource(:lines).under(:invoices).with_except(:destroy)}it{is_expected.tohave_resource(:adjustments).under(:invoices,:lines)}it{is_expected.tohave_resource(:profile).singular}describe_infodoit{is_expected.tohave_title('Billing API')}it{is_expected.tohave_version('1.0.0')}it{is_expected.tohave_summary('A billing API')}it{is_expected.tohave_description('Invoice management and payments')}it{is_expected.tohave_terms_of_service('https://example.com/terms')}it{is_expected.todefine_contact('API Support').with_email('support@example.com').with_url('https://example.com/support')}it{is_expected.todefine_license('MIT').with_url('https://opensource.org/licenses/MIT')}it{is_expected.todefine_server('https://api.example.com').with_description('Production')}enddescribe_object:addressdoit{is_expected.tohave_description('Mailing address')}it{is_expected.tohave_example({street: '123 Main St'})}it{is_expected.tohave_param(:street).of_type(:string)}it{is_expected.tohave_param(:city).of_type(:string)}enddescribe_union:recipientdoit{is_expected.tohave_discriminator(:type)}it{is_expected.tohave_description('Invoice recipient')}it{is_expected.tohave_variant(:customer).of_type(:customer)}it{is_expected.tohave_variant(:company).of_type(:company)}it{is_expected.tohave_variant(:legacy_customer).deprecated.with_description('Use customer instead')}endit{is_expected.todefine_enum(:status).with_values(%w[draftsentpaid]).with_description('Invoice status').with_example('draft')}it{is_expected.todefine_enum(:currency).deprecated}it{is_expected.tohave_representation(InvoiceRepresentation)}it{is_expected.tohave_identifier(:invoices)}it{is_expected.tohave_import(SharedContract,as: :shared)}it{is_expected.tobe_abstract}describe_action:createdoit{is_expected.tohave_summary('Create invoice')}it{is_expected.tohave_description('Creates a new invoice')}it{is_expected.tohave_tags(:billing)}it{is_expected.tohave_raises(:not_found,:conflict)}it{is_expected.tohave_operation_id('createInvoice')}it{is_expected.tobe_deprecated}enddescribe_action:destroydoit{is_expected.tobe_no_content}endTests the request or response. Use with describe_body and describe_query.
describe_action:createdodescribe_requestdodescribe_bodydoit{is_expected.tohave_param(:title).of_type(:string).required.with_description('Invoice title').with_example('Q1 Consulting')}it{is_expected.tohave_param(:notes).of_type(:string).optional.nullable}it{is_expected.tohave_param(:status).with_enum(%w[draftsent]).with_default('draft')}it{is_expected.tohave_param(:customer_email).with_format(:email)}it{is_expected.tohave_param(:amount).of_type(:decimal).with_min(0).with_max(1_000_000)}it{is_expected.tohave_param(:tax_code).deprecated}enddescribe_querydoit{is_expected.tohave_param(:include).of_type(:string).optional}endenddescribe_responsedodescribe_bodydoit{is_expected.tohave_param(:id).of_type(:uuid)}endendendTests an inline type's params. Nestable.
describe_action:createdodescribe_requestdodescribe_bodydoit{is_expected.tohave_param(:address).of_type(:object)}describe_param:addressdoit{is_expected.tohave_param(:street).of_type(:string)}it{is_expected.tohave_param(:city).of_type(:string)}endendendendit{is_expected.tohave_model(Invoice)}it{is_expected.tohave_root(:invoice,:invoices)}it{is_expected.tohave_type_name('CustomInvoice')}it{is_expected.tohave_description('An invoice')}it{is_expected.tohave_example({number: 'INV-001',title: 'Q1 Consulting'})}it{is_expected.tobe_deprecated}it{is_expected.tobe_abstract}it{is_expected.tohave_attribute(:number).of_type(:string).with_description('Invoice number').with_example('INV-001')}it{is_expected.tohave_attribute(:total).of_type(:decimal).filterable.sortable}it{is_expected.tohave_attribute(:title).writable}it{is_expected.tohave_attribute(:title).writable(:create)}it{is_expected.tohave_attribute(:notes).optional.nullable}it{is_expected.tohave_attribute(:notes).empty}it{is_expected.tohave_attribute(:status).with_enum(%w[draftsentpaid]).with_default('draft')}it{is_expected.tohave_attribute(:customer_email).with_format(:email)}it{is_expected.tohave_attribute(:amount).with_min(0).with_max(1_000_000)}it{is_expected.tohave_attribute(:tax_code).deprecated}it{is_expected.tohave_association(:lines).of_type(:has_many).writable.allow_destroy.filterable.sortable.with_description('Invoice line items')}it{is_expected.tohave_association(:lines).writable(:create)}it{is_expected.tohave_association(:customer).of_type(:belongs_to).with_include(:always)}it{is_expected.tohave_association(:payable).polymorphic}it{is_expected.tohave_association(:receipt).with_representation(ReceiptRepresentation)}it{is_expected.tohave_association(:lines).nullable}it{is_expected.tohave_association(:payments).deprecated}Apiwork::API.define'/api/v1'dokey_format:camelexport:openapiinfodotitle'Billing API'version'1.0.0'contactdoname'API Support'email'support@example.com'endlicensedoname'MIT'endserverdourl'https://api.example.com'description'Production'endendenum:status,values: %i[draftsentpaid]object:address,description: 'Mailing address'dostring:streetstring:cityendunion:recipient,discriminator: :typedovarianttag: :customerdoobjectdostring:nameendendvarianttag: :companydoobjectdostring:nameendendendresources:invoicesresource:profileendclassInvoiceContract < Apiwork::Contract::BaserepresentationInvoiceRepresentationimportSharedContract,as: :sharedenum:priority,values: %i[lownormalhigh]object:line_detaildostring:descriptiondecimal:amountendaction:createdosummary'Create invoice'requestdobodydostring:titledecimal:amountendendresponsedobodydouuid:idendendendaction:destroydoresponseno_content: trueendendclassInvoiceRepresentation < Apiwork::Representation::BasemodelInvoiceroot:invoice,:invoicesattribute:title,writable: truehas_many:linesendRSpec.describe'API V1'dosubject{Apiwork::API.find!('/api/v1')}it{is_expected.tohave_key_format(:camel)}it{is_expected.tohave_export(:openapi)}it{is_expected.tohave_resource(:invoices)}it{is_expected.tohave_resource(:profile).singular}it{is_expected.todefine_enum(:status).with_values(%w[draftsentpaid])}describe_infodoit{is_expected.tohave_title('Billing API')}it{is_expected.tohave_version('1.0.0')}it{is_expected.todefine_contact('API Support').with_email('support@example.com')}it{is_expected.todefine_license('MIT')}it{is_expected.todefine_server('https://api.example.com').with_description('Production')}enddescribe_object:addressdoit{is_expected.tohave_description('Mailing address')}it{is_expected.tohave_param(:street).of_type(:string)}it{is_expected.tohave_param(:city).of_type(:string)}enddescribe_union:recipientdoit{is_expected.tohave_discriminator(:type)}it{is_expected.tohave_variant(:customer)}it{is_expected.tohave_variant(:company)}endendRSpec.describeInvoiceContractdosubject{described_class}it{is_expected.tohave_representation(InvoiceRepresentation)}it{is_expected.tohave_import(SharedContract,as: :shared)}it{is_expected.todefine_enum(:priority).with_values(%w[lownormalhigh])}describe_object:line_detaildoit{is_expected.tohave_param(:description).of_type(:string)}it{is_expected.tohave_param(:amount).of_type(:decimal)}enddescribe_action:createdoit{is_expected.tohave_summary('Create invoice')}describe_requestdodescribe_bodydoit{is_expected.tohave_param(:title).of_type(:string)}it{is_expected.tohave_param(:amount).of_type(:decimal)}endenddescribe_responsedodescribe_bodydoit{is_expected.tohave_param(:id).of_type(:uuid)}endendenddescribe_action:destroydoit{is_expected.tobe_no_content}endendRSpec.describeInvoiceRepresentationdosubject{described_class}it{is_expected.tohave_model(Invoice)}it{is_expected.tohave_root(:invoice,:invoices)}it{is_expected.tohave_attribute(:title).of_type(:string).writable}it{is_expected.tohave_association(:lines).of_type(:has_many)}endMIT