├── .github ├── renovate.json └── workflows │ ├── release-cpan.yml │ ├── release-github.yml │ ├── release-hex.yml │ ├── release-mvn.yml │ ├── release-npm.yml │ ├── release-nuget.yml │ ├── release-php.yml │ ├── release-pypi.yml │ ├── release-rubygem.yml │ ├── test-codegen.yml │ ├── test-cpp.yml │ ├── test-dotnet.yml │ ├── test-elixir.yml │ ├── test-go.yml │ ├── test-java.yml │ ├── test-javascript.yml │ ├── test-perl.yml │ ├── test-php.yml │ ├── test-python.yml │ └── test-ruby.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── RELEASING.md ├── after.json ├── codegen ├── .rubocop.yml ├── codegen.rb ├── generators │ ├── base.rb │ ├── cpp.rb │ ├── dotnet.rb │ ├── go.rb │ ├── java.rb │ ├── markdown.rb │ ├── perl.rb │ ├── php.rb │ ├── python.rb │ ├── ruby.rb │ ├── text_helpers.rb │ └── typescript.rb └── templates │ ├── cpp.enum.hpp.erb │ ├── cpp.hpp.erb │ ├── dotnet.dotnet.erb │ ├── dotnet.enum.dotnet.erb │ ├── go.enum.go.erb │ ├── go.go.erb │ ├── java.enum.java.erb │ ├── java.java.erb │ ├── markdown.enum.md.erb │ ├── markdown.md.erb │ ├── perl.pm.erb │ ├── php.enum.php.erb │ ├── php.php.erb │ ├── python.enum.py.erb │ ├── python.py.erb │ ├── ruby.enum.rb.erb │ ├── ruby.rb.erb │ ├── typescript.enum.ts.erb │ └── typescript.ts.erb ├── cpp ├── .gitignore ├── CMakeLists.txt ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── VERSION ├── cmake │ ├── cmate │ └── cucumber_messages-config.cmake.in ├── deps.txt ├── include │ └── messages │ │ └── cucumber │ │ └── messages │ │ ├── all.hpp │ │ ├── attachment.hpp │ │ ├── attachment_content_encoding.hpp │ │ ├── background.hpp │ │ ├── ci.hpp │ │ ├── comment.hpp │ │ ├── data_table.hpp │ │ ├── doc_string.hpp │ │ ├── duration.hpp │ │ ├── envelope.hpp │ │ ├── examples.hpp │ │ ├── exception.hpp │ │ ├── feature.hpp │ │ ├── feature_child.hpp │ │ ├── gherkin_document.hpp │ │ ├── git.hpp │ │ ├── group.hpp │ │ ├── hook.hpp │ │ ├── hook_type.hpp │ │ ├── java_method.hpp │ │ ├── java_stack_trace_element.hpp │ │ ├── location.hpp │ │ ├── meta.hpp │ │ ├── parameter_type.hpp │ │ ├── parse_error.hpp │ │ ├── pickle.hpp │ │ ├── pickle_doc_string.hpp │ │ ├── pickle_step.hpp │ │ ├── pickle_step_argument.hpp │ │ ├── pickle_step_type.hpp │ │ ├── pickle_table.hpp │ │ ├── pickle_table_cell.hpp │ │ ├── pickle_table_row.hpp │ │ ├── pickle_tag.hpp │ │ ├── product.hpp │ │ ├── rule.hpp │ │ ├── rule_child.hpp │ │ ├── scenario.hpp │ │ ├── source.hpp │ │ ├── source_media_type.hpp │ │ ├── source_reference.hpp │ │ ├── step.hpp │ │ ├── step_definition.hpp │ │ ├── step_definition_pattern.hpp │ │ ├── step_definition_pattern_type.hpp │ │ ├── step_keyword_type.hpp │ │ ├── step_match_argument.hpp │ │ ├── step_match_arguments_list.hpp │ │ ├── table_cell.hpp │ │ ├── table_row.hpp │ │ ├── tag.hpp │ │ ├── test_case.hpp │ │ ├── test_case_finished.hpp │ │ ├── test_case_started.hpp │ │ ├── test_run_finished.hpp │ │ ├── test_run_hook_finished.hpp │ │ ├── test_run_hook_started.hpp │ │ ├── test_run_started.hpp │ │ ├── test_step.hpp │ │ ├── test_step_finished.hpp │ │ ├── test_step_result.hpp │ │ ├── test_step_result_status.hpp │ │ ├── test_step_started.hpp │ │ ├── timestamp.hpp │ │ └── undefined_parameter_type.hpp ├── project.yaml └── src │ ├── CMakeLists.txt │ └── lib │ ├── CMakeLists.txt │ └── messages │ ├── CMakeLists.txt │ ├── cucumber │ └── messages │ │ ├── attachment.cpp │ │ ├── attachment_content_encoding.cpp │ │ ├── background.cpp │ │ ├── ci.cpp │ │ ├── comment.cpp │ │ ├── data_table.cpp │ │ ├── doc_string.cpp │ │ ├── duration.cpp │ │ ├── envelope.cpp │ │ ├── examples.cpp │ │ ├── exception.cpp │ │ ├── feature.cpp │ │ ├── feature_child.cpp │ │ ├── gherkin_document.cpp │ │ ├── git.cpp │ │ ├── group.cpp │ │ ├── hook.cpp │ │ ├── hook_type.cpp │ │ ├── java_method.cpp │ │ ├── java_stack_trace_element.cpp │ │ ├── location.cpp │ │ ├── meta.cpp │ │ ├── parameter_type.cpp │ │ ├── parse_error.cpp │ │ ├── pickle.cpp │ │ ├── pickle_doc_string.cpp │ │ ├── pickle_step.cpp │ │ ├── pickle_step_argument.cpp │ │ ├── pickle_step_type.cpp │ │ ├── pickle_table.cpp │ │ ├── pickle_table_cell.cpp │ │ ├── pickle_table_row.cpp │ │ ├── pickle_tag.cpp │ │ ├── product.cpp │ │ ├── rule.cpp │ │ ├── rule_child.cpp │ │ ├── scenario.cpp │ │ ├── source.cpp │ │ ├── source_media_type.cpp │ │ ├── source_reference.cpp │ │ ├── step.cpp │ │ ├── step_definition.cpp │ │ ├── step_definition_pattern.cpp │ │ ├── step_definition_pattern_type.cpp │ │ ├── step_keyword_type.cpp │ │ ├── step_match_argument.cpp │ │ ├── step_match_arguments_list.cpp │ │ ├── table_cell.cpp │ │ ├── table_row.cpp │ │ ├── tag.cpp │ │ ├── test_case.cpp │ │ ├── test_case_finished.cpp │ │ ├── test_case_started.cpp │ │ ├── test_run_finished.cpp │ │ ├── test_run_hook_finished.cpp │ │ ├── test_run_hook_started.cpp │ │ ├── test_run_started.cpp │ │ ├── test_step.cpp │ │ ├── test_step_finished.cpp │ │ ├── test_step_result.cpp │ │ ├── test_step_result_status.cpp │ │ ├── test_step_started.cpp │ │ ├── timestamp.cpp │ │ ├── undefined_parameter_type.cpp │ │ ├── utils.cpp │ │ └── utils.hpp │ └── link.yaml ├── dotnet ├── .devcontainer │ └── devcontainer.json ├── .gitignore ├── .vs │ └── ProjectEvaluation │ │ └── cucumber.messages.strings.v8.bin ├── Cucumber.Messages.Specs │ ├── BasicMessageSerializationTests.cs │ ├── ConvertersTests.cs │ ├── Cucumber.Messages.Specs.csproj │ ├── CucumberMessagEnumConverter.cs │ ├── MessageToNdjsonWriterSUT.cs │ ├── MessagesTest.cs │ ├── NdJsonMessageReaderSUT.cs │ ├── NdjsonSerializer.cs │ ├── NdjsonStreamSerializationTests.cs │ └── ProtocolVersionTest.cs ├── Cucumber.Messages.sln ├── Cucumber.Messages │ ├── .gitignore │ ├── .releaseable │ ├── Converters.cs │ ├── Cucumber.Messages.csproj │ ├── Cucumber.Messages.snk │ ├── MessageToNdjsonWriter.cs │ ├── NdjsonMessageReader.cs │ ├── ProtocolVersion.cs │ ├── Resources │ │ └── cucumber-mark-green-128.png │ └── generated │ │ ├── Attachment.cs │ │ ├── AttachmentContentEncoding.cs │ │ ├── Background.cs │ │ ├── Ci.cs │ │ ├── Comment.cs │ │ ├── DataTable.cs │ │ ├── DocString.cs │ │ ├── Duration.cs │ │ ├── Envelope.cs │ │ ├── Examples.cs │ │ ├── Exception.cs │ │ ├── Feature.cs │ │ ├── FeatureChild.cs │ │ ├── GherkinDocument.cs │ │ ├── Git.cs │ │ ├── Group.cs │ │ ├── Hook.cs │ │ ├── HookType.cs │ │ ├── JavaMethod.cs │ │ ├── JavaStackTraceElement.cs │ │ ├── Location.cs │ │ ├── Meta.cs │ │ ├── ParameterType.cs │ │ ├── ParseError.cs │ │ ├── Pickle.cs │ │ ├── PickleDocString.cs │ │ ├── PickleStep.cs │ │ ├── PickleStepArgument.cs │ │ ├── PickleStepType.cs │ │ ├── PickleTable.cs │ │ ├── PickleTableCell.cs │ │ ├── PickleTableRow.cs │ │ ├── PickleTag.cs │ │ ├── Product.cs │ │ ├── Rule.cs │ │ ├── RuleChild.cs │ │ ├── Scenario.cs │ │ ├── Source.cs │ │ ├── SourceMediaType.cs │ │ ├── SourceReference.cs │ │ ├── Step.cs │ │ ├── StepDefinition.cs │ │ ├── StepDefinitionPattern.cs │ │ ├── StepDefinitionPatternType.cs │ │ ├── StepKeywordType.cs │ │ ├── StepMatchArgument.cs │ │ ├── StepMatchArgumentsList.cs │ │ ├── TableCell.cs │ │ ├── TableRow.cs │ │ ├── Tag.cs │ │ ├── TestCase.cs │ │ ├── TestCaseFinished.cs │ │ ├── TestCaseStarted.cs │ │ ├── TestRunFinished.cs │ │ ├── TestRunHookFinished.cs │ │ ├── TestRunHookStarted.cs │ │ ├── TestRunStarted.cs │ │ ├── TestStep.cs │ │ ├── TestStepFinished.cs │ │ ├── TestStepResult.cs │ │ ├── TestStepResultStatus.cs │ │ ├── TestStepStarted.cs │ │ ├── Timestamp.cs │ │ └── UndefinedParameterType.cs ├── LICENSE └── Makefile ├── elixir ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── default.mk ├── lib │ ├── cucumber_message.ex │ └── cucumber_messages │ │ ├── generated │ │ └── .gitignore │ │ └── writer.ex ├── messages.proto ├── mix.exs ├── mix.lock └── test │ ├── cucumber_message_test.exs │ └── test_helper.exs ├── go ├── .gitignore ├── LICENSE ├── Makefile ├── go.mod ├── go.sum ├── id_generator.go ├── id_generator_test.go ├── messages.go ├── messages_test.go ├── time_conversion.go └── time_conversion_test.go ├── java ├── .gitignore ├── Makefile ├── README.md ├── pom.xml └── src │ ├── generated │ └── java │ │ └── io │ │ └── cucumber │ │ └── messages │ │ └── types │ │ ├── Attachment.java │ │ ├── AttachmentContentEncoding.java │ │ ├── Background.java │ │ ├── Ci.java │ │ ├── Comment.java │ │ ├── DataTable.java │ │ ├── DocString.java │ │ ├── Duration.java │ │ ├── Envelope.java │ │ ├── Examples.java │ │ ├── Exception.java │ │ ├── Feature.java │ │ ├── FeatureChild.java │ │ ├── GherkinDocument.java │ │ ├── Git.java │ │ ├── Group.java │ │ ├── Hook.java │ │ ├── HookType.java │ │ ├── JavaMethod.java │ │ ├── JavaStackTraceElement.java │ │ ├── Location.java │ │ ├── Meta.java │ │ ├── ParameterType.java │ │ ├── ParseError.java │ │ ├── Pickle.java │ │ ├── PickleDocString.java │ │ ├── PickleStep.java │ │ ├── PickleStepArgument.java │ │ ├── PickleStepType.java │ │ ├── PickleTable.java │ │ ├── PickleTableCell.java │ │ ├── PickleTableRow.java │ │ ├── PickleTag.java │ │ ├── Product.java │ │ ├── Rule.java │ │ ├── RuleChild.java │ │ ├── Scenario.java │ │ ├── Source.java │ │ ├── SourceMediaType.java │ │ ├── SourceReference.java │ │ ├── Step.java │ │ ├── StepDefinition.java │ │ ├── StepDefinitionPattern.java │ │ ├── StepDefinitionPatternType.java │ │ ├── StepKeywordType.java │ │ ├── StepMatchArgument.java │ │ ├── StepMatchArgumentsList.java │ │ ├── TableCell.java │ │ ├── TableRow.java │ │ ├── Tag.java │ │ ├── TestCase.java │ │ ├── TestCaseFinished.java │ │ ├── TestCaseStarted.java │ │ ├── TestRunFinished.java │ │ ├── TestRunHookFinished.java │ │ ├── TestRunHookStarted.java │ │ ├── TestRunStarted.java │ │ ├── TestStep.java │ │ ├── TestStepFinished.java │ │ ├── TestStepResult.java │ │ ├── TestStepResultStatus.java │ │ ├── TestStepStarted.java │ │ ├── Timestamp.java │ │ └── UndefinedParameterType.java │ ├── main │ ├── java │ │ └── io │ │ │ └── cucumber │ │ │ └── messages │ │ │ ├── Convertor.java │ │ │ ├── IdGenerator.java │ │ │ ├── MessageToNdjsonWriter.java │ │ │ ├── NdjsonToMessageIterable.java │ │ │ ├── ProtocolVersion.java │ │ │ └── TimeConversion.java │ └── resources │ │ └── io │ │ └── cucumber │ │ └── messages │ │ └── version.properties │ └── test │ └── java │ └── io │ └── cucumber │ └── messages │ ├── ConvertorTest.java │ ├── Jackson.java │ ├── JacksonTest.java │ ├── MessagesTest.java │ ├── NdjsonSerializationTest.java │ └── ProtocolVersionTest.java ├── javascript ├── .gitignore ├── .mocharc.json ├── LICENSE ├── Makefile ├── README.md ├── package-lock.json ├── package.cjs.json ├── package.json ├── schema │ ├── .gitignore │ ├── .gitkeep │ └── .npmignore ├── src │ ├── IdGenerator.ts │ ├── TimeConversion.ts │ ├── getWorstTestStepResult.ts │ ├── index.ts │ ├── messages.ts │ ├── parseEnvelope.ts │ └── version.ts ├── test │ ├── TimeConversionTest.ts │ ├── getWorstTestStepResultsTest.ts │ └── messagesTest.ts ├── tsconfig.build-cjs.json ├── tsconfig.build-esm.json ├── tsconfig.build.json └── tsconfig.json ├── jsonschema ├── Attachment.json ├── Duration.json ├── Envelope.json ├── Exception.json ├── GherkinDocument.json ├── Hook.json ├── Location.json ├── Meta.json ├── ParameterType.json ├── ParseError.json ├── Pickle.json ├── Source.json ├── SourceReference.json ├── StepDefinition.json ├── TestCase.json ├── TestCaseFinished.json ├── TestCaseStarted.json ├── TestRunFinished.json ├── TestRunHookFinished.json ├── TestRunHookStarted.json ├── TestRunStarted.json ├── TestStepFinished.json ├── TestStepResult.json ├── TestStepStarted.json ├── Timestamp.json └── UndefinedParameterType.json ├── messages-stream.svg ├── messages.md ├── messages.monopic ├── messages.png ├── package-lock.json ├── package.json ├── perl ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── VERSION ├── cpanfile ├── dist.ini ├── lib │ └── Cucumber │ │ ├── Messages.pm │ │ └── Messages │ │ └── Message.pm └── t │ ├── 01-load.t │ ├── 02-instantiation.t │ ├── 03-deserialize.t │ └── compatibility-kit │ ├── .gitignore │ ├── package-lock.json │ └── package.json ├── php ├── .gitignore ├── .php-cs-fixer.php ├── LICENSE ├── Makefile ├── README.md ├── composer.json ├── phpunit.xml ├── psalm.xml ├── src-generated │ ├── Attachment.php │ ├── Attachment │ │ └── ContentEncoding.php │ ├── Background.php │ ├── Ci.php │ ├── Comment.php │ ├── DataTable.php │ ├── DocString.php │ ├── Duration.php │ ├── Envelope.php │ ├── Examples.php │ ├── Exception.php │ ├── Feature.php │ ├── FeatureChild.php │ ├── GherkinDocument.php │ ├── Git.php │ ├── Group.php │ ├── Hook.php │ ├── Hook │ │ └── Type.php │ ├── JavaMethod.php │ ├── JavaStackTraceElement.php │ ├── Location.php │ ├── Meta.php │ ├── ParameterType.php │ ├── ParseError.php │ ├── Pickle.php │ ├── PickleDocString.php │ ├── PickleStep.php │ ├── PickleStep │ │ └── Type.php │ ├── PickleStepArgument.php │ ├── PickleTable.php │ ├── PickleTableCell.php │ ├── PickleTableRow.php │ ├── PickleTag.php │ ├── Product.php │ ├── Rule.php │ ├── RuleChild.php │ ├── Scenario.php │ ├── Source.php │ ├── Source │ │ └── MediaType.php │ ├── SourceReference.php │ ├── Step.php │ ├── Step │ │ └── KeywordType.php │ ├── StepDefinition.php │ ├── StepDefinitionPattern.php │ ├── StepDefinitionPattern │ │ └── Type.php │ ├── StepMatchArgument.php │ ├── StepMatchArgumentsList.php │ ├── TableCell.php │ ├── TableRow.php │ ├── Tag.php │ ├── TestCase.php │ ├── TestCaseFinished.php │ ├── TestCaseStarted.php │ ├── TestRunFinished.php │ ├── TestRunHookFinished.php │ ├── TestRunHookStarted.php │ ├── TestRunStarted.php │ ├── TestStep.php │ ├── TestStepFinished.php │ ├── TestStepResult.php │ ├── TestStepResult │ │ └── Status.php │ ├── TestStepStarted.php │ ├── Timestamp.php │ └── UndefinedParameterType.php ├── src │ ├── DecodingException.php │ ├── DecodingException │ │ ├── MalformedJsonException.php │ │ ├── SchemaViolationException.php │ │ └── UnexpectedDecodingException.php │ ├── Id │ │ ├── IdGenerator.php │ │ ├── IncrementingIdGenerator.php │ │ └── UuidIdGenerator.php │ ├── JsonEncodingTrait.php │ └── Streams │ │ ├── NdJson │ │ ├── NdJsonStreamReader.php │ │ └── NdJsonStreamWriter.php │ │ ├── StreamReader.php │ │ ├── StreamWriter.php │ │ └── WithFileHandleTrait.php └── tests │ ├── AcceptanceTest.php │ ├── EnvelopeTest.php │ ├── Id │ ├── IdGeneratorTestTrait.php │ ├── IncrementingIdGeneratorTest.php │ └── UuidIdGeneratorTest.php │ ├── JsonDecodingTraitTest.php │ └── Samples │ └── minimal.feature.ndjson ├── python ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── pyproject.toml ├── pytest.ini ├── src │ └── cucumber_messages │ │ ├── __init__.py │ │ ├── _message_enums.py │ │ ├── _messages.py │ │ └── json_converter.py └── tests │ ├── conftest.py │ ├── test_json_converter.py │ ├── test_messages.py │ └── test_model_load.py ├── ruby ├── .gitignore ├── .rspec ├── .rubocop.yml ├── Gemfile ├── LICENSE ├── Makefile ├── README.md ├── Rakefile ├── VERSION ├── cucumber-messages.gemspec ├── lib │ └── cucumber │ │ ├── messages.rb │ │ └── messages │ │ ├── attachment.rb │ │ ├── attachment_content_encoding.rb │ │ ├── background.rb │ │ ├── ci.rb │ │ ├── comment.rb │ │ ├── data_table.rb │ │ ├── doc_string.rb │ │ ├── duration.rb │ │ ├── envelope.rb │ │ ├── examples.rb │ │ ├── exception.rb │ │ ├── feature.rb │ │ ├── feature_child.rb │ │ ├── gherkin_document.rb │ │ ├── git.rb │ │ ├── group.rb │ │ ├── helpers │ │ ├── id_generator.rb │ │ ├── id_generator │ │ │ ├── incrementing.rb │ │ │ └── uuid.rb │ │ ├── ndjson_to_message_enumerator.rb │ │ └── time_conversion.rb │ │ ├── hook.rb │ │ ├── hook_type.rb │ │ ├── java_method.rb │ │ ├── java_stack_trace_element.rb │ │ ├── location.rb │ │ ├── message.rb │ │ ├── meta.rb │ │ ├── parameter_type.rb │ │ ├── parse_error.rb │ │ ├── pickle.rb │ │ ├── pickle_doc_string.rb │ │ ├── pickle_step.rb │ │ ├── pickle_step_argument.rb │ │ ├── pickle_step_type.rb │ │ ├── pickle_table.rb │ │ ├── pickle_table_cell.rb │ │ ├── pickle_table_row.rb │ │ ├── pickle_tag.rb │ │ ├── product.rb │ │ ├── rule.rb │ │ ├── rule_child.rb │ │ ├── scenario.rb │ │ ├── source.rb │ │ ├── source_media_type.rb │ │ ├── source_reference.rb │ │ ├── step.rb │ │ ├── step_definition.rb │ │ ├── step_definition_pattern.rb │ │ ├── step_definition_pattern_type.rb │ │ ├── step_keyword_type.rb │ │ ├── step_match_argument.rb │ │ ├── step_match_arguments_list.rb │ │ ├── table_cell.rb │ │ ├── table_row.rb │ │ ├── tag.rb │ │ ├── test_case.rb │ │ ├── test_case_finished.rb │ │ ├── test_case_started.rb │ │ ├── test_run_finished.rb │ │ ├── test_run_hook_finished.rb │ │ ├── test_run_hook_started.rb │ │ ├── test_run_started.rb │ │ ├── test_step.rb │ │ ├── test_step_finished.rb │ │ ├── test_step_result.rb │ │ ├── test_step_result_status.rb │ │ ├── test_step_started.rb │ │ ├── timestamp.rb │ │ └── undefined_parameter_type.rb └── spec │ ├── cucumber │ └── messages │ │ ├── acceptance_spec.rb │ │ ├── helpers │ │ ├── id_generator │ │ │ ├── incrementing_spec.rb │ │ │ └── uuid_spec.rb │ │ ├── ndjson_to_message_enumerator_spec.rb │ │ └── time_conversion_spec.rb │ │ └── message_spec.rb │ ├── spec_helper.rb │ └── support │ ├── comprehensive_message.rb │ ├── enum_message.rb │ └── simple_message.rb └── validate.cjs /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "github>cucumber/renovate-config" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.github/workflows/release-cpan.yml: -------------------------------------------------------------------------------- 1 | name: Release Perl 2 | 3 | on: 4 | push: 5 | branches: [release/*] 6 | 7 | jobs: 8 | publish-cpan: 9 | name: Publish to CPAN 10 | runs-on: ubuntu-latest 11 | environment: Release 12 | permissions: 13 | contents: write 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: cucumber/action-publish-cpan@v1.0.1 17 | with: 18 | cpan-user: ${{ secrets.CPAN_USER }} 19 | cpan-password: ${{ secrets.CPAN_PASSWORD }} 20 | working-directory: 'perl' 21 | -------------------------------------------------------------------------------- /.github/workflows/release-github.yml: -------------------------------------------------------------------------------- 1 | name: Release on GitHub 2 | 3 | on: 4 | push: 5 | branches: [release/*] 6 | 7 | jobs: 8 | create-github-release: 9 | name: Create GitHub Release and Git tag 10 | runs-on: ubuntu-latest 11 | environment: Release 12 | permissions: 13 | contents: write 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: cucumber/action-create-github-release@v1.1.1 17 | with: 18 | github-token: ${{ secrets.GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /.github/workflows/release-hex.yml: -------------------------------------------------------------------------------- 1 | name: Release Elixir 2 | 3 | on: 4 | push: 5 | branches: [release/*] 6 | 7 | jobs: 8 | publish-hex: 9 | name: Publish to hex.pm 10 | runs-on: ubuntu-latest 11 | environment: Release 12 | permissions: 13 | contents: write 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | - name: Setup Beam 18 | uses: erlef/setup-beam@v1 19 | with: 20 | otp-version: '27.1' 21 | elixir-version: '1.17' 22 | - name: Install Protoc 23 | uses: arduino/setup-protoc@v1 24 | - name: Run Tests 25 | run: make 26 | working-directory: elixir 27 | - name: Publish to hex.pm 28 | uses: cucumber/action-publish-hex@v1.0.0 29 | with: 30 | hex-api-key: ${{ secrets.HEX_API_KEY }} 31 | working-directory: 'elixir' 32 | -------------------------------------------------------------------------------- /.github/workflows/release-mvn.yml: -------------------------------------------------------------------------------- 1 | name: Release Java 2 | 3 | on: 4 | push: 5 | branches: [release/*] 6 | 7 | jobs: 8 | publish-mvn: 9 | name: Publish Maven Package 10 | runs-on: ubuntu-latest 11 | environment: Release 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/setup-java@v4 15 | with: 16 | distribution: 'temurin' 17 | java-version: '11' 18 | cache: 'maven' 19 | - uses: cucumber/action-publish-mvn@v3.0.0 20 | with: 21 | gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} 22 | gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }} 23 | nexus-username: ${{ secrets.SONATYPE_USERNAME }} 24 | nexus-password: ${{ secrets.SONATYPE_PASSWORD }} 25 | working-directory: java 26 | -------------------------------------------------------------------------------- /.github/workflows/release-npm.yml: -------------------------------------------------------------------------------- 1 | name: Release JavaScript 2 | 3 | on: 4 | push: 5 | branches: [release/*] 6 | 7 | jobs: 8 | publish-npm: 9 | name: Publish NPM module 10 | runs-on: ubuntu-latest 11 | environment: Release 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/setup-node@v4 15 | with: 16 | node-version: '22' 17 | cache: 'npm' 18 | cache-dependency-path: javascript/package-lock.json 19 | - run: npm install-test 20 | working-directory: javascript 21 | - uses: cucumber/action-publish-npm@v1.1.1 22 | with: 23 | npm-token: ${{ secrets.NPM_TOKEN }} 24 | working-directory: javascript 25 | -------------------------------------------------------------------------------- /.github/workflows/release-nuget.yml: -------------------------------------------------------------------------------- 1 | name: Release dotNET 2 | 3 | on: 4 | push: 5 | branches: 6 | - "release/*" 7 | 8 | jobs: 9 | publish-nuget: 10 | name: Publish package to NuGet.org 11 | runs-on: ubuntu-latest 12 | environment: Release 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Setup .NET 16 | uses: actions/setup-dotnet@v4 17 | with: 18 | dotnet-version: 8.0.x 19 | - uses: cucumber/action-publish-nuget@v1.0.0 20 | with: 21 | nuget-api-key: ${{ secrets.NUGET_API_KEY }} 22 | working-directory: "dotnet" 23 | -------------------------------------------------------------------------------- /.github/workflows/release-php.yml: -------------------------------------------------------------------------------- 1 | name: Release PHP 2 | 3 | on: 4 | push: 5 | branches: [release/*] 6 | 7 | jobs: 8 | publish-php-subrepo: 9 | name: Publish to cucumber/php subrepo 10 | runs-on: ubuntu-latest 11 | environment: Release 12 | permissions: 13 | contents: write 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: '0' 18 | - uses: cucumber/action-publish-subrepo@v1.1.1 19 | with: 20 | working-directory: php 21 | github-token: ${{ secrets.CUKEBOT_GITHUB_TOKEN }} 22 | -------------------------------------------------------------------------------- /.github/workflows/release-pypi.yml: -------------------------------------------------------------------------------- 1 | name: Release Python 2 | 3 | on: 4 | push: 5 | branches: [release/*] 6 | 7 | jobs: 8 | publish-pypi: 9 | name: Publish PyPI Package 10 | runs-on: ubuntu-latest 11 | environment: Release 12 | permissions: 13 | id-token: write 14 | defaults: 15 | run: 16 | working-directory: python 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@v4 20 | 21 | - name: Set up Python 3.13 22 | uses: actions/setup-python@v5 23 | with: 24 | python-version: "3.13" 25 | 26 | - name: Show Python version 27 | run: python --version 28 | 29 | - name: Build package 30 | run: | 31 | python -m pip install build twine 32 | python -m build 33 | twine check --strict dist/* 34 | 35 | - name: Publish package distributions to PyPI 36 | uses: pypa/gh-action-pypi-publish@release/v1 37 | with: 38 | packages-dir: python/dist 39 | -------------------------------------------------------------------------------- /.github/workflows/release-rubygem.yml: -------------------------------------------------------------------------------- 1 | name: Release Ruby 2 | 3 | on: 4 | push: 5 | branches: [release/*] 6 | 7 | jobs: 8 | publish-rubygem: 9 | name: Publish Ruby Gem 10 | runs-on: ubuntu-latest 11 | environment: Release 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: ruby/setup-ruby@v1 15 | with: 16 | ruby-version: '3.3' 17 | bundler-cache: true 18 | - uses: cucumber/action-publish-rubygem@v1.0.0 19 | with: 20 | rubygems_api_key: ${{ secrets.RUBYGEMS_API_KEY }} 21 | working_directory: ruby 22 | -------------------------------------------------------------------------------- /.github/workflows/test-codegen.yml: -------------------------------------------------------------------------------- 1 | name: test-codegen 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - renovate/** 8 | pull_request: 9 | branches: 10 | - main 11 | workflow_call: 12 | 13 | jobs: 14 | test-codegen: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: Set up Node 21 | uses: actions/setup-node@v4 22 | with: 23 | node-version: 18 24 | cache: "npm" 25 | 26 | - name: validate the json schemas 27 | run: make validate 28 | 29 | - name: Set up Ruby 30 | uses: ruby/setup-ruby@v1 31 | with: 32 | ruby-version: '3.1' 33 | 34 | - name: generate code for all languages 35 | run: | 36 | make clean-all 37 | make generate-all 38 | 39 | - name: check the repo is still clean after generation 40 | run: | 41 | git status --porcelain 42 | git diff HEAD 43 | [ -z "$(git status --porcelain)" ] 44 | -------------------------------------------------------------------------------- /.github/workflows/test-cpp.yml: -------------------------------------------------------------------------------- 1 | name: test-cpp 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - cpp* 8 | - renovate/** 9 | pull_request: 10 | branches: 11 | - main 12 | workflow_call: 13 | 14 | jobs: 15 | test-cpp: 16 | strategy: 17 | matrix: 18 | config: 19 | - os: ubuntu-latest 20 | cc: gcc 21 | - os: ubuntu-latest 22 | cc: clang 23 | - os: macos-latest 24 | cc: clang 25 | - os: windows-latest 26 | cc: cl 27 | runs-on: ${{ matrix.config.os }} 28 | steps: 29 | - uses: actions/checkout@v4 30 | - uses: ilammy/msvc-dev-cmd@v1 31 | - name: install dependencies 32 | working-directory: cpp 33 | run: | 34 | cmake -P cmake/cmate --cc=${{ matrix.config.cc }} install 35 | 36 | - name: configure and build 37 | working-directory: cpp 38 | run: | 39 | cmake -P cmake/cmate --cc=${{ matrix.config.cc }} build --release 40 | -------------------------------------------------------------------------------- /.github/workflows/test-dotnet.yml: -------------------------------------------------------------------------------- 1 | name: test-dotnet 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - renovate/** 8 | pull_request: 9 | branches: 10 | - main 11 | workflow_call: 12 | 13 | jobs: 14 | test-dotnet: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: actions/setup-dotnet@v4 20 | with: 21 | dotnet-version: '8.0.x' 22 | 23 | - name: run tests 24 | run: | 25 | dotnet test 26 | working-directory: dotnet 27 | -------------------------------------------------------------------------------- /.github/workflows/test-elixir.yml: -------------------------------------------------------------------------------- 1 | name: test-elixir 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - renovate/** 8 | pull_request: 9 | branches: 10 | - main 11 | workflow_call: 12 | 13 | jobs: 14 | test-elixir: 15 | name: Test Elixir 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v4 21 | - name: Setup Beam 22 | uses: erlef/setup-beam@v1 23 | with: 24 | otp-version: '27.1' 25 | elixir-version: '1.17' 26 | 27 | - name: Install Protoc 28 | uses: arduino/setup-protoc@v1 29 | 30 | - name: Run Tests 31 | run: make 32 | working-directory: elixir 33 | 34 | -------------------------------------------------------------------------------- /.github/workflows/test-go.yml: -------------------------------------------------------------------------------- 1 | name: test-go 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - renovate/** 8 | pull_request: 9 | branches: 10 | - main 11 | workflow_call: 12 | 13 | jobs: 14 | test-go: 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | os: 20 | - ubuntu-latest 21 | go: ['1.20.x', '1.21.x'] 22 | include: 23 | - os: windows-latest 24 | go: '1.21.x' 25 | - os: macos-latest 26 | go: '1.21.x' 27 | 28 | steps: 29 | - uses: actions/checkout@v4 30 | - name: Set up Go 31 | uses: actions/setup-go@v5 32 | with: 33 | go-version: ${{ matrix.go }} 34 | 35 | - name: lint 36 | working-directory: go 37 | run: gofmt -w . 38 | 39 | - name: test 40 | working-directory: go 41 | run: go test --v ./... 42 | -------------------------------------------------------------------------------- /.github/workflows/test-java.yml: -------------------------------------------------------------------------------- 1 | name: test-java 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - renovate/** 8 | pull_request: 9 | branches: 10 | - main 11 | workflow_call: 12 | 13 | jobs: 14 | test-java: 15 | name: Java ${{ matrix.java }} ${{ matrix.os }} 16 | runs-on: ${{ matrix.os }} 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | os: 21 | - ubuntu-latest 22 | java: ["11", "17"] 23 | include: 24 | - os: windows-latest 25 | java: "17" 26 | - os: macos-latest 27 | java: "17" 28 | 29 | steps: 30 | - uses: actions/checkout@v4 31 | 32 | - uses: actions/setup-java@v4 33 | with: 34 | distribution: "temurin" 35 | java-version: ${{ matrix.java }} 36 | cache: "maven" 37 | 38 | - run: mvn install 39 | working-directory: java 40 | 41 | - run: mvn test 42 | working-directory: java 43 | -------------------------------------------------------------------------------- /.github/workflows/test-perl.yml: -------------------------------------------------------------------------------- 1 | name: test-perl 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - renovate/** 8 | pull_request: 9 | branches: 10 | - main 11 | workflow_call: 12 | 13 | jobs: 14 | test-perl: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: install cpanm and multiple modules 21 | uses: perl-actions/install-with-cpanm@v1 22 | with: 23 | cpanfile: "perl/cpanfile" 24 | 25 | - name: install the CCK 26 | run: npm ci 27 | working-directory: perl/t/compatibility-kit 28 | 29 | - name: run tests 30 | run: | 31 | prove -l 32 | AUTHOR_TESTS=1 prove -l 33 | working-directory: perl 34 | -------------------------------------------------------------------------------- /.github/workflows/test-ruby.yml: -------------------------------------------------------------------------------- 1 | name: test-ruby 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - renovate/** 8 | pull_request: 9 | branches: 10 | - main 11 | workflow_call: 12 | 13 | jobs: 14 | test-ruby: 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | os: 20 | - ubuntu-latest 21 | ruby: ['3.0', '3.1', '3.2', '3.3'] 22 | include: 23 | - os: macos-latest 24 | ruby: '3.3' 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | - uses: ruby/setup-ruby@v1 29 | with: 30 | ruby-version: ${{ matrix.ruby }} 31 | bundler-cache: true 32 | working-directory: ruby 33 | - run: bundle exec rake 34 | working-directory: ruby 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | *.iml 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cucumber Ltd and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /RELEASING.md: -------------------------------------------------------------------------------- 1 | See [.github/RELEASING](https://github.com/cucumber/.github/blob/main/RELEASING.md). 2 | -------------------------------------------------------------------------------- /codegen/.rubocop.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - rubocop-performance 3 | 4 | AllCops: 5 | TargetRubyVersion: 3.0 6 | NewCops: enable 7 | 8 | Style/RegexpLiteral: 9 | AllowInnerSlashes: true 10 | -------------------------------------------------------------------------------- /codegen/codegen.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'generators/text_helpers' 4 | 5 | require_relative 'generators/base' 6 | 7 | require_relative 'generators/cpp' 8 | require_relative 'generators/dotnet' 9 | require_relative 'generators/go' 10 | require_relative 'generators/java' 11 | require_relative 'generators/markdown' 12 | require_relative 'generators/perl' 13 | require_relative 'generators/php' 14 | require_relative 'generators/python' 15 | require_relative 'generators/ruby' 16 | require_relative 'generators/typescript' 17 | 18 | clazz = Object.const_get(ARGV[0]) 19 | template_name = ARGV[1] 20 | clazz.new.generate(template_name) 21 | -------------------------------------------------------------------------------- /codegen/generators/cpp.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Generator 4 | # Generator::Cpp 5 | # Automatic Code generation overrides for the C++ programming language 6 | class Cpp < Base 7 | def array_type_for(type_name) 8 | "std::vector<#{type_name}>" 9 | end 10 | 11 | def format_description(raw_description, indent_string: '') 12 | return '' if raw_description.nil? 13 | 14 | raw_description 15 | .split("\n") 16 | .map(&:strip) 17 | .reject { |line| line == '*' } 18 | .map { |line| "// #{line}".rstrip } 19 | .join("\n#{indent_string}") 20 | end 21 | 22 | private 23 | 24 | def language_translations_for_data_types 25 | { 26 | 'integer' => 'std::size_t', 27 | 'string' => 'std::string', 28 | 'boolean' => 'bool' 29 | } 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /codegen/generators/dotnet.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Generator 4 | # Generator::Dotnet 5 | # Automatic Code generation overrides for the .NET programming language 6 | class Dotnet < Base 7 | def array_type_for(type_name) 8 | "List<#{type_name}>" 9 | end 10 | 11 | def format_description(raw_description, indent_string: '') 12 | return '' if raw_description.nil? 13 | 14 | raw_description 15 | .split("\n") 16 | .map(&:strip) 17 | .reject { |line| line == '*' } 18 | .map { |line| " * #{line}".rstrip } 19 | .join("\n#{indent_string}") 20 | end 21 | 22 | private 23 | 24 | def language_translations_for_data_types 25 | { 26 | 'integer' => 'long', 27 | 'string' => 'string', 28 | 'boolean' => 'bool' 29 | } 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /codegen/generators/go.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Generator 4 | # Generator::Go 5 | # Automatic Code generation overrides for the Go programming language 6 | class Go < Base 7 | def array_type_for(type_name) 8 | "[]#{type_name}" 9 | end 10 | 11 | def property_type_from_ref(ref) 12 | "*#{class_name(ref)}" 13 | end 14 | 15 | private 16 | 17 | def language_translations_for_data_types 18 | { 19 | 'integer' => 'int64', 20 | 'string' => 'string', 21 | 'boolean' => 'bool' 22 | } 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /codegen/generators/java.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Generator 4 | # Generator::Java 5 | # Automatic Code generation overrides for the Java programming language 6 | class Java < Base 7 | def array_type_for(type_name) 8 | "java.util.List<#{type_name}>" 9 | end 10 | 11 | def format_description(raw_description, indent_string: '') 12 | return '' if raw_description.nil? 13 | 14 | raw_description 15 | .split("\n") 16 | .map(&:strip) 17 | .reject { |line| line == '*' } 18 | .map { |line| " * #{line}".rstrip } 19 | .join("\n#{indent_string}") 20 | end 21 | 22 | private 23 | 24 | def language_translations_for_data_types 25 | { 26 | 'integer' => 'Long', 27 | 'string' => 'String', 28 | 'boolean' => 'Boolean' 29 | } 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /codegen/generators/markdown.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Generator 4 | # Generator::Markdown 5 | # Automatic Code generation overrides for the 'Cucumber with Markdown' programming language 6 | # NB: This is based on the cucumber-js implementation 7 | class Markdown < Base 8 | def initialize 9 | # This path is different because the make task is ran from the TLD, not a language specific one 10 | super(paths: Dir['./jsonschema/*.json']) 11 | end 12 | 13 | def array_type_for(type_name) 14 | "#{type_name}[]" 15 | end 16 | 17 | def property_type_from_enum(enum) 18 | "[#{enum}](##{enum.downcase})" 19 | end 20 | 21 | def property_type_from_ref(ref) 22 | "[#{class_name(ref)}](##{class_name(ref).downcase})" 23 | end 24 | 25 | private 26 | 27 | def language_translations_for_data_types 28 | { 29 | 'integer' => 'integer', 30 | 'string' => 'string', 31 | 'boolean' => 'boolean' 32 | } 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /codegen/generators/text_helpers.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Generator 4 | # Generator::TextHelpers 5 | # A few handy text helpers for converting text strings into different formats 6 | module TextHelpers 7 | private 8 | 9 | def capitalize(string) 10 | string.sub(/./, &:upcase) 11 | end 12 | 13 | # Adapted from rails -> https://github.com/rails/rails/blob/v6.1.3.2/activesupport/lib/active_support/inflector/methods.rb#L92 14 | def underscore(camel_cased_word) 15 | return camel_cased_word unless /[A-Z-]/.match?(camel_cased_word) 16 | 17 | camel_cased_word.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2') 18 | .gsub(/([a-z\d])([A-Z])/, '\1_\2') 19 | .tr('-', '_') 20 | .downcase 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /codegen/generators/typescript.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Generator 4 | # Generator::TypeScript 5 | # Automatic Code generation overrides for the TypeScript programming language 6 | class TypeScript < Base 7 | def array_type_for(type_name) 8 | "readonly #{type_name}[]" 9 | end 10 | 11 | private 12 | 13 | def language_translations_for_data_types 14 | { 15 | 'integer' => 'number', 16 | 'string' => 'string', 17 | 'boolean' => 'boolean' 18 | } 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /codegen/templates/dotnet.enum.dotnet.erb: -------------------------------------------------------------------------------- 1 | <% @enums.each do |enum| -%> 2 | <%= enum[:name] %>.cs 3 | using System; 4 | using System.ComponentModel; 5 | using System.Reflection; 6 | 7 | namespace Io.Cucumber.Messages.Types; 8 | 9 | // ------------------------------------------------------------------------------ 10 | // This code was generated based on the Cucumber JSON schema 11 | // Changes to this file may cause incorrect behavior and will be lost if 12 | // the code is regenerated. 13 | // ------------------------------------------------------------------------------ 14 | 15 | public enum <%= enum[:name] %> { 16 | <% enum[:values].each.with_index(1) do |value, index| -%> 17 | 18 | [Description("<%= value%>")] 19 | <%= enum_constant(value) %><%= index < enum[:values].length ? ',' : '' %> 20 | <% end -%> 21 | } 22 | 23 | public static class <%= enum[:name] %>Extensions 24 | { 25 | public static string Value(this <%= enum[:name] %> v) { 26 | var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); 27 | return attribute == null ? v.ToString() : attribute.Description; 28 | } 29 | } 30 | <% end -%> 31 | -------------------------------------------------------------------------------- /codegen/templates/go.enum.go.erb: -------------------------------------------------------------------------------- 1 | <% @enums.each_with_index do |enum, index| -%> 2 | type <%= enum[:name] %> string 3 | 4 | const ( 5 | <%- 6 | enum_constant_max_length = enum[:values].max_by { |value| enum_constant(value).length }.length 7 | -%> 8 | <% enum[:values].each do |value| -%> 9 | <%=enum[:name] %>_<%= enum_constant(value).ljust(enum_constant_max_length) %> <%= enum[:name] %> = "<%= value %>" 10 | <% end -%> 11 | ) 12 | 13 | func (e <%= enum[:name] %>) String() string { 14 | switch e { 15 | <%- enum[:values].each do |value| -%> 16 | case <%= enum[:name] %>_<%= enum_constant(value) %>: 17 | return "<%= value %>" 18 | <%- end -%> 19 | default: 20 | panic("Bad enum value for <%= enum[:name] %>") 21 | } 22 | } 23 | <%- if index != @enums.size - 1 -%> 24 | 25 | <%- end -%> 26 | <%- end -%> 27 | -------------------------------------------------------------------------------- /codegen/templates/go.go.erb: -------------------------------------------------------------------------------- 1 | package messages 2 | 3 | <% @schemas.each do |key, schema| -%> 4 | type <%= class_name(key) %> struct { 5 | <%- 6 | property_name_max_length = schema['properties'].max_by{ |property_name,_| property_name.length }[0].length 7 | type_names = schema['properties'].map { |property_name, property| [property_name, type_for(class_name(key), property_name, property)] } 8 | type_name_max_length = type_names.max_by{ |_,type_name| type_name.length }[1].length 9 | -%> 10 | <%- type_names.each do |property_name, type_name| -%> 11 | <%- 12 | required = (schema['required'] || []).index(property_name) 13 | -%> 14 | <%- %> <%= capitalize(property_name).ljust(property_name_max_length) %> <%= type_name.ljust(type_name_max_length) %> `json:"<%= property_name %><%= required ? '' : ',omitempty' %>"` 15 | <%- end -%> 16 | } 17 | 18 | <% end -%> -------------------------------------------------------------------------------- /codegen/templates/java.enum.java.erb: -------------------------------------------------------------------------------- 1 | <% @enums.each do |enum| -%> 2 | <%= enum[:name] %>.java 3 | package io.cucumber.messages.types; 4 | 5 | // Generated code 6 | @SuppressWarnings("unused") 7 | public enum <%= enum[:name] %> { 8 | <% enum[:values].each_with_index do |value, index| -%> 9 | 10 | <%= enum_constant(value) %>("<%= value %>")<%= index < enum[:values].length - 1 ? ',' : ';' %> 11 | <% end -%> 12 | 13 | private final String value; 14 | 15 | <%= enum[:name] %>(String value) { 16 | this.value = value; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return this.value; 22 | } 23 | 24 | public String value() { 25 | return this.value; 26 | } 27 | 28 | public static <%= enum[:name] %> fromValue(String value) { 29 | for (<%= enum[:name] %> v : values()) { 30 | if (v.value.equals(value)) { 31 | return v; 32 | } 33 | } 34 | throw new IllegalArgumentException(value); 35 | } 36 | } 37 | <% end -%> 38 | -------------------------------------------------------------------------------- /codegen/templates/markdown.enum.md.erb: -------------------------------------------------------------------------------- 1 | <% @enums.each do |enum| -%> 2 | ## <%= enum[:name] %> 3 | 4 | One of the following: 5 | 6 | <% enum[:values].each do |value| -%> 7 | * `"<%= value %>"` 8 | <% end %> 9 | 10 | <% end -%> 11 | -------------------------------------------------------------------------------- /codegen/templates/markdown.md.erb: -------------------------------------------------------------------------------- 1 | # Cucumber Messages 2 | 3 | Each message is an instance of [Envelope](#envelope). The `Envelope` message 4 | will only have one of its fields set, which indicates the payload of the message. 5 | 6 | <% @schemas.each do |key, schema| -%> 7 | ## <%= class_name(key) %> 8 | 9 | | Field | Type | Required | Description | 10 | | ----- | ---- | ----------- | ----------- | 11 | <% schema['properties'].each do |property_name, property| -%> 12 | <%- 13 | type_name = type_for(class_name(key), property_name, property) 14 | required = (schema['required'] || []).index(property_name) 15 | -%> 16 | <%- %>| `<%= property_name %>` | <%= type_name %> | <%= required ? 'yes' : 'no' %> | | 17 | <% end -%> 18 | 19 | <% end -%> -------------------------------------------------------------------------------- /codegen/templates/php.enum.php.erb: -------------------------------------------------------------------------------- 1 | <% @enums.each do |enum| -%> 2 | <%= enum[:name].split('\\').join('/') %>.php 3 | 12 | namespace Cucumber\Messages\<%= namespaces.slice(0,1)[0] %>; 13 | 14 | enum <%= namespaces[-1] %>: string 15 | { 16 | <%- enum[:values].each do |value| -%> 17 | case <%= enum_constant(value) %> = '<%= value %>'; 18 | <%- end -%> 19 | } 20 | <%- end -%> 21 | -------------------------------------------------------------------------------- /codegen/templates/python.enum.py.erb: -------------------------------------------------------------------------------- 1 | # This code was generated using the code generator from cucumber-messages. 2 | # Manual changes will be lost if the code is regenerated. 3 | # Generator: cucumber-messages-python 4 | 5 | from enum import Enum 6 | 7 | 8 | <%- @enums.each_with_index do |enum, index| -%> 9 | class <%= enum[:name] %>(Enum): 10 | <%- enum[:values].each do |value| -%> 11 | <%= format_enum_value(value) %> = "<%= value %>" 12 | <%- end -%> 13 | <%- if index < @enums.length - 1 -%> 14 | 15 | 16 | <%- end -%> 17 | <%- end -%> 18 | -------------------------------------------------------------------------------- /codegen/templates/ruby.enum.rb.erb: -------------------------------------------------------------------------------- 1 | <%- @enums.each do |enum| -%> 2 | <%= underscore(enum[:name]) %>.rb 3 | # frozen_string_literal: true 4 | 5 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 6 | module Cucumber 7 | module Messages 8 | class <%= enum[:name] %> 9 | <%- enum[:values].each do |value| -%> 10 | <%= enum_constant(value) %> = '<%= value %>' 11 | <%- end -%> 12 | end 13 | end 14 | end 15 | <% end -%> 16 | -------------------------------------------------------------------------------- /codegen/templates/typescript.enum.ts.erb: -------------------------------------------------------------------------------- 1 | <% @enums.each do |enum| -%> 2 | export enum <%= enum[:name] %> { 3 | <% enum[:values].each do |value| -%> 4 | <%= enum_constant(value) %> = '<%= value %>', 5 | <% end -%> 6 | } 7 | 8 | <% end -%> 9 | -------------------------------------------------------------------------------- /codegen/templates/typescript.ts.erb: -------------------------------------------------------------------------------- 1 | import { Type } from 'class-transformer' 2 | import 'reflect-metadata' 3 | 4 | <% @schemas.each do |key, schema| -%> 5 | export class <%= class_name(key) -%> { 6 | <%- schema['properties'].each do |property_name, property| -%> 7 | 8 | <%- ref = property['$ref'] || property['items'] && property['items']['$ref'] -%> 9 | <%- if ref -%> 10 | <%- %> @Type(() => <%= class_name(ref) -%>) 11 | <%- end -%> 12 | <%- if (schema['required'] || []).index(property_name) -%> 13 | <%- %> <%= property_name %>: <%= type_for(class_name(key), property_name, property) -%> = <%= default_value(class_name(key), property_name, property) -%> 14 | <%- else -%> 15 | <%- %> <%= property_name %>?: <%= type_for(class_name(key), property_name, property) -%> 16 | <%- end -%> 17 | 18 | <%- end -%> 19 | } 20 | 21 | <% end -%> 22 | -------------------------------------------------------------------------------- /cpp/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | stage/ 3 | .cenv/ 4 | -------------------------------------------------------------------------------- /cpp/Dockerfile: -------------------------------------------------------------------------------- 1 | #syntax=docker/dockerfile:1.16 2 | 3 | # Base image 4 | FROM debian:bullseye-slim AS cpp 5 | 6 | RUN < 4 | 5 | namespace cucumber::messages { 6 | 7 | enum class attachment_content_encoding 8 | { 9 | IDENTITY, 10 | BASE64 11 | }; 12 | 13 | std::string_view 14 | to_string(attachment_content_encoding v); 15 | 16 | std::ostream& 17 | operator<<(std::ostream& os, attachment_content_encoding v); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/background.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the Background message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // Generated code 21 | 22 | struct background 23 | { 24 | cucumber::messages::location location; 25 | std::string keyword; 26 | std::string name; 27 | std::string description; 28 | std::vector steps; 29 | std::string id; 30 | 31 | std::string to_string() const; 32 | 33 | void to_json(json& j) const; 34 | std::string to_json() const; 35 | }; 36 | 37 | std::ostream& 38 | operator<<(std::ostream& os, const background& msg); 39 | 40 | void to_json(json& j, const background& m); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/ci.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the Ci message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // CI environment 20 | // 21 | // Generated code 22 | 23 | struct ci 24 | { 25 | std::string name; 26 | std::optional url; 27 | std::optional build_number; 28 | std::optional git; 29 | 30 | std::string to_string() const; 31 | 32 | void to_json(json& j) const; 33 | std::string to_json() const; 34 | }; 35 | 36 | std::ostream& 37 | operator<<(std::ostream& os, const ci& msg); 38 | 39 | void to_json(json& j, const ci& m); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/comment.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the Comment message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // A comment in a Gherkin document 20 | // 21 | // Generated code 22 | 23 | struct comment 24 | { 25 | cucumber::messages::location location; 26 | std::string text; 27 | 28 | std::string to_string() const; 29 | 30 | void to_json(json& j) const; 31 | std::string to_json() const; 32 | }; 33 | 34 | std::ostream& 35 | operator<<(std::ostream& os, const comment& msg); 36 | 37 | void to_json(json& j, const comment& m); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/data_table.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the DataTable message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // Generated code 21 | 22 | struct data_table 23 | { 24 | cucumber::messages::location location; 25 | std::vector rows; 26 | 27 | std::string to_string() const; 28 | 29 | void to_json(json& j) const; 30 | std::string to_json() const; 31 | }; 32 | 33 | std::ostream& 34 | operator<<(std::ostream& os, const data_table& msg); 35 | 36 | void to_json(json& j, const data_table& m); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/doc_string.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the DocString message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct doc_string 22 | { 23 | cucumber::messages::location location; 24 | std::optional media_type; 25 | std::string content; 26 | std::string delimiter; 27 | 28 | std::string to_string() const; 29 | 30 | void to_json(json& j) const; 31 | std::string to_json() const; 32 | }; 33 | 34 | std::ostream& 35 | operator<<(std::ostream& os, const doc_string& msg); 36 | 37 | void to_json(json& j, const doc_string& m); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/duration.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the Duration message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // The structure is pretty close of the Timestamp one. For clarity, a second type 18 | // of message is used. 19 | // 20 | // Generated code 21 | 22 | struct duration 23 | { 24 | std::size_t seconds; 25 | std::size_t nanos; 26 | 27 | std::string to_string() const; 28 | 29 | void to_json(json& j) const; 30 | std::string to_json() const; 31 | }; 32 | 33 | std::ostream& 34 | operator<<(std::ostream& os, const duration& msg); 35 | 36 | void to_json(json& j, const duration& m); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/exception.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the Exception message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // A simplified representation of an exception 18 | // 19 | // Generated code 20 | 21 | struct exception 22 | { 23 | std::string type; 24 | std::optional message; 25 | std::optional stack_trace; 26 | 27 | std::string to_string() const; 28 | 29 | void to_json(json& j) const; 30 | std::string to_json() const; 31 | }; 32 | 33 | std::ostream& 34 | operator<<(std::ostream& os, const exception& msg); 35 | 36 | void to_json(json& j, const exception& m); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/feature_child.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace cucumber::messages { 14 | 15 | using json = nlohmann::json; 16 | 17 | // 18 | // Represents the FeatureChild message in Cucumber's message protocol 19 | // @see Github - Cucumber - Messages 20 | // 21 | // A child node of a `Feature` node 22 | // 23 | // Generated code 24 | 25 | struct feature_child 26 | { 27 | std::optional rule; 28 | std::optional background; 29 | std::optional scenario; 30 | 31 | std::string to_string() const; 32 | 33 | void to_json(json& j) const; 34 | std::string to_json() const; 35 | }; 36 | 37 | std::ostream& 38 | operator<<(std::ostream& os, const feature_child& msg); 39 | 40 | void to_json(json& j, const feature_child& m); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/git.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the Git message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // Information about Git, provided by the Build/CI server as environment 18 | // variables. 19 | // 20 | // Generated code 21 | 22 | struct git 23 | { 24 | std::string remote; 25 | std::string revision; 26 | std::optional branch; 27 | std::optional tag; 28 | 29 | std::string to_string() const; 30 | 31 | void to_json(json& j) const; 32 | std::string to_json() const; 33 | }; 34 | 35 | std::ostream& 36 | operator<<(std::ostream& os, const git& msg); 37 | 38 | void to_json(json& j, const git& m); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/group.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the Group message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct group 22 | { 23 | std::vector children; 24 | std::optional start; 25 | std::optional value; 26 | 27 | std::string to_string() const; 28 | 29 | void to_json(json& j) const; 30 | std::string to_json() const; 31 | }; 32 | 33 | std::ostream& 34 | operator<<(std::ostream& os, const group& msg); 35 | 36 | void to_json(json& j, const group& m); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/hook.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the Hook message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // Generated code 21 | 22 | struct hook 23 | { 24 | std::string id; 25 | std::optional name; 26 | cucumber::messages::source_reference source_reference; 27 | std::optional tag_expression; 28 | std::optional type; 29 | 30 | std::string to_string() const; 31 | 32 | void to_json(json& j) const; 33 | std::string to_json() const; 34 | }; 35 | 36 | std::ostream& 37 | operator<<(std::ostream& os, const hook& msg); 38 | 39 | void to_json(json& j, const hook& m); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/hook_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace cucumber::messages { 6 | 7 | enum class hook_type 8 | { 9 | BEFORE_TEST_RUN, 10 | AFTER_TEST_RUN, 11 | BEFORE_TEST_CASE, 12 | AFTER_TEST_CASE, 13 | BEFORE_TEST_STEP, 14 | AFTER_TEST_STEP 15 | }; 16 | 17 | std::string_view 18 | to_string(hook_type v); 19 | 20 | std::ostream& 21 | operator<<(std::ostream& os, hook_type v); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/java_method.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the JavaMethod message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // Generated code 18 | 19 | struct java_method 20 | { 21 | std::string class_name; 22 | std::string method_name; 23 | std::vector method_parameter_types; 24 | 25 | std::string to_string() const; 26 | 27 | void to_json(json& j) const; 28 | std::string to_json() const; 29 | }; 30 | 31 | std::ostream& 32 | operator<<(std::ostream& os, const java_method& msg); 33 | 34 | void to_json(json& j, const java_method& m); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/java_stack_trace_element.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the JavaStackTraceElement message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // Generated code 18 | 19 | struct java_stack_trace_element 20 | { 21 | std::string class_name; 22 | std::string file_name; 23 | std::string method_name; 24 | 25 | std::string to_string() const; 26 | 27 | void to_json(json& j) const; 28 | std::string to_json() const; 29 | }; 30 | 31 | std::ostream& 32 | operator<<(std::ostream& os, const java_stack_trace_element& msg); 33 | 34 | void to_json(json& j, const java_stack_trace_element& m); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/location.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the Location message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // Points to a line and a column in a text file 18 | // 19 | // Generated code 20 | 21 | struct location 22 | { 23 | std::size_t line; 24 | std::optional column; 25 | 26 | std::string to_string() const; 27 | 28 | void to_json(json& j) const; 29 | std::string to_json() const; 30 | }; 31 | 32 | std::ostream& 33 | operator<<(std::ostream& os, const location& msg); 34 | 35 | void to_json(json& j, const location& m); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/parameter_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the ParameterType message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct parameter_type 22 | { 23 | std::string name; 24 | std::vector regular_expressions; 25 | bool prefer_for_regular_expression_match; 26 | bool use_for_snippets; 27 | std::string id; 28 | std::optional source_reference; 29 | 30 | std::string to_string() const; 31 | 32 | void to_json(json& j) const; 33 | std::string to_json() const; 34 | }; 35 | 36 | std::ostream& 37 | operator<<(std::ostream& os, const parameter_type& msg); 38 | 39 | void to_json(json& j, const parameter_type& m); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/parse_error.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the ParseError message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct parse_error 22 | { 23 | cucumber::messages::source_reference source; 24 | std::string message; 25 | 26 | std::string to_string() const; 27 | 28 | void to_json(json& j) const; 29 | std::string to_json() const; 30 | }; 31 | 32 | std::ostream& 33 | operator<<(std::ostream& os, const parse_error& msg); 34 | 35 | void to_json(json& j, const parse_error& m); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/pickle_doc_string.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the PickleDocString message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // Generated code 18 | 19 | struct pickle_doc_string 20 | { 21 | std::optional media_type; 22 | std::string content; 23 | 24 | std::string to_string() const; 25 | 26 | void to_json(json& j) const; 27 | std::string to_json() const; 28 | }; 29 | 30 | std::ostream& 31 | operator<<(std::ostream& os, const pickle_doc_string& msg); 32 | 33 | void to_json(json& j, const pickle_doc_string& m); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/pickle_step.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the PickleStep message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // An executable step 21 | // 22 | // Generated code 23 | 24 | struct pickle_step 25 | { 26 | std::optional argument; 27 | std::vector ast_node_ids; 28 | std::string id; 29 | std::optional type; 30 | std::string text; 31 | 32 | std::string to_string() const; 33 | 34 | void to_json(json& j) const; 35 | std::string to_json() const; 36 | }; 37 | 38 | std::ostream& 39 | operator<<(std::ostream& os, const pickle_step& msg); 40 | 41 | void to_json(json& j, const pickle_step& m); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/pickle_step_argument.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the PickleStepArgument message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // An optional argument 21 | // 22 | // Generated code 23 | 24 | struct pickle_step_argument 25 | { 26 | std::optional doc_string; 27 | std::optional data_table; 28 | 29 | std::string to_string() const; 30 | 31 | void to_json(json& j) const; 32 | std::string to_json() const; 33 | }; 34 | 35 | std::ostream& 36 | operator<<(std::ostream& os, const pickle_step_argument& msg); 37 | 38 | void to_json(json& j, const pickle_step_argument& m); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/pickle_step_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace cucumber::messages { 6 | 7 | enum class pickle_step_type 8 | { 9 | UNKNOWN, 10 | CONTEXT, 11 | ACTION, 12 | OUTCOME 13 | }; 14 | 15 | std::string_view 16 | to_string(pickle_step_type v); 17 | 18 | std::ostream& 19 | operator<<(std::ostream& os, pickle_step_type v); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/pickle_table.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the PickleTable message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct pickle_table 22 | { 23 | std::vector rows; 24 | 25 | std::string to_string() const; 26 | 27 | void to_json(json& j) const; 28 | std::string to_json() const; 29 | }; 30 | 31 | std::ostream& 32 | operator<<(std::ostream& os, const pickle_table& msg); 33 | 34 | void to_json(json& j, const pickle_table& m); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/pickle_table_cell.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the PickleTableCell message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // Generated code 18 | 19 | struct pickle_table_cell 20 | { 21 | std::string value; 22 | 23 | std::string to_string() const; 24 | 25 | void to_json(json& j) const; 26 | std::string to_json() const; 27 | }; 28 | 29 | std::ostream& 30 | operator<<(std::ostream& os, const pickle_table_cell& msg); 31 | 32 | void to_json(json& j, const pickle_table_cell& m); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/pickle_table_row.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the PickleTableRow message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct pickle_table_row 22 | { 23 | std::vector cells; 24 | 25 | std::string to_string() const; 26 | 27 | void to_json(json& j) const; 28 | std::string to_json() const; 29 | }; 30 | 31 | std::ostream& 32 | operator<<(std::ostream& os, const pickle_table_row& msg); 33 | 34 | void to_json(json& j, const pickle_table_row& m); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/pickle_tag.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the PickleTag message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // A tag 18 | // 19 | // Generated code 20 | 21 | struct pickle_tag 22 | { 23 | std::string name; 24 | std::string ast_node_id; 25 | 26 | std::string to_string() const; 27 | 28 | void to_json(json& j) const; 29 | std::string to_json() const; 30 | }; 31 | 32 | std::ostream& 33 | operator<<(std::ostream& os, const pickle_tag& msg); 34 | 35 | void to_json(json& j, const pickle_tag& m); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/product.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the Product message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // Used to describe various properties of Meta 18 | // 19 | // Generated code 20 | 21 | struct product 22 | { 23 | std::string name; 24 | std::optional version; 25 | 26 | std::string to_string() const; 27 | 28 | void to_json(json& j) const; 29 | std::string to_json() const; 30 | }; 31 | 32 | std::ostream& 33 | operator<<(std::ostream& os, const product& msg); 34 | 35 | void to_json(json& j, const product& m); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/rule.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace cucumber::messages { 14 | 15 | using json = nlohmann::json; 16 | 17 | // 18 | // Represents the Rule message in Cucumber's message protocol 19 | // @see Github - Cucumber - Messages 20 | // 21 | // Generated code 22 | 23 | struct rule 24 | { 25 | cucumber::messages::location location; 26 | std::vector tags; 27 | std::string keyword; 28 | std::string name; 29 | std::string description; 30 | std::vector children; 31 | std::string id; 32 | 33 | std::string to_string() const; 34 | 35 | void to_json(json& j) const; 36 | std::string to_json() const; 37 | }; 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const rule& msg); 41 | 42 | void to_json(json& j, const rule& m); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/rule_child.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the RuleChild message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // A child node of a `Rule` node 21 | // 22 | // Generated code 23 | 24 | struct rule_child 25 | { 26 | std::optional background; 27 | std::optional scenario; 28 | 29 | std::string to_string() const; 30 | 31 | void to_json(json& j) const; 32 | std::string to_json() const; 33 | }; 34 | 35 | std::ostream& 36 | operator<<(std::ostream& os, const rule_child& msg); 37 | 38 | void to_json(json& j, const rule_child& m); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/source.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the Source message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // //// Source 20 | // 21 | // A source file, typically a Gherkin document or Java/Ruby/JavaScript source code 22 | // 23 | // Generated code 24 | 25 | struct source 26 | { 27 | std::string uri; 28 | std::string data; 29 | cucumber::messages::source_media_type media_type; 30 | 31 | std::string to_string() const; 32 | 33 | void to_json(json& j) const; 34 | std::string to_json() const; 35 | }; 36 | 37 | std::ostream& 38 | operator<<(std::ostream& os, const source& msg); 39 | 40 | void to_json(json& j, const source& m); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/source_media_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace cucumber::messages { 6 | 7 | enum class source_media_type 8 | { 9 | TEXT_X_CUCUMBER_GHERKIN_PLAIN, 10 | TEXT_X_CUCUMBER_GHERKIN_MARKDOWN 11 | }; 12 | 13 | std::string_view 14 | to_string(source_media_type v); 15 | 16 | std::ostream& 17 | operator<<(std::ostream& os, source_media_type v); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/step_definition.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the StepDefinition message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // Generated code 21 | 22 | struct step_definition 23 | { 24 | std::string id; 25 | cucumber::messages::step_definition_pattern pattern; 26 | cucumber::messages::source_reference source_reference; 27 | 28 | std::string to_string() const; 29 | 30 | void to_json(json& j) const; 31 | std::string to_json() const; 32 | }; 33 | 34 | std::ostream& 35 | operator<<(std::ostream& os, const step_definition& msg); 36 | 37 | void to_json(json& j, const step_definition& m); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/step_definition_pattern.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the StepDefinitionPattern message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct step_definition_pattern 22 | { 23 | std::string source; 24 | cucumber::messages::step_definition_pattern_type type; 25 | 26 | std::string to_string() const; 27 | 28 | void to_json(json& j) const; 29 | std::string to_json() const; 30 | }; 31 | 32 | std::ostream& 33 | operator<<(std::ostream& os, const step_definition_pattern& msg); 34 | 35 | void to_json(json& j, const step_definition_pattern& m); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/step_definition_pattern_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace cucumber::messages { 6 | 7 | enum class step_definition_pattern_type 8 | { 9 | CUCUMBER_EXPRESSION, 10 | REGULAR_EXPRESSION 11 | }; 12 | 13 | std::string_view 14 | to_string(step_definition_pattern_type v); 15 | 16 | std::ostream& 17 | operator<<(std::ostream& os, step_definition_pattern_type v); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/step_keyword_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace cucumber::messages { 6 | 7 | enum class step_keyword_type 8 | { 9 | UNKNOWN, 10 | CONTEXT, 11 | ACTION, 12 | OUTCOME, 13 | CONJUNCTION 14 | }; 15 | 16 | std::string_view 17 | to_string(step_keyword_type v); 18 | 19 | std::ostream& 20 | operator<<(std::ostream& os, step_keyword_type v); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/step_match_arguments_list.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the StepMatchArgumentsList message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct step_match_arguments_list 22 | { 23 | std::vector step_match_arguments; 24 | 25 | std::string to_string() const; 26 | 27 | void to_json(json& j) const; 28 | std::string to_json() const; 29 | }; 30 | 31 | std::ostream& 32 | operator<<(std::ostream& os, const step_match_arguments_list& msg); 33 | 34 | void to_json(json& j, const step_match_arguments_list& m); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/table_cell.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the TableCell message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // A cell in a `TableRow` 20 | // 21 | // Generated code 22 | 23 | struct table_cell 24 | { 25 | cucumber::messages::location location; 26 | std::string value; 27 | 28 | std::string to_string() const; 29 | 30 | void to_json(json& j) const; 31 | std::string to_json() const; 32 | }; 33 | 34 | std::ostream& 35 | operator<<(std::ostream& os, const table_cell& msg); 36 | 37 | void to_json(json& j, const table_cell& m); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/table_row.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the TableRow message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // A row in a table 21 | // 22 | // Generated code 23 | 24 | struct table_row 25 | { 26 | cucumber::messages::location location; 27 | std::vector cells; 28 | std::string id; 29 | 30 | std::string to_string() const; 31 | 32 | void to_json(json& j) const; 33 | std::string to_json() const; 34 | }; 35 | 36 | std::ostream& 37 | operator<<(std::ostream& os, const table_row& msg); 38 | 39 | void to_json(json& j, const table_row& m); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/tag.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the Tag message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // A tag 20 | // 21 | // Generated code 22 | 23 | struct tag 24 | { 25 | cucumber::messages::location location; 26 | std::string name; 27 | std::string id; 28 | 29 | std::string to_string() const; 30 | 31 | void to_json(json& j) const; 32 | std::string to_json() const; 33 | }; 34 | 35 | std::ostream& 36 | operator<<(std::ostream& os, const tag& msg); 37 | 38 | void to_json(json& j, const tag& m); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_case.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the TestCase message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // //// TestCases 20 | // 21 | // A `TestCase` contains a sequence of `TestStep`s. 22 | // 23 | // Generated code 24 | 25 | struct test_case 26 | { 27 | std::string id; 28 | std::string pickle_id; 29 | std::vector test_steps; 30 | std::optional test_run_started_id; 31 | 32 | std::string to_string() const; 33 | 34 | void to_json(json& j) const; 35 | std::string to_json() const; 36 | }; 37 | 38 | std::ostream& 39 | operator<<(std::ostream& os, const test_case& msg); 40 | 41 | void to_json(json& j, const test_case& m); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_case_finished.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the TestCaseFinished message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct test_case_finished 22 | { 23 | std::string test_case_started_id; 24 | cucumber::messages::timestamp timestamp; 25 | bool will_be_retried; 26 | 27 | std::string to_string() const; 28 | 29 | void to_json(json& j) const; 30 | std::string to_json() const; 31 | }; 32 | 33 | std::ostream& 34 | operator<<(std::ostream& os, const test_case_finished& msg); 35 | 36 | void to_json(json& j, const test_case_finished& m); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_case_started.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the TestCaseStarted message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct test_case_started 22 | { 23 | std::size_t attempt; 24 | std::string id; 25 | std::string test_case_id; 26 | std::optional worker_id; 27 | cucumber::messages::timestamp timestamp; 28 | 29 | std::string to_string() const; 30 | 31 | void to_json(json& j) const; 32 | std::string to_json() const; 33 | }; 34 | 35 | std::ostream& 36 | operator<<(std::ostream& os, const test_case_started& msg); 37 | 38 | void to_json(json& j, const test_case_started& m); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_run_finished.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the TestRunFinished message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // Generated code 21 | 22 | struct test_run_finished 23 | { 24 | std::optional message; 25 | bool success; 26 | cucumber::messages::timestamp timestamp; 27 | std::optional exception; 28 | std::optional test_run_started_id; 29 | 30 | std::string to_string() const; 31 | 32 | void to_json(json& j) const; 33 | std::string to_json() const; 34 | }; 35 | 36 | std::ostream& 37 | operator<<(std::ostream& os, const test_run_finished& msg); 38 | 39 | void to_json(json& j, const test_run_finished& m); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_run_hook_finished.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the TestRunHookFinished message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // Generated code 21 | 22 | struct test_run_hook_finished 23 | { 24 | std::string test_run_hook_started_id; 25 | cucumber::messages::test_step_result result; 26 | cucumber::messages::timestamp timestamp; 27 | 28 | std::string to_string() const; 29 | 30 | void to_json(json& j) const; 31 | std::string to_json() const; 32 | }; 33 | 34 | std::ostream& 35 | operator<<(std::ostream& os, const test_run_hook_finished& msg); 36 | 37 | void to_json(json& j, const test_run_hook_finished& m); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_run_hook_started.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the TestRunHookStarted message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct test_run_hook_started 22 | { 23 | std::string id; 24 | std::string test_run_started_id; 25 | std::string hook_id; 26 | cucumber::messages::timestamp timestamp; 27 | 28 | std::string to_string() const; 29 | 30 | void to_json(json& j) const; 31 | std::string to_json() const; 32 | }; 33 | 34 | std::ostream& 35 | operator<<(std::ostream& os, const test_run_hook_started& msg); 36 | 37 | void to_json(json& j, const test_run_hook_started& m); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_run_started.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the TestRunStarted message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct test_run_started 22 | { 23 | cucumber::messages::timestamp timestamp; 24 | std::optional id; 25 | 26 | std::string to_string() const; 27 | 28 | void to_json(json& j) const; 29 | std::string to_json() const; 30 | }; 31 | 32 | std::ostream& 33 | operator<<(std::ostream& os, const test_run_started& msg); 34 | 35 | void to_json(json& j, const test_run_started& m); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_step_finished.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace cucumber::messages { 13 | 14 | using json = nlohmann::json; 15 | 16 | // 17 | // Represents the TestStepFinished message in Cucumber's message protocol 18 | // @see Github - Cucumber - Messages 19 | // 20 | // Generated code 21 | 22 | struct test_step_finished 23 | { 24 | std::string test_case_started_id; 25 | std::string test_step_id; 26 | cucumber::messages::test_step_result test_step_result; 27 | cucumber::messages::timestamp timestamp; 28 | 29 | std::string to_string() const; 30 | 31 | void to_json(json& j) const; 32 | std::string to_json() const; 33 | }; 34 | 35 | std::ostream& 36 | operator<<(std::ostream& os, const test_step_finished& msg); 37 | 38 | void to_json(json& j, const test_step_finished& m); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_step_result_status.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace cucumber::messages { 6 | 7 | enum class test_step_result_status 8 | { 9 | UNKNOWN, 10 | PASSED, 11 | SKIPPED, 12 | PENDING, 13 | UNDEFINED, 14 | AMBIGUOUS, 15 | FAILED 16 | }; 17 | 18 | std::string_view 19 | to_string(test_step_result_status v); 20 | 21 | std::ostream& 22 | operator<<(std::ostream& os, test_step_result_status v); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/test_step_started.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace cucumber::messages { 12 | 13 | using json = nlohmann::json; 14 | 15 | // 16 | // Represents the TestStepStarted message in Cucumber's message protocol 17 | // @see Github - Cucumber - Messages 18 | // 19 | // Generated code 20 | 21 | struct test_step_started 22 | { 23 | std::string test_case_started_id; 24 | std::string test_step_id; 25 | cucumber::messages::timestamp timestamp; 26 | 27 | std::string to_string() const; 28 | 29 | void to_json(json& j) const; 30 | std::string to_json() const; 31 | }; 32 | 33 | std::ostream& 34 | operator<<(std::ostream& os, const test_step_started& msg); 35 | 36 | void to_json(json& j, const test_step_started& m); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/timestamp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the Timestamp message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // Generated code 18 | 19 | struct timestamp 20 | { 21 | std::size_t seconds; 22 | std::size_t nanos; 23 | 24 | std::string to_string() const; 25 | 26 | void to_json(json& j) const; 27 | std::string to_json() const; 28 | }; 29 | 30 | std::ostream& 31 | operator<<(std::ostream& os, const timestamp& msg); 32 | 33 | void to_json(json& j, const timestamp& m); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /cpp/include/messages/cucumber/messages/undefined_parameter_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace cucumber::messages { 10 | 11 | using json = nlohmann::json; 12 | 13 | // 14 | // Represents the UndefinedParameterType message in Cucumber's message protocol 15 | // @see Github - Cucumber - Messages 16 | // 17 | // Generated code 18 | 19 | struct undefined_parameter_type 20 | { 21 | std::string expression; 22 | std::string name; 23 | 24 | std::string to_string() const; 25 | 26 | void to_json(json& j) const; 27 | std::string to_json() const; 28 | }; 29 | 30 | std::ostream& 31 | operator<<(std::ostream& os, const undefined_parameter_type& msg); 32 | 33 | void to_json(json& j, const undefined_parameter_type& m); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /cpp/project.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: cucumber_messages 3 | version_file: VERSION 4 | namespace: cucumber 5 | std: 17 6 | packages: 7 | cmake: 8 | - nlohmann_json: 9 | deps: 10 | - nlohmann/json@v3.11.3: 11 | args: 12 | - -DJSON_BuildTests=OFF 13 | - -DJSON_Install=ON 14 | -------------------------------------------------------------------------------- /cpp/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(lib) 2 | -------------------------------------------------------------------------------- /cpp/src/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(cucumber-messages) 2 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/attachment_content_encoding.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string_view 9 | to_string(attachment_content_encoding v) 10 | { 11 | using map_type = std::unordered_map; 12 | 13 | static const map_type m = { 14 | { attachment_content_encoding::IDENTITY, "IDENTITY" }, 15 | { attachment_content_encoding::BASE64, "BASE64" } 16 | }; 17 | 18 | return m.at(v); 19 | } 20 | 21 | std::ostream& 22 | operator<<(std::ostream& os, attachment_content_encoding v) 23 | { 24 | os << to_string(v); 25 | 26 | return os; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/comment.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | comment::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "location=", location); 14 | cucumber::messages::to_string(oss, ", text=", text); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | comment::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("location"), location); 23 | cucumber::messages::to_json(j, camelize("text"), text); 24 | } 25 | 26 | std::string 27 | comment::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const comment& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const comment& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/data_table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | data_table::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "location=", location); 14 | cucumber::messages::to_string(oss, ", rows=", rows); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | data_table::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("location"), location); 23 | cucumber::messages::to_json(j, camelize("rows"), rows); 24 | } 25 | 26 | std::string 27 | data_table::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const data_table& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const data_table& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/duration.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | duration::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "seconds=", seconds); 14 | cucumber::messages::to_string(oss, ", nanos=", nanos); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | duration::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("seconds"), seconds); 23 | cucumber::messages::to_json(j, camelize("nanos"), nanos); 24 | } 25 | 26 | std::string 27 | duration::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const duration& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const duration& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/hook_type.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string_view 9 | to_string(hook_type v) 10 | { 11 | using map_type = std::unordered_map; 12 | 13 | static const map_type m = { 14 | { hook_type::BEFORE_TEST_RUN, "BEFORE_TEST_RUN" }, 15 | { hook_type::AFTER_TEST_RUN, "AFTER_TEST_RUN" }, 16 | { hook_type::BEFORE_TEST_CASE, "BEFORE_TEST_CASE" }, 17 | { hook_type::AFTER_TEST_CASE, "AFTER_TEST_CASE" }, 18 | { hook_type::BEFORE_TEST_STEP, "BEFORE_TEST_STEP" }, 19 | { hook_type::AFTER_TEST_STEP, "AFTER_TEST_STEP" } 20 | }; 21 | 22 | return m.at(v); 23 | } 24 | 25 | std::ostream& 26 | operator<<(std::ostream& os, hook_type v) 27 | { 28 | os << to_string(v); 29 | 30 | return os; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/location.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | location::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "line=", line); 14 | cucumber::messages::to_string(oss, ", column=", column); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | location::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("line"), line); 23 | cucumber::messages::to_json(j, camelize("column"), column); 24 | } 25 | 26 | std::string 27 | location::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const location& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const location& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/parse_error.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | parse_error::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "source=", source); 14 | cucumber::messages::to_string(oss, ", message=", message); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | parse_error::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("source"), source); 23 | cucumber::messages::to_json(j, camelize("message"), message); 24 | } 25 | 26 | std::string 27 | parse_error::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const parse_error& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const parse_error& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/pickle_step_type.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string_view 9 | to_string(pickle_step_type v) 10 | { 11 | using map_type = std::unordered_map; 12 | 13 | static const map_type m = { 14 | { pickle_step_type::UNKNOWN, "Unknown" }, 15 | { pickle_step_type::CONTEXT, "Context" }, 16 | { pickle_step_type::ACTION, "Action" }, 17 | { pickle_step_type::OUTCOME, "Outcome" } 18 | }; 19 | 20 | return m.at(v); 21 | } 22 | 23 | std::ostream& 24 | operator<<(std::ostream& os, pickle_step_type v) 25 | { 26 | os << to_string(v); 27 | 28 | return os; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/pickle_table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | pickle_table::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "rows=", rows); 14 | 15 | return oss.str(); 16 | } 17 | 18 | void 19 | pickle_table::to_json(json& j) const 20 | { 21 | cucumber::messages::to_json(j, camelize("rows"), rows); 22 | } 23 | 24 | std::string 25 | pickle_table::to_json() const 26 | { 27 | std::ostringstream oss; 28 | json j; 29 | 30 | to_json(j); 31 | 32 | oss << j; 33 | 34 | return oss.str(); 35 | } 36 | 37 | std::ostream& 38 | operator<<(std::ostream& os, const pickle_table& msg) 39 | { 40 | os << msg.to_string(); 41 | 42 | return os; 43 | } 44 | 45 | void to_json(json& j, const pickle_table& m) 46 | { m.to_json(j); } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/pickle_table_cell.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | pickle_table_cell::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "value=", value); 14 | 15 | return oss.str(); 16 | } 17 | 18 | void 19 | pickle_table_cell::to_json(json& j) const 20 | { 21 | cucumber::messages::to_json(j, camelize("value"), value); 22 | } 23 | 24 | std::string 25 | pickle_table_cell::to_json() const 26 | { 27 | std::ostringstream oss; 28 | json j; 29 | 30 | to_json(j); 31 | 32 | oss << j; 33 | 34 | return oss.str(); 35 | } 36 | 37 | std::ostream& 38 | operator<<(std::ostream& os, const pickle_table_cell& msg) 39 | { 40 | os << msg.to_string(); 41 | 42 | return os; 43 | } 44 | 45 | void to_json(json& j, const pickle_table_cell& m) 46 | { m.to_json(j); } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/pickle_table_row.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | pickle_table_row::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "cells=", cells); 14 | 15 | return oss.str(); 16 | } 17 | 18 | void 19 | pickle_table_row::to_json(json& j) const 20 | { 21 | cucumber::messages::to_json(j, camelize("cells"), cells); 22 | } 23 | 24 | std::string 25 | pickle_table_row::to_json() const 26 | { 27 | std::ostringstream oss; 28 | json j; 29 | 30 | to_json(j); 31 | 32 | oss << j; 33 | 34 | return oss.str(); 35 | } 36 | 37 | std::ostream& 38 | operator<<(std::ostream& os, const pickle_table_row& msg) 39 | { 40 | os << msg.to_string(); 41 | 42 | return os; 43 | } 44 | 45 | void to_json(json& j, const pickle_table_row& m) 46 | { m.to_json(j); } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/pickle_tag.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | pickle_tag::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "name=", name); 14 | cucumber::messages::to_string(oss, ", ast_node_id=", ast_node_id); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | pickle_tag::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("name"), name); 23 | cucumber::messages::to_json(j, camelize("ast_node_id"), ast_node_id); 24 | } 25 | 26 | std::string 27 | pickle_tag::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const pickle_tag& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const pickle_tag& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/product.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | product::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "name=", name); 14 | cucumber::messages::to_string(oss, ", version=", version); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | product::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("name"), name); 23 | cucumber::messages::to_json(j, camelize("version"), version); 24 | } 25 | 26 | std::string 27 | product::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const product& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const product& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/rule_child.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | rule_child::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "background=", background); 14 | cucumber::messages::to_string(oss, ", scenario=", scenario); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | rule_child::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("background"), background); 23 | cucumber::messages::to_json(j, camelize("scenario"), scenario); 24 | } 25 | 26 | std::string 27 | rule_child::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const rule_child& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const rule_child& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/source_media_type.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string_view 9 | to_string(source_media_type v) 10 | { 11 | using map_type = std::unordered_map; 12 | 13 | static const map_type m = { 14 | { source_media_type::TEXT_X_CUCUMBER_GHERKIN_PLAIN, "text/x.cucumber.gherkin+plain" }, 15 | { source_media_type::TEXT_X_CUCUMBER_GHERKIN_MARKDOWN, "text/x.cucumber.gherkin+markdown" } 16 | }; 17 | 18 | return m.at(v); 19 | } 20 | 21 | std::ostream& 22 | operator<<(std::ostream& os, source_media_type v) 23 | { 24 | os << to_string(v); 25 | 26 | return os; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/step_definition_pattern_type.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string_view 9 | to_string(step_definition_pattern_type v) 10 | { 11 | using map_type = std::unordered_map; 12 | 13 | static const map_type m = { 14 | { step_definition_pattern_type::CUCUMBER_EXPRESSION, "CUCUMBER_EXPRESSION" }, 15 | { step_definition_pattern_type::REGULAR_EXPRESSION, "REGULAR_EXPRESSION" } 16 | }; 17 | 18 | return m.at(v); 19 | } 20 | 21 | std::ostream& 22 | operator<<(std::ostream& os, step_definition_pattern_type v) 23 | { 24 | os << to_string(v); 25 | 26 | return os; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/step_keyword_type.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string_view 9 | to_string(step_keyword_type v) 10 | { 11 | using map_type = std::unordered_map; 12 | 13 | static const map_type m = { 14 | { step_keyword_type::UNKNOWN, "Unknown" }, 15 | { step_keyword_type::CONTEXT, "Context" }, 16 | { step_keyword_type::ACTION, "Action" }, 17 | { step_keyword_type::OUTCOME, "Outcome" }, 18 | { step_keyword_type::CONJUNCTION, "Conjunction" } 19 | }; 20 | 21 | return m.at(v); 22 | } 23 | 24 | std::ostream& 25 | operator<<(std::ostream& os, step_keyword_type v) 26 | { 27 | os << to_string(v); 28 | 29 | return os; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/step_match_arguments_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | step_match_arguments_list::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "step_match_arguments=", step_match_arguments); 14 | 15 | return oss.str(); 16 | } 17 | 18 | void 19 | step_match_arguments_list::to_json(json& j) const 20 | { 21 | cucumber::messages::to_json(j, camelize("step_match_arguments"), step_match_arguments); 22 | } 23 | 24 | std::string 25 | step_match_arguments_list::to_json() const 26 | { 27 | std::ostringstream oss; 28 | json j; 29 | 30 | to_json(j); 31 | 32 | oss << j; 33 | 34 | return oss.str(); 35 | } 36 | 37 | std::ostream& 38 | operator<<(std::ostream& os, const step_match_arguments_list& msg) 39 | { 40 | os << msg.to_string(); 41 | 42 | return os; 43 | } 44 | 45 | void to_json(json& j, const step_match_arguments_list& m) 46 | { m.to_json(j); } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/table_cell.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | table_cell::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "location=", location); 14 | cucumber::messages::to_string(oss, ", value=", value); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | table_cell::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("location"), location); 23 | cucumber::messages::to_json(j, camelize("value"), value); 24 | } 25 | 26 | std::string 27 | table_cell::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const table_cell& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const table_cell& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/test_run_started.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | test_run_started::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "timestamp=", timestamp); 14 | cucumber::messages::to_string(oss, ", id=", id); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | test_run_started::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("timestamp"), timestamp); 23 | cucumber::messages::to_json(j, camelize("id"), id); 24 | } 25 | 26 | std::string 27 | test_run_started::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const test_run_started& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const test_run_started& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/test_step_result_status.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string_view 9 | to_string(test_step_result_status v) 10 | { 11 | using map_type = std::unordered_map; 12 | 13 | static const map_type m = { 14 | { test_step_result_status::UNKNOWN, "UNKNOWN" }, 15 | { test_step_result_status::PASSED, "PASSED" }, 16 | { test_step_result_status::SKIPPED, "SKIPPED" }, 17 | { test_step_result_status::PENDING, "PENDING" }, 18 | { test_step_result_status::UNDEFINED, "UNDEFINED" }, 19 | { test_step_result_status::AMBIGUOUS, "AMBIGUOUS" }, 20 | { test_step_result_status::FAILED, "FAILED" } 21 | }; 22 | 23 | return m.at(v); 24 | } 25 | 26 | std::ostream& 27 | operator<<(std::ostream& os, test_step_result_status v) 28 | { 29 | os << to_string(v); 30 | 31 | return os; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/timestamp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace cucumber::messages { 7 | 8 | std::string 9 | timestamp::to_string() const 10 | { 11 | std::ostringstream oss; 12 | 13 | cucumber::messages::to_string(oss, "seconds=", seconds); 14 | cucumber::messages::to_string(oss, ", nanos=", nanos); 15 | 16 | return oss.str(); 17 | } 18 | 19 | void 20 | timestamp::to_json(json& j) const 21 | { 22 | cucumber::messages::to_json(j, camelize("seconds"), seconds); 23 | cucumber::messages::to_json(j, camelize("nanos"), nanos); 24 | } 25 | 26 | std::string 27 | timestamp::to_json() const 28 | { 29 | std::ostringstream oss; 30 | json j; 31 | 32 | to_json(j); 33 | 34 | oss << j; 35 | 36 | return oss.str(); 37 | } 38 | 39 | std::ostream& 40 | operator<<(std::ostream& os, const timestamp& msg) 41 | { 42 | os << msg.to_string(); 43 | 44 | return os; 45 | } 46 | 47 | void to_json(json& j, const timestamp& m) 48 | { m.to_json(j); } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/cucumber/messages/utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace cucumber::messages { 4 | 5 | // https://codereview.stackexchange.com/questions/263749/codewars-kata-converting-snake-case-identifiers-to-camelcase-in-c 6 | std::string 7 | camelize(std::string s, bool initial_tail) 8 | { 9 | std::size_t n = 0; 10 | bool tail = initial_tail; 11 | 12 | for (unsigned char c : s) { 13 | if (c == '-' || c == '_') { 14 | tail = false; 15 | } else if (tail) { 16 | s[n++] = c; 17 | } else { 18 | tail = true; 19 | s[n++] = std::toupper(c); 20 | } 21 | } 22 | 23 | s.resize(n); 24 | 25 | return s; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /cpp/src/lib/messages/link.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | libs: 3 | public: 4 | - nlohmann_json::nlohmann_json 5 | -------------------------------------------------------------------------------- /dotnet/.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/ruby 3 | { 4 | "name": "Ruby", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "mcr.microsoft.com/devcontainers/ruby:1-3.3-bullseye", 7 | "features": { 8 | "ghcr.io/jungaretti/features/make:1": {}, 9 | "ghcr.io/devcontainers/features/dotnet:2": { 10 | "version": "8.0" 11 | } 12 | } 13 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 14 | // "forwardPorts": [], 15 | // Use 'postCreateCommand' to run commands after the container is created. 16 | // "postCreateCommand": "ruby --version", 17 | // Configure tool-specific properties. 18 | // "customizations": {}, 19 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 20 | // "remoteUser": "root" 21 | } -------------------------------------------------------------------------------- /dotnet/.vs/ProjectEvaluation/cucumber.messages.strings.v8.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/messages/f196c49ebc6a7299bf75304e1c8fce90d8453b9b/dotnet/.vs/ProjectEvaluation/cucumber.messages.strings.v8.bin -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages.Specs/ConvertersTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Xunit; 7 | 8 | namespace Cucumber.Messages.Specs 9 | { 10 | public class ConvertersTests 11 | { 12 | 13 | [Fact] 14 | public void ConvertsToAndFromTimestamp() 15 | { 16 | var current = DateTime.Parse("2024-06-29T17:29:47.1537257Z", null, System.Globalization.DateTimeStyles.RoundtripKind); 17 | var timestamp = Converters.ToTimestamp(current); 18 | 19 | var dt = Converters.ToDateTime(timestamp); 20 | 21 | Assert.Equal(current, dt); 22 | } 23 | 24 | [Fact] 25 | public void ConvertsToAndFromDuration() 26 | { 27 | var current = TimeSpan.FromSeconds(3.000161); 28 | var duration = Converters.ToDuration(current); 29 | 30 | var ts = Converters.ToTimeSpan(duration); 31 | 32 | Assert.Equal(current, ts); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages.Specs/Cucumber.Messages.Specs.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | False 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages.Specs/MessageToNdjsonWriterSUT.cs: -------------------------------------------------------------------------------- 1 | using Io.Cucumber.Messages.Types; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Cucumber.Messages.Specs 10 | { 11 | internal class MessageToNdjsonWriterSUT : MessageToNdjsonWriter 12 | { 13 | public MessageToNdjsonWriterSUT(Stream stream) : base(stream, (StreamWriter streamWriter, Envelope envelope) => streamWriter.Write(NdjsonSerializer.Serialize(envelope))) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages.Specs/MessagesTest.cs: -------------------------------------------------------------------------------- 1 | using Io.Cucumber.Messages.Types; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Xunit; 8 | 9 | namespace Cucumber.Messages.Specs 10 | { 11 | public class MessagesTest 12 | { 13 | 14 | [Fact] 15 | public void ThrowsWhenRequiredFieldsAreMissing() 16 | { 17 | Assert.Throws(() => new Background(null, null, null, null, null, null)); 18 | } 19 | 20 | [Fact] 21 | public void IsValidWhenNoRequiredFieldsAreMissing() 22 | { 23 | // This should succeed as no constructor arguments to an Envelope are required. 24 | var env = new Envelope(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages.Specs/NdJsonMessageReaderSUT.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Cucumber.Messages.Specs 9 | { 10 | internal class NdjsonMessageReaderSUT : NdjsonMessageReader 11 | { 12 | public NdjsonMessageReaderSUT(Stream inputStream) : base(inputStream, (string line) => NdjsonSerializer.Deserialize(line)) 13 | { 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages.Specs/ProtocolVersionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | using Xunit; 8 | 9 | namespace Cucumber.Messages.Specs 10 | { 11 | public class ProtocolVersionTest 12 | { 13 | [Fact] 14 | public void ProtocolVersionIsCorrect() 15 | { 16 | Assert.Matches(@"\d+\.\d+\.\d+(-[0-9A-Za-z-](\.[0-9A-Za-z-])*)?", Cucumber.Messages.ProtocolVersion.Version); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages/.gitignore: -------------------------------------------------------------------------------- 1 | # protoc-generated file 2 | Messages.cs 3 | 4 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages/.releaseable: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/messages/f196c49ebc6a7299bf75304e1c8fce90d8453b9b/dotnet/Cucumber.Messages/.releaseable -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages/Cucumber.Messages.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/messages/f196c49ebc6a7299bf75304e1c8fce90d8453b9b/dotnet/Cucumber.Messages/Cucumber.Messages.snk -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages/ProtocolVersion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Text; 5 | 6 | namespace Cucumber.Messages 7 | { 8 | public class ProtocolVersion 9 | { 10 | public static string Version 11 | { 12 | get 13 | { 14 | return GetPackageVersion(typeof(ProtocolVersion).GetTypeInfo().Assembly); 15 | } 16 | } 17 | 18 | private static string GetPackageVersion(Assembly assembly) 19 | { 20 | var version = assembly.GetCustomAttribute()?.InformationalVersion; 21 | return version?.Split(new char['+'], 2)[0]; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages/Resources/cucumber-mark-green-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/messages/f196c49ebc6a7299bf75304e1c8fce90d8453b9b/dotnet/Cucumber.Messages/Resources/cucumber-mark-green-128.png -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages/generated/AttachmentContentEncoding.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Reflection; 4 | 5 | namespace Io.Cucumber.Messages.Types; 6 | 7 | // ------------------------------------------------------------------------------ 8 | // This code was generated based on the Cucumber JSON schema 9 | // Changes to this file may cause incorrect behavior and will be lost if 10 | // the code is regenerated. 11 | // ------------------------------------------------------------------------------ 12 | 13 | public enum AttachmentContentEncoding { 14 | 15 | [Description("IDENTITY")] 16 | IDENTITY, 17 | 18 | [Description("BASE64")] 19 | BASE64 20 | } 21 | 22 | public static class AttachmentContentEncodingExtensions 23 | { 24 | public static string Value(this AttachmentContentEncoding v) { 25 | var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); 26 | return attribute == null ? v.ToString() : attribute.Description; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages/generated/PickleStepType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Reflection; 4 | 5 | namespace Io.Cucumber.Messages.Types; 6 | 7 | // ------------------------------------------------------------------------------ 8 | // This code was generated based on the Cucumber JSON schema 9 | // Changes to this file may cause incorrect behavior and will be lost if 10 | // the code is regenerated. 11 | // ------------------------------------------------------------------------------ 12 | 13 | public enum PickleStepType { 14 | 15 | [Description("Unknown")] 16 | UNKNOWN, 17 | 18 | [Description("Context")] 19 | CONTEXT, 20 | 21 | [Description("Action")] 22 | ACTION, 23 | 24 | [Description("Outcome")] 25 | OUTCOME 26 | } 27 | 28 | public static class PickleStepTypeExtensions 29 | { 30 | public static string Value(this PickleStepType v) { 31 | var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); 32 | return attribute == null ? v.ToString() : attribute.Description; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages/generated/SourceMediaType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Reflection; 4 | 5 | namespace Io.Cucumber.Messages.Types; 6 | 7 | // ------------------------------------------------------------------------------ 8 | // This code was generated based on the Cucumber JSON schema 9 | // Changes to this file may cause incorrect behavior and will be lost if 10 | // the code is regenerated. 11 | // ------------------------------------------------------------------------------ 12 | 13 | public enum SourceMediaType { 14 | 15 | [Description("text/x.cucumber.gherkin+plain")] 16 | TEXT_X_CUCUMBER_GHERKIN_PLAIN, 17 | 18 | [Description("text/x.cucumber.gherkin+markdown")] 19 | TEXT_X_CUCUMBER_GHERKIN_MARKDOWN 20 | } 21 | 22 | public static class SourceMediaTypeExtensions 23 | { 24 | public static string Value(this SourceMediaType v) { 25 | var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); 26 | return attribute == null ? v.ToString() : attribute.Description; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dotnet/Cucumber.Messages/generated/StepDefinitionPatternType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Reflection; 4 | 5 | namespace Io.Cucumber.Messages.Types; 6 | 7 | // ------------------------------------------------------------------------------ 8 | // This code was generated based on the Cucumber JSON schema 9 | // Changes to this file may cause incorrect behavior and will be lost if 10 | // the code is regenerated. 11 | // ------------------------------------------------------------------------------ 12 | 13 | public enum StepDefinitionPatternType { 14 | 15 | [Description("CUCUMBER_EXPRESSION")] 16 | CUCUMBER_EXPRESSION, 17 | 18 | [Description("REGULAR_EXPRESSION")] 19 | REGULAR_EXPRESSION 20 | } 21 | 22 | public static class StepDefinitionPatternTypeExtensions 23 | { 24 | public static string Value(this StepDefinitionPatternType v) { 25 | var attribute = v.GetType().GetField(v.ToString()).GetCustomAttribute(); 26 | return attribute == null ? v.ToString() : attribute.Description; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dotnet/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cucumber Ltd and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /elixir/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/elixir,vscode 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=elixir,vscode 4 | 5 | ### Elixir ### 6 | /_build 7 | /cover 8 | /deps 9 | /doc 10 | /.fetch 11 | erl_crash.dump 12 | *.ez 13 | *.beam 14 | /config/*.secret.exs 15 | .elixir_ls/ 16 | 17 | ### Elixir Patch ### 18 | 19 | ### vscode ### 20 | .vscode/* 21 | !.vscode/settings.json 22 | !.vscode/tasks.json 23 | !.vscode/launch.json 24 | !.vscode/extensions.json 25 | *.code-workspace 26 | 27 | # End of https://www.toptal.com/developers/gitignore/api/elixir,vscode 28 | 29 | .deps 30 | .tested 31 | .compile_messages 32 | .setup_mix_and_get_dependencies 33 | -------------------------------------------------------------------------------- /elixir/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cucumber Ltd and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /elixir/Makefile: -------------------------------------------------------------------------------- 1 | include default.mk 2 | 3 | clean: 4 | rm -rf _build deps .deps .tested 5 | rm -rf lib/cucumber_messages/generated/* 6 | 7 | .deps: setup_mix_and_get_dependencies update_proto_file compile_messages revert_proto_file 8 | touch .deps 9 | 10 | setup_mix_and_get_dependencies: 11 | mix local.hex --force 12 | mix deps.get 13 | .PHONY: setup_mix_and_get_dependencies 14 | 15 | update_proto_file: messages.proto 16 | mv $< $<.bak 17 | cat $<.bak | sed "s/package io.cucumber.messages/package cucumber_messages/" > $< 18 | 19 | compile_messages: 20 | MIX_ENV=prod mix protox.generate --multiple-files --output-path=lib/cucumber_messages/generated messages.proto 21 | .PHONY: compile_messages 22 | 23 | revert_proto_file: messages.proto.bak 24 | mv messages.proto.bak messages.proto 25 | .PHONY: revert_proto_file 26 | -------------------------------------------------------------------------------- /elixir/README.md: -------------------------------------------------------------------------------- 1 | # CucumberMessages 2 | 3 | This package is released at [hex.pm](https://hex.pm/packages/cucumber_messages). 4 | 5 | ## Credits 6 | 7 | This library is originally funded by [UCLL](https://www.ucll.be) its "First Time Right" research project. 8 | -------------------------------------------------------------------------------- /elixir/lib/cucumber_message.ex: -------------------------------------------------------------------------------- 1 | defmodule CucumberMessages do 2 | @moduledoc """ 3 | This small library its sole purpose is to convert the protobuf schema to Elixir code. In order to use this library, you do not need protoc installed at all! 4 | """ 5 | 6 | @doc """ 7 | Convert a list of envelopes to the passed format. At the moment only ndjson is supported until there is binary test data. 8 | 9 | Because the underlying Protox library doesn't support JSON conversion, we had to write a manual implementation. ndjson formatting is, at the moment, only supported for the `cucumber_gherkin` library. Other messages will not properly be formatted according to protobuf protocols. 10 | """ 11 | def convert_envelopes_to(envelopes, :ndjson) do 12 | Enum.map(envelopes, &CucumberMessages.Writer.envelope_to_ndjson!/1) 13 | |> Enum.map(&Jason.encode!(&1)) 14 | |> Enum.join("\n") 15 | |> case do 16 | "" -> "" 17 | result -> result <> "\n" 18 | end 19 | end 20 | 21 | # def convert_envelopes_to(envelopes, :binary) do 22 | # end 23 | end 24 | -------------------------------------------------------------------------------- /elixir/lib/cucumber_messages/generated/.gitignore: -------------------------------------------------------------------------------- 1 | /*.ex -------------------------------------------------------------------------------- /elixir/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule CucumberMessages.MixProject do 2 | @moduledoc false 3 | use Mix.Project 4 | 5 | @github "https://github.com/cucumber/messages" 6 | 7 | def project do 8 | [ 9 | app: :cucumber_messages, 10 | version: "27.2.0", 11 | name: "CucumberMessages", 12 | description: description(), 13 | package: package(), 14 | elixir: "~> 1.10", 15 | start_permanent: Mix.env() == :prod, 16 | deps: deps() 17 | ] 18 | end 19 | 20 | def application do 21 | [ 22 | extra_applications: [:logger] 23 | ] 24 | end 25 | 26 | defp deps do 27 | [ 28 | {:protox, "~> 2.0"}, 29 | {:jason, "~> 1.4"}, 30 | {:ex_doc, "~> 0.38", only: :dev, runtime: false} 31 | ] 32 | end 33 | 34 | defp description() do 35 | "Elixir implementation of the cucumber messages protobuf schema" 36 | end 37 | 38 | defp package() do 39 | [ 40 | licenses: ["MIT"], 41 | source_url: @github, 42 | links: %{"GitHub" => @github} 43 | ] 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /elixir/test/cucumber_message_test.exs: -------------------------------------------------------------------------------- 1 | defmodule CucumberMessagesTest do 2 | use ExUnit.Case 3 | 4 | # No testdata for now 5 | end 6 | -------------------------------------------------------------------------------- /elixir/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /go/.gitignore: -------------------------------------------------------------------------------- 1 | .built 2 | .compared 3 | .deps 4 | .dist 5 | .dist-compressed 6 | .go-get 7 | .gofmt 8 | .linted 9 | .tested* 10 | acceptance/ 11 | bin/ 12 | dist/ 13 | dist_compressed/ 14 | *.bin 15 | *.iml 16 | # upx dist/cucumber-gherkin-openbsd-386 fails with a core dump 17 | core.*.!usr!bin!upx-ucl 18 | -------------------------------------------------------------------------------- /go/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cucumber Ltd and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /go/Makefile: -------------------------------------------------------------------------------- 1 | schemas = $(shell find ../jsonschema -name "*.json") 2 | 3 | .DEFAULT_GOAL = help 4 | 5 | help: ## Show this help 6 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \n\nWhere is one of:\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 7 | 8 | generate: require messages.go ## Generate go code based on the schemas found in ../jsonschema and using the scripts in ../jsonschema/scripts for the generation 9 | 10 | require: ## Check requirements for the code generation (ruby and go are required) 11 | @ruby --version >/dev/null 2>&1 || (echo "ERROR: ruby is required."; exit 1) 12 | @go version >/dev/null 2>&1 || (echo "ERROR: go is required."; exit 1) 13 | 14 | clean: ## Remove automatically generated files and related artifacts 15 | rm -f messages.go 16 | 17 | messages.go: $(schemas) ../codegen/codegen.rb ../codegen/templates/go.go.erb ../codegen/templates/go.enum.go.erb 18 | ruby ../codegen/codegen.rb Generator::Go go.go.erb > $@ 19 | ruby ../codegen/codegen.rb Generator::Go go.enum.go.erb >> $@ 20 | -------------------------------------------------------------------------------- /go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/cucumber/messages/go/v27 2 | 3 | require ( 4 | github.com/google/uuid v1.6.0 5 | github.com/stretchr/testify v1.10.0 6 | ) 7 | 8 | require ( 9 | github.com/davecgh/go-spew v1.1.1 // indirect 10 | github.com/pmezard/go-difflib v1.0.0 // indirect 11 | gopkg.in/yaml.v3 v3.0.1 // indirect 12 | ) 13 | 14 | go 1.19 15 | -------------------------------------------------------------------------------- /go/id_generator.go: -------------------------------------------------------------------------------- 1 | package messages 2 | 3 | import ( 4 | "strconv" 5 | 6 | "github.com/google/uuid" 7 | ) 8 | 9 | type IdGenerator interface { 10 | newId() func() string 11 | } 12 | 13 | type Incrementing struct { 14 | next int 15 | } 16 | 17 | func (self *Incrementing) NewId() string { 18 | result := strconv.Itoa(self.next) 19 | self.next++ 20 | return result 21 | } 22 | 23 | type UUID struct { 24 | next int 25 | } 26 | 27 | func (i UUID) NewId() string { 28 | return uuid.New().String() 29 | } 30 | -------------------------------------------------------------------------------- /go/id_generator_test.go: -------------------------------------------------------------------------------- 1 | package messages 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestIdGeneratorIncrementing(t *testing.T) { 8 | newId := (&Incrementing{0}).NewId 9 | 10 | generated := newId() 11 | if generated != "0" { 12 | t.Errorf("Expected 0, got: %s", generated) 13 | } 14 | 15 | generated = newId() 16 | if generated != "1" { 17 | t.Errorf("Expected 1, got: %s", generated) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /go/time_conversion.go: -------------------------------------------------------------------------------- 1 | package messages 2 | 3 | import "time" 4 | 5 | const nanosPerSecond = 1000000000 6 | 7 | func DurationToGoDuration(duration Duration) time.Duration { 8 | secondNanos := duration.Seconds * nanosPerSecond 9 | return time.Duration(secondNanos + int64(duration.Nanos)) 10 | } 11 | 12 | func GoDurationToDuration(goDuration time.Duration) Duration { 13 | seconds := int64(goDuration / nanosPerSecond) 14 | nanos := int64(goDuration % nanosPerSecond) 15 | return Duration{ 16 | Seconds: seconds, 17 | Nanos: nanos, 18 | } 19 | } 20 | 21 | func TimestampToGoTime(timestamp Timestamp) time.Time { 22 | return time.Unix(timestamp.Seconds, timestamp.Nanos) 23 | } 24 | 25 | func GoTimeToTimestamp(t time.Time) Timestamp { 26 | unixNanos := t.UnixNano() 27 | seconds := unixNanos / nanosPerSecond 28 | nanos := unixNanos % nanosPerSecond 29 | 30 | return Timestamp{ 31 | Seconds: seconds, 32 | Nanos: nanos, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | target/ 4 | release.properties 5 | pom.xml.releaseBackup 6 | pom.xml.versionsBackup 7 | dependency-reduced-pom.xml 8 | .classpath 9 | .deps 10 | .project 11 | .settings/ 12 | .tested* 13 | .compared 14 | .built 15 | .codegen 16 | # Approval tests 17 | acceptance/ 18 | -------------------------------------------------------------------------------- /java/README.md: -------------------------------------------------------------------------------- 1 | [![Maven Central](https://img.shields.io/maven-central/v/io.cucumber/messages.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.cucumber%22%20AND%20a:%22messages%22) 2 | 3 | # Cucumber Messages for Java (JSON schema) 4 | 5 | ```java 6 | Iterable envelopes = new io.cucumber.messages.NdjsonToMessageIterable(inputStream) 7 | for (Envelope envelope : envelopes) { 8 | // Do something with the message 9 | } 10 | ``` 11 | 12 | See Unit tests for more examples. 13 | -------------------------------------------------------------------------------- /java/src/generated/java/io/cucumber/messages/types/AttachmentContentEncoding.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages.types; 2 | 3 | // Generated code 4 | @SuppressWarnings("unused") 5 | public enum AttachmentContentEncoding { 6 | 7 | IDENTITY("IDENTITY"), 8 | 9 | BASE64("BASE64"); 10 | 11 | private final String value; 12 | 13 | AttachmentContentEncoding(String value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return this.value; 20 | } 21 | 22 | public String value() { 23 | return this.value; 24 | } 25 | 26 | public static AttachmentContentEncoding fromValue(String value) { 27 | for (AttachmentContentEncoding v : values()) { 28 | if (v.value.equals(value)) { 29 | return v; 30 | } 31 | } 32 | throw new IllegalArgumentException(value); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java/src/generated/java/io/cucumber/messages/types/HookType.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages.types; 2 | 3 | // Generated code 4 | @SuppressWarnings("unused") 5 | public enum HookType { 6 | 7 | BEFORE_TEST_RUN("BEFORE_TEST_RUN"), 8 | 9 | AFTER_TEST_RUN("AFTER_TEST_RUN"), 10 | 11 | BEFORE_TEST_CASE("BEFORE_TEST_CASE"), 12 | 13 | AFTER_TEST_CASE("AFTER_TEST_CASE"), 14 | 15 | BEFORE_TEST_STEP("BEFORE_TEST_STEP"), 16 | 17 | AFTER_TEST_STEP("AFTER_TEST_STEP"); 18 | 19 | private final String value; 20 | 21 | HookType(String value) { 22 | this.value = value; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return this.value; 28 | } 29 | 30 | public String value() { 31 | return this.value; 32 | } 33 | 34 | public static HookType fromValue(String value) { 35 | for (HookType v : values()) { 36 | if (v.value.equals(value)) { 37 | return v; 38 | } 39 | } 40 | throw new IllegalArgumentException(value); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java/src/generated/java/io/cucumber/messages/types/PickleStepType.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages.types; 2 | 3 | // Generated code 4 | @SuppressWarnings("unused") 5 | public enum PickleStepType { 6 | 7 | UNKNOWN("Unknown"), 8 | 9 | CONTEXT("Context"), 10 | 11 | ACTION("Action"), 12 | 13 | OUTCOME("Outcome"); 14 | 15 | private final String value; 16 | 17 | PickleStepType(String value) { 18 | this.value = value; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return this.value; 24 | } 25 | 26 | public String value() { 27 | return this.value; 28 | } 29 | 30 | public static PickleStepType fromValue(String value) { 31 | for (PickleStepType v : values()) { 32 | if (v.value.equals(value)) { 33 | return v; 34 | } 35 | } 36 | throw new IllegalArgumentException(value); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /java/src/generated/java/io/cucumber/messages/types/SourceMediaType.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages.types; 2 | 3 | // Generated code 4 | @SuppressWarnings("unused") 5 | public enum SourceMediaType { 6 | 7 | TEXT_X_CUCUMBER_GHERKIN_PLAIN("text/x.cucumber.gherkin+plain"), 8 | 9 | TEXT_X_CUCUMBER_GHERKIN_MARKDOWN("text/x.cucumber.gherkin+markdown"); 10 | 11 | private final String value; 12 | 13 | SourceMediaType(String value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return this.value; 20 | } 21 | 22 | public String value() { 23 | return this.value; 24 | } 25 | 26 | public static SourceMediaType fromValue(String value) { 27 | for (SourceMediaType v : values()) { 28 | if (v.value.equals(value)) { 29 | return v; 30 | } 31 | } 32 | throw new IllegalArgumentException(value); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java/src/generated/java/io/cucumber/messages/types/StepDefinitionPatternType.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages.types; 2 | 3 | // Generated code 4 | @SuppressWarnings("unused") 5 | public enum StepDefinitionPatternType { 6 | 7 | CUCUMBER_EXPRESSION("CUCUMBER_EXPRESSION"), 8 | 9 | REGULAR_EXPRESSION("REGULAR_EXPRESSION"); 10 | 11 | private final String value; 12 | 13 | StepDefinitionPatternType(String value) { 14 | this.value = value; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return this.value; 20 | } 21 | 22 | public String value() { 23 | return this.value; 24 | } 25 | 26 | public static StepDefinitionPatternType fromValue(String value) { 27 | for (StepDefinitionPatternType v : values()) { 28 | if (v.value.equals(value)) { 29 | return v; 30 | } 31 | } 32 | throw new IllegalArgumentException(value); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java/src/generated/java/io/cucumber/messages/types/StepKeywordType.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages.types; 2 | 3 | // Generated code 4 | @SuppressWarnings("unused") 5 | public enum StepKeywordType { 6 | 7 | UNKNOWN("Unknown"), 8 | 9 | CONTEXT("Context"), 10 | 11 | ACTION("Action"), 12 | 13 | OUTCOME("Outcome"), 14 | 15 | CONJUNCTION("Conjunction"); 16 | 17 | private final String value; 18 | 19 | StepKeywordType(String value) { 20 | this.value = value; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return this.value; 26 | } 27 | 28 | public String value() { 29 | return this.value; 30 | } 31 | 32 | public static StepKeywordType fromValue(String value) { 33 | for (StepKeywordType v : values()) { 34 | if (v.value.equals(value)) { 35 | return v; 36 | } 37 | } 38 | throw new IllegalArgumentException(value); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java/src/generated/java/io/cucumber/messages/types/TestStepResultStatus.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages.types; 2 | 3 | // Generated code 4 | @SuppressWarnings("unused") 5 | public enum TestStepResultStatus { 6 | 7 | UNKNOWN("UNKNOWN"), 8 | 9 | PASSED("PASSED"), 10 | 11 | SKIPPED("SKIPPED"), 12 | 13 | PENDING("PENDING"), 14 | 15 | UNDEFINED("UNDEFINED"), 16 | 17 | AMBIGUOUS("AMBIGUOUS"), 18 | 19 | FAILED("FAILED"); 20 | 21 | private final String value; 22 | 23 | TestStepResultStatus(String value) { 24 | this.value = value; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return this.value; 30 | } 31 | 32 | public String value() { 33 | return this.value; 34 | } 35 | 36 | public static TestStepResultStatus fromValue(String value) { 37 | for (TestStepResultStatus v : values()) { 38 | if (v.value.equals(value)) { 39 | return v; 40 | } 41 | } 42 | throw new IllegalArgumentException(value); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java/src/main/java/io/cucumber/messages/IdGenerator.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages; 2 | 3 | public interface IdGenerator { 4 | String newId(); 5 | } 6 | -------------------------------------------------------------------------------- /java/src/main/java/io/cucumber/messages/ProtocolVersion.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages; 2 | 3 | import java.util.ResourceBundle; 4 | 5 | public final class ProtocolVersion { 6 | 7 | private ProtocolVersion(){ 8 | 9 | } 10 | 11 | public static String getVersion() { 12 | return ResourceBundle.getBundle("io.cucumber.messages.version").getString("messages.version"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /java/src/main/java/io/cucumber/messages/TimeConversion.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages; 2 | 3 | import io.cucumber.messages.types.Duration; 4 | import io.cucumber.messages.types.Timestamp; 5 | 6 | @Deprecated 7 | @SuppressWarnings("unused") 8 | public final class TimeConversion { 9 | 10 | private TimeConversion(){ 11 | 12 | } 13 | 14 | public static Timestamp javaInstantToTimestamp(java.time.Instant instant) { 15 | return Convertor.toMessage(instant); 16 | } 17 | 18 | public static Duration javaDurationToDuration(java.time.Duration duration) { 19 | return Convertor.toMessage(duration); 20 | } 21 | 22 | public static java.time.Instant timestampToJavaInstant(Timestamp timestamp) { 23 | return Convertor.toInstant(timestamp); 24 | } 25 | 26 | public static java.time.Duration durationToJavaDuration(Duration duration) { 27 | return Convertor.toDuration(duration); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java/src/main/resources/io/cucumber/messages/version.properties: -------------------------------------------------------------------------------- 1 | messages.version=${project.version} 2 | -------------------------------------------------------------------------------- /java/src/test/java/io/cucumber/messages/ProtocolVersionTest.java: -------------------------------------------------------------------------------- 1 | package io.cucumber.messages; 2 | 3 | import org.hamcrest.Matchers; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.hamcrest.MatcherAssert.assertThat; 7 | 8 | class ProtocolVersionTest { 9 | 10 | @Test 11 | void should_have_a_resource_bundle_version() { 12 | String version = ProtocolVersion.getVersion(); 13 | assertThat(version, Matchers.matchesPattern("\\d+\\.\\d+\\.\\d+(-SNAPSHOT)?")); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /javascript/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | .idea/ 3 | .nyc_output/ 4 | coverage/ 5 | node_modules/ 6 | yarn.lock 7 | *.log 8 | .deps 9 | .tested* 10 | .linted 11 | .built* 12 | .compared 13 | .codegen 14 | acceptance/ 15 | storybook-static 16 | *-go 17 | *.iml 18 | .vscode-test 19 | -------------------------------------------------------------------------------- /javascript/.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "loader": "ts-node/esm", 3 | "extension": ["ts", "tsx"], 4 | "recursive": true, 5 | "timeout": 10000 6 | } 7 | -------------------------------------------------------------------------------- /javascript/Makefile: -------------------------------------------------------------------------------- 1 | schemas = $(shell find ../jsonschema -name "*.json") 2 | 3 | .DEFAULT_GOAL = help 4 | 5 | help: ## Show this help 6 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \n\nWhere is one of:\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 7 | 8 | generate: require src/messages.ts ## Generate typescript code based on the schemas found in ../jsonschema and using the scripts in ../jsonschema/scripts for the generation 9 | 10 | require: ## Check requirements for the code generation (ruby is required) 11 | @ruby --version >/dev/null 2>&1 || (echo "ERROR: ruby is required."; exit 1) 12 | 13 | clean: ## Remove automatically generated files and related artifacts 14 | rm -f src/messages.ts 15 | 16 | src/messages.ts: $(schemas) ../codegen/codegen.rb ../codegen/templates/typescript.ts.erb ../codegen/templates/typescript.enum.ts.erb 17 | ruby ../codegen/codegen.rb Generator::TypeScript typescript.ts.erb > $@ 18 | ruby ../codegen/codegen.rb Generator::TypeScript typescript.enum.ts.erb >> $@ 19 | -------------------------------------------------------------------------------- /javascript/README.md: -------------------------------------------------------------------------------- 1 | # Cucumber Messages for JavaScript (JSON schema) 2 | 3 | -------------------------------------------------------------------------------- /javascript/package.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@cucumber/messages", 3 | "type": "commonjs" 4 | } 5 | -------------------------------------------------------------------------------- /javascript/schema/.gitignore: -------------------------------------------------------------------------------- 1 | *.json -------------------------------------------------------------------------------- /javascript/schema/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/messages/f196c49ebc6a7299bf75304e1c8fce90d8453b9b/javascript/schema/.gitkeep -------------------------------------------------------------------------------- /javascript/schema/.npmignore: -------------------------------------------------------------------------------- 1 | .gitkeep 2 | .gitignore 3 | !*.json 4 | -------------------------------------------------------------------------------- /javascript/src/IdGenerator.ts: -------------------------------------------------------------------------------- 1 | import { v4 as uuidv4 } from 'uuid' 2 | 3 | export type NewId = () => string 4 | 5 | export function uuid(): NewId { 6 | return () => uuidv4() 7 | } 8 | 9 | export function incrementing(): NewId { 10 | let next = 0 11 | return () => (next++).toString() 12 | } 13 | -------------------------------------------------------------------------------- /javascript/src/getWorstTestStepResult.ts: -------------------------------------------------------------------------------- 1 | import { TestStepResult, TestStepResultStatus } from './messages.js' 2 | import { millisecondsToDuration } from './TimeConversion.js' 3 | 4 | /** 5 | * Gets the worst result 6 | * @param testStepResults 7 | */ 8 | export function getWorstTestStepResult(testStepResults: readonly TestStepResult[]): TestStepResult { 9 | return ( 10 | testStepResults.slice().sort((r1, r2) => ordinal(r2.status) - ordinal(r1.status))[0] || { 11 | status: TestStepResultStatus.UNKNOWN, 12 | duration: millisecondsToDuration(0), 13 | } 14 | ) 15 | } 16 | 17 | function ordinal(status: TestStepResultStatus) { 18 | return [ 19 | TestStepResultStatus.UNKNOWN, 20 | TestStepResultStatus.PASSED, 21 | TestStepResultStatus.SKIPPED, 22 | TestStepResultStatus.PENDING, 23 | TestStepResultStatus.UNDEFINED, 24 | TestStepResultStatus.AMBIGUOUS, 25 | TestStepResultStatus.FAILED, 26 | ].indexOf(status) 27 | } 28 | -------------------------------------------------------------------------------- /javascript/src/index.ts: -------------------------------------------------------------------------------- 1 | import * as TimeConversion from './TimeConversion.js' 2 | import * as IdGenerator from './IdGenerator.js' 3 | import { parseEnvelope } from './parseEnvelope.js' 4 | import { getWorstTestStepResult } from './getWorstTestStepResult.js' 5 | import { version } from './version.js' 6 | 7 | export * from './messages.js' 8 | 9 | export { TimeConversion, IdGenerator, version, parseEnvelope, getWorstTestStepResult } 10 | -------------------------------------------------------------------------------- /javascript/src/parseEnvelope.ts: -------------------------------------------------------------------------------- 1 | import { Envelope } from './messages.js' 2 | import { plainToClass } from 'class-transformer' 3 | 4 | /** 5 | * Parses JSON into an Envelope object. The difference from JSON.parse 6 | * is that the resulting objects will have default values (defined in the JSON Schema) 7 | * for properties that are absent from the JSON. 8 | */ 9 | export function parseEnvelope(json: string): Envelope { 10 | const plain = JSON.parse(json) 11 | return plainToClass(Envelope, plain) 12 | } 13 | -------------------------------------------------------------------------------- /javascript/src/version.ts: -------------------------------------------------------------------------------- 1 | // This file is automatically generated using npm scripts 2 | export const version = '27.2.0' 3 | -------------------------------------------------------------------------------- /javascript/test/getWorstTestStepResultsTest.ts: -------------------------------------------------------------------------------- 1 | import { getWorstTestStepResult } from '../src/getWorstTestStepResult.js' 2 | import { TestStepResultStatus } from '../src/messages.js' 3 | import assert from 'assert' 4 | 5 | describe('getWorstTestStepResult', () => { 6 | it('returns a FAILED result for PASSED,FAILED,PASSED', () => { 7 | const result = getWorstTestStepResult([ 8 | { 9 | status: TestStepResultStatus.PASSED, 10 | duration: { seconds: 0, nanos: 0 }, 11 | }, 12 | { 13 | status: TestStepResultStatus.FAILED, 14 | duration: { seconds: 0, nanos: 0 }, 15 | }, 16 | { 17 | status: TestStepResultStatus.PASSED, 18 | duration: { seconds: 0, nanos: 0 }, 19 | }, 20 | ]) 21 | assert.strictEqual(result.status, TestStepResultStatus.FAILED) 22 | }) 23 | }) 24 | -------------------------------------------------------------------------------- /javascript/tsconfig.build-cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.build.json", 3 | "compilerOptions": { 4 | "outDir": "dist/cjs", 5 | "target": "ES5", 6 | "module": "CommonJS", 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /javascript/tsconfig.build-esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.build.json", 3 | "compilerOptions": { 4 | "lib": [ 5 | "ES2019" 6 | ], 7 | "target": "ES6", 8 | "module": "ES6", 9 | "outDir": "dist/esm" 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /javascript/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "composite": true, 5 | "declaration": true, 6 | "declarationMap": true, 7 | "sourceMap": true, 8 | "rootDir": ".", 9 | "noEmit": false 10 | }, 11 | "include": [ 12 | "src", 13 | "test" 14 | ], 15 | } -------------------------------------------------------------------------------- /javascript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "declaration": true, 5 | "sourceMap": true, 6 | "allowJs": false, 7 | "resolveJsonModule": true, 8 | "esModuleInterop": true, 9 | "noImplicitAny": true, 10 | "downlevelIteration": true, 11 | "skipLibCheck": true, 12 | "strictNullChecks": true, 13 | "experimentalDecorators": true, 14 | "module": "ESNext", 15 | "lib": [ 16 | "ES6" 17 | ], 18 | "target": "ES6", 19 | "moduleResolution": "node", 20 | "allowSyntheticDefaultImports": true, 21 | "noEmit": true, 22 | } 23 | } -------------------------------------------------------------------------------- /jsonschema/Duration.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "Duration.json", 4 | "additionalProperties": false, 5 | "description": "The structure is pretty close of the Timestamp one. For clarity, a second type\n of message is used.", 6 | "required": [ 7 | "seconds", 8 | "nanos" 9 | ], 10 | "properties": { 11 | "seconds": { 12 | "type": "integer" 13 | }, 14 | "nanos": { 15 | "description": "Non-negative fractions of a second at nanosecond resolution. Negative\n second values with fractions must still have non-negative nanos values\n that count forward in time. Must be from 0 to 999,999,999\n inclusive.", 16 | "type": "integer" 17 | } 18 | }, 19 | "type": "object" 20 | } 21 | -------------------------------------------------------------------------------- /jsonschema/Exception.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "Exception.json", 4 | "additionalProperties": false, 5 | "description": "A simplified representation of an exception", 6 | "required": [ 7 | "type" 8 | ], 9 | "properties": { 10 | "type": { 11 | "type": "string", 12 | "description": "The type of the exception that caused this result. E.g. \"Error\" or \"org.opentest4j.AssertionFailedError\"" 13 | }, 14 | "message": { 15 | "type": "string", 16 | "description": "The message of exception that caused this result. E.g. expected: \"a\" but was: \"b\"" 17 | }, 18 | "stackTrace": { 19 | "type": "string", 20 | "description": "The stringified stack trace of the exception that caused this result" 21 | } 22 | }, 23 | "type": "object" 24 | } 25 | -------------------------------------------------------------------------------- /jsonschema/Hook.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "Hook.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "id", 7 | "sourceReference" 8 | ], 9 | "properties": { 10 | "id": { 11 | "type": "string" 12 | }, 13 | "name": { 14 | "type": "string" 15 | }, 16 | "sourceReference": { 17 | "$ref": "./SourceReference.json" 18 | }, 19 | "tagExpression": { 20 | "type": "string" 21 | }, 22 | "type": { 23 | "type": "string", 24 | "enum": [ 25 | "BEFORE_TEST_RUN", 26 | "AFTER_TEST_RUN", 27 | "BEFORE_TEST_CASE", 28 | "AFTER_TEST_CASE", 29 | "BEFORE_TEST_STEP", 30 | "AFTER_TEST_STEP" 31 | ] 32 | } 33 | }, 34 | "type": "object" 35 | } 36 | -------------------------------------------------------------------------------- /jsonschema/Location.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "Location.json", 4 | "additionalProperties": false, 5 | "description": "*\n Points to a line and a column in a text file", 6 | "properties": { 7 | "line": { 8 | "type": "integer" 9 | }, 10 | "column": { 11 | "type": "integer" 12 | } 13 | }, 14 | "required": [ 15 | "line" 16 | ], 17 | "type": "object" 18 | } 19 | -------------------------------------------------------------------------------- /jsonschema/ParameterType.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "ParameterType.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "id", 7 | "name", 8 | "preferForRegularExpressionMatch", 9 | "regularExpressions", 10 | "useForSnippets" 11 | ], 12 | "properties": { 13 | "name": { 14 | "description": "The name is unique, so we don't need an id.", 15 | "type": "string" 16 | }, 17 | "regularExpressions": { 18 | "items": { 19 | "type": "string" 20 | }, 21 | "type": "array", 22 | "minItems": 1 23 | }, 24 | "preferForRegularExpressionMatch": { 25 | "type": "boolean" 26 | }, 27 | "useForSnippets": { 28 | "type": "boolean" 29 | }, 30 | "id": { 31 | "type": "string" 32 | }, 33 | "sourceReference": { 34 | "$ref": "./SourceReference.json" 35 | } 36 | }, 37 | "type": "object" 38 | } 39 | -------------------------------------------------------------------------------- /jsonschema/ParseError.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "ParseError.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "source", 7 | "message" 8 | ], 9 | "properties": { 10 | "source": { 11 | "$ref": "./SourceReference.json" 12 | }, 13 | "message": { 14 | "type": "string" 15 | } 16 | }, 17 | "type": "object" 18 | } 19 | -------------------------------------------------------------------------------- /jsonschema/Source.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "Source.json", 4 | "additionalProperties": false, 5 | "description": "//// Source\n\n*\n A source file, typically a Gherkin document or Java/Ruby/JavaScript source code", 6 | "required": [ 7 | "uri", 8 | "data", 9 | "mediaType" 10 | ], 11 | "properties": { 12 | "uri": { 13 | "description": "*\n The [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier)\n of the source, typically a file path relative to the root directory", 14 | "type": "string" 15 | }, 16 | "data": { 17 | "description": "The contents of the file", 18 | "type": "string" 19 | }, 20 | "mediaType": { 21 | "description": "The media type of the file. Can be used to specify custom types, such as\n text/x.cucumber.gherkin+plain", 22 | "type": "string", 23 | "enum": [ 24 | "text/x.cucumber.gherkin+plain", 25 | "text/x.cucumber.gherkin+markdown" 26 | ] 27 | } 28 | }, 29 | "type": "object" 30 | } 31 | -------------------------------------------------------------------------------- /jsonschema/StepDefinition.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "StepDefinition.json", 4 | "additionalProperties": false, 5 | "definitions": { 6 | "StepDefinitionPattern": { 7 | "additionalProperties": false, 8 | "required": [ 9 | "source", 10 | "type" 11 | ], 12 | "properties": { 13 | "source": { 14 | "type": "string" 15 | }, 16 | "type": { 17 | "enum": [ 18 | "CUCUMBER_EXPRESSION", 19 | "REGULAR_EXPRESSION" 20 | ], 21 | "type": "string" 22 | } 23 | }, 24 | "type": "object" 25 | } 26 | }, 27 | "required": [ 28 | "id", 29 | "pattern", 30 | "sourceReference" 31 | ], 32 | "properties": { 33 | "id": { 34 | "type": "string" 35 | }, 36 | "pattern": { 37 | "$ref": "#/definitions/StepDefinitionPattern" 38 | }, 39 | "sourceReference": { 40 | "$ref": "./SourceReference.json" 41 | } 42 | }, 43 | "type": "object" 44 | } 45 | -------------------------------------------------------------------------------- /jsonschema/TestCaseFinished.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "TestCaseFinished.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "testCaseStartedId", 7 | "timestamp", 8 | "willBeRetried" 9 | ], 10 | "properties": { 11 | "testCaseStartedId": { 12 | "type": "string" 13 | }, 14 | "timestamp": { 15 | "$ref": "./Timestamp.json" 16 | }, 17 | "willBeRetried": { 18 | "type": "boolean" 19 | } 20 | }, 21 | "type": "object" 22 | } 23 | -------------------------------------------------------------------------------- /jsonschema/TestRunFinished.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "TestRunFinished.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "success", 7 | "timestamp" 8 | ], 9 | "properties": { 10 | "message": { 11 | "description": "An informative message about the test run. Typically additional information about failure, but not necessarily.", 12 | "type": "string" 13 | }, 14 | "success": { 15 | "description": "A test run is successful if all steps are either passed or skipped, all before/after hooks passed and no other exceptions where thrown.", 16 | "type": "boolean" 17 | }, 18 | "timestamp": { 19 | "$ref": "./Timestamp.json", 20 | "description": "Timestamp when the TestRun is finished" 21 | }, 22 | "exception": { 23 | "$ref": "./Exception.json", 24 | "description": "Any exception thrown during the test run, if any. Does not include exceptions thrown while executing steps." 25 | }, 26 | "testRunStartedId": { 27 | "type": "string" 28 | } 29 | }, 30 | "type": "object" 31 | } 32 | -------------------------------------------------------------------------------- /jsonschema/TestRunHookFinished.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "TestRunHookFinished.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "testRunHookStartedId", 7 | "result", 8 | "timestamp" 9 | ], 10 | "properties": { 11 | "testRunHookStartedId": { 12 | "description": "Identifier for the hook execution that has finished", 13 | "type": "string" 14 | }, 15 | "result": { 16 | "$ref": "./TestStepResult.json" 17 | }, 18 | "timestamp": { 19 | "$ref": "./Timestamp.json" 20 | } 21 | }, 22 | "type": "object" 23 | } -------------------------------------------------------------------------------- /jsonschema/TestRunHookStarted.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "TestRunHookStarted.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "id", 7 | "testRunStartedId", 8 | "hookId", 9 | "timestamp" 10 | ], 11 | "properties": { 12 | "id": { 13 | "description": "Unique identifier for this hook execution", 14 | "type": "string" 15 | }, 16 | "testRunStartedId": { 17 | "description": "Identifier for the test run that this hook execution belongs to", 18 | "type": "string" 19 | }, 20 | "hookId": { 21 | "description": "Identifier for the hook that will be executed", 22 | "type": "string" 23 | }, 24 | "timestamp": { 25 | "$ref": "./Timestamp.json" 26 | } 27 | }, 28 | "type": "object" 29 | } -------------------------------------------------------------------------------- /jsonschema/TestRunStarted.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "TestRunStarted.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "timestamp" 7 | ], 8 | "properties": { 9 | "timestamp": { 10 | "$ref": "./Timestamp.json" 11 | }, 12 | "id": { 13 | "type": "string" 14 | } 15 | }, 16 | "type": "object" 17 | } 18 | -------------------------------------------------------------------------------- /jsonschema/TestStepFinished.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "TestStepFinished.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "testCaseStartedId", 7 | "testStepId", 8 | "testStepResult", 9 | "timestamp" 10 | ], 11 | "properties": { 12 | "testCaseStartedId": { 13 | "type": "string" 14 | }, 15 | "testStepId": { 16 | "type": "string" 17 | }, 18 | "testStepResult": { 19 | "$ref": "./TestStepResult.json" 20 | }, 21 | "timestamp": { 22 | "$ref": "./Timestamp.json" 23 | } 24 | }, 25 | "type": "object" 26 | } 27 | -------------------------------------------------------------------------------- /jsonschema/TestStepResult.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "TestStepResult.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "duration", 7 | "status" 8 | ], 9 | "properties": { 10 | "duration": { 11 | "$ref": "./Duration.json" 12 | }, 13 | "message": { 14 | "type": "string", 15 | "description": "An arbitrary bit of information that explains this result. This can be a stack trace of anything else." 16 | }, 17 | "status": { 18 | "enum": [ 19 | "UNKNOWN", 20 | "PASSED", 21 | "SKIPPED", 22 | "PENDING", 23 | "UNDEFINED", 24 | "AMBIGUOUS", 25 | "FAILED" 26 | ], 27 | "type": "string" 28 | }, 29 | "exception": { 30 | "$ref": "./Exception.json", 31 | "description": "Exception thrown while executing this step, if any." 32 | } 33 | }, 34 | "type": "object" 35 | } -------------------------------------------------------------------------------- /jsonschema/TestStepStarted.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "TestStepStarted.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "testCaseStartedId", 7 | "testStepId", 8 | "timestamp" 9 | ], 10 | "properties": { 11 | "testCaseStartedId": { 12 | "type": "string" 13 | }, 14 | "testStepId": { 15 | "type": "string" 16 | }, 17 | "timestamp": { 18 | "$ref": "./Timestamp.json" 19 | } 20 | }, 21 | "type": "object" 22 | } 23 | -------------------------------------------------------------------------------- /jsonschema/Timestamp.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "Timestamp.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "seconds", 7 | "nanos" 8 | ], 9 | "properties": { 10 | "seconds": { 11 | "description": "Represents seconds of UTC time since Unix epoch\n 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to\n 9999-12-31T23:59:59Z inclusive.", 12 | "type": "integer" 13 | }, 14 | "nanos": { 15 | "description": "Non-negative fractions of a second at nanosecond resolution. Negative\n second values with fractions must still have non-negative nanos values\n that count forward in time. Must be from 0 to 999,999,999\n inclusive.", 16 | "type": "integer" 17 | } 18 | }, 19 | "type": "object" 20 | } 21 | -------------------------------------------------------------------------------- /jsonschema/UndefinedParameterType.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "UndefinedParameterType.json", 4 | "additionalProperties": false, 5 | "required": [ 6 | "expression", 7 | "name" 8 | ], 9 | "properties": { 10 | "expression": { 11 | "type": "string" 12 | }, 13 | "name": { 14 | "type": "string" 15 | } 16 | }, 17 | "type": "object" 18 | } 19 | -------------------------------------------------------------------------------- /messages.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/messages/f196c49ebc6a7299bf75304e1c8fce90d8453b9b/messages.monopic -------------------------------------------------------------------------------- /messages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/messages/f196c49ebc6a7299bf75304e1c8fce90d8453b9b/messages.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@cucumber/messages-validation-kit", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "Allow to validate the schemas", 6 | "devDependencies": { 7 | "ajv": "8.17.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /perl/.gitignore: -------------------------------------------------------------------------------- 1 | .build/ 2 | .built 3 | acceptance/ 4 | Cucumber-Messages-* 5 | perl5/ 6 | .cpanfile_dependencies 7 | cpanfile.snapshot 8 | CHANGELOG.md 9 | -------------------------------------------------------------------------------- /perl/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cucumber Ltd and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /perl/Makefile: -------------------------------------------------------------------------------- 1 | schemas = $(shell find ../jsonschema -name "*.json") 2 | 3 | .DEFAULT_GOAL = help 4 | 5 | help: ## Show this help 6 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \n\nWhere is one of:\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 7 | 8 | generate: require lib/Cucumber/Messages.pm ## Generate perl code based on the schemas found in ../jsonschema and using the scripts in ../jsonschema/scripts for the generation 9 | 10 | require: ## Check requirements for the code generation (ruby is required) 11 | @ruby --version >/dev/null 2>&1 || (echo "ERROR: ruby is required."; exit 1) 12 | 13 | clean: ## Remove automatically generated files and related artifacts 14 | rm -f lib/Cucumber/Messages.pm 15 | 16 | lib/Cucumber/Messages.pm: $(schemas) ../codegen/codegen.rb ../codegen/templates/perl.pm.erb 17 | ruby ../codegen/codegen.rb Generator::Perl perl.pm.erb > $@ 18 | -------------------------------------------------------------------------------- /perl/README.md: -------------------------------------------------------------------------------- 1 | # Cucumber Messages for Perl (JSON schema) 2 | 3 | -------------------------------------------------------------------------------- /perl/VERSION: -------------------------------------------------------------------------------- 1 | 27.2.0 2 | -------------------------------------------------------------------------------- /perl/cpanfile: -------------------------------------------------------------------------------- 1 | 2 | requires "perl", "5.14.4"; 3 | 4 | requires "JSON::MaybeXS"; 5 | requires "Moo"; 6 | 7 | 8 | on 'test' => sub { 9 | requires "File::Find::Rule"; 10 | requires "Test2::Tools::ClassicCompare"; 11 | requires "Test2::V0"; 12 | 13 | }; 14 | 15 | 16 | on 'develop' => sub { 17 | # There are no specific development dependencies 18 | } -------------------------------------------------------------------------------- /perl/t/01-load.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | 3 | use Test2::V0; 4 | 5 | use Cucumber::Messages::Message; 6 | use Cucumber::Messages; 7 | 8 | pass 'Both libraries loaded fine'; 9 | 10 | done_testing; 11 | -------------------------------------------------------------------------------- /perl/t/02-instantiation.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | 3 | use Test2::V0; 4 | no strict 'refs'; 5 | 6 | use Cucumber::Messages; 7 | 8 | # Go over all subpackages of the Cucumber::Messages package; 9 | # each subpackage should also be a Moo class, which we can instantiate. 10 | # Verify that each class can be instantiated without supplying arguments 11 | # (all required parameters have a default value; this tests the execution 12 | # of the subs that provide the default values) 13 | for my $pkg ( grep { m/::$/ } keys %{ "Cucumber::Messages::" }) { 14 | my $class = ($pkg =~ s/::$//r); 15 | 16 | ok lives { "Cucumber::Messages::$class"->new() } 17 | or diag $@; 18 | } 19 | 20 | 21 | done_testing; 22 | -------------------------------------------------------------------------------- /perl/t/compatibility-kit/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /perl/t/compatibility-kit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cucumber-compatibility-kit-for-perl-tests", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@cucumber/compatibility-kit": "^18.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /php/.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock 3 | .phpunit.cache 4 | .php-cs-fixer.cache 5 | .codegen 6 | .deps 7 | .tested 8 | 9 | build -------------------------------------------------------------------------------- /php/.php-cs-fixer.php: -------------------------------------------------------------------------------- 1 | in([ 4 | __DIR__ . '/src', 5 | __DIR__ . '/src-generated', 6 | __DIR__ . '/tests', 7 | ]) 8 | ; 9 | 10 | $config = new PhpCsFixer\Config(); 11 | return $config->setFinder($finder); 12 | -------------------------------------------------------------------------------- /php/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cucumber Ltd and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /php/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cucumber/messages", 3 | "description": "JSON schema-based messages for Cucumber's inter-process communication", 4 | "author": "Cucumber Limited ", 5 | "license": "MIT", 6 | "type": "library", 7 | "require": { 8 | "php": "^8.1", 9 | "ext-json": "*" 10 | }, 11 | "require-dev": { 12 | "vimeo/psalm": "^5.5", 13 | "phpunit/phpunit": "^10.3||^11.0", 14 | "psalm/plugin-phpunit": "^0.19.0", 15 | "friendsofphp/php-cs-fixer": "^3.5", 16 | "ramsey/uuid": "^4.5.0" 17 | }, 18 | "autoload": { 19 | "psr-4": { 20 | "Cucumber\\Messages\\": [ 21 | "src", 22 | "src-generated" 23 | ] 24 | } 25 | }, 26 | "autoload-dev": { 27 | "psr-4": { 28 | "Cucumber\\Messages\\": [ 29 | "src", 30 | "src-generated", 31 | "tests" 32 | ] 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /php/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | tests 13 | 14 | 15 | 16 | 17 | 18 | src 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /php/psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /php/src-generated/Attachment/ContentEncoding.php: -------------------------------------------------------------------------------- 1 | next++; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /php/src/Streams/NdJson/NdJsonStreamReader.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | public function envelopes(): Generator 20 | { 21 | while (!feof($this->fileHandle) && ($line = fgets($this->fileHandle))) { 22 | yield Envelope::fromJson($line); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /php/src/Streams/NdJson/NdJsonStreamWriter.php: -------------------------------------------------------------------------------- 1 | $envelopes 17 | */ 18 | public function writeEnvelopes(iterable $envelopes): void 19 | { 20 | foreach ($envelopes as $envelope) { 21 | fputs($this->fileHandle, $envelope->asJson() . "\n"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /php/src/Streams/StreamReader.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function envelopes(): iterable; 15 | } 16 | -------------------------------------------------------------------------------- /php/src/Streams/StreamWriter.php: -------------------------------------------------------------------------------- 1 | $envelopes 13 | */ 14 | public function writeEnvelopes(iterable $envelopes): void; 15 | } 16 | -------------------------------------------------------------------------------- /php/src/Streams/WithFileHandleTrait.php: -------------------------------------------------------------------------------- 1 | gherkinDocument); 16 | } 17 | 18 | public function testItCanBeConstructedWithASubsetOfProperties(): void 19 | { 20 | $envelope = new Envelope( 21 | gherkinDocument: new GherkinDocument( 22 | feature: new Feature( 23 | location: new Location( 24 | line: 21 25 | ) 26 | ) 27 | ) 28 | ); 29 | 30 | self::assertSame( 31 | 21, 32 | $envelope->gherkinDocument?->feature?->location?->line 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /php/tests/Id/IdGeneratorTestTrait.php: -------------------------------------------------------------------------------- 1 | idGenerator->newId()); 12 | } 13 | 14 | public function testItDoesNotRepeatIds(): void 15 | { 16 | $id1 = $this->idGenerator->newId(); 17 | $id2 = $this->idGenerator->newId(); 18 | 19 | self::assertNotEquals($id1, $id2); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /php/tests/Id/IncrementingIdGeneratorTest.php: -------------------------------------------------------------------------------- 1 | idGenerator = new IncrementingIdGenerator(); 16 | } 17 | 18 | public function testItIncrementsFromZero(): void 19 | { 20 | self::assertSame('0', $this->idGenerator->newId()); 21 | self::assertSame('1', $this->idGenerator->newId()); 22 | self::assertSame('2', $this->idGenerator->newId()); 23 | self::assertSame('3', $this->idGenerator->newId()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /php/tests/Id/UuidIdGeneratorTest.php: -------------------------------------------------------------------------------- 1 | idGenerator = new UuidIdGenerator(); 18 | } 19 | 20 | public function testItGeneratesUuids(): void 21 | { 22 | $uuid = $this->idGenerator->newId(); 23 | 24 | self::assertTrue(Uuid::isValid($uuid)); 25 | } 26 | 27 | public function testItGeneratesV4Uuids(): void 28 | { 29 | $uuid = $this->idGenerator->newId(); 30 | 31 | $fields = (Uuid::fromString($uuid))->getFields(); 32 | 33 | self::assertInstanceOf(FieldsInterface::class, $fields); 34 | self::assertSame(4, $fields->getVersion()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /python/.gitignore: -------------------------------------------------------------------------------- 1 | *.rej 2 | *.py[cod] 3 | /.env 4 | *.orig 5 | **/__pycache__ 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Packages 11 | *.egg 12 | *.egg-info 13 | dist 14 | build 15 | _build 16 | eggs 17 | parts 18 | bin 19 | var 20 | sdist 21 | develop-eggs 22 | .installed.cfg 23 | lib 24 | lib64 25 | 26 | # Installer logs 27 | pip-log.txt 28 | 29 | # Unit test / coverage reports 30 | .coverage 31 | .tox 32 | nosetests.xml 33 | 34 | # Translations 35 | *.mo 36 | 37 | # Mr Developer 38 | .mr.developer.cfg 39 | .project 40 | .pydevproject 41 | .pytest_cache 42 | .ropeproject 43 | 44 | # Sublime 45 | /*.sublime-* 46 | 47 | #PyCharm 48 | /.idea 49 | 50 | # virtualenv 51 | /.Python 52 | /lib 53 | /include 54 | /share 55 | /local 56 | -------------------------------------------------------------------------------- /python/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cucumber Ltd and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | # Messages 2 | 3 | Cucumber Messages for Python https://github.com/cucumber/messages 4 | -------------------------------------------------------------------------------- /python/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | testpaths = tests 3 | -------------------------------------------------------------------------------- /python/src/cucumber_messages/__init__.py: -------------------------------------------------------------------------------- 1 | from . import _messages, json_converter 2 | from ._messages import * 3 | 4 | message_converter: json_converter.JsonDataclassConverter = json_converter.JsonDataclassConverter(module_scope=_messages) 5 | -------------------------------------------------------------------------------- /python/tests/conftest.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/messages/f196c49ebc6a7299bf75304e1c8fce90d8453b9b/python/tests/conftest.py -------------------------------------------------------------------------------- /ruby/.gitignore: -------------------------------------------------------------------------------- 1 | Gemfile.lock 2 | coverage/ 3 | acceptance/ 4 | pkg/ 5 | *.gem 6 | .compared 7 | *.iml 8 | -------------------------------------------------------------------------------- /ruby/.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | --color 3 | -------------------------------------------------------------------------------- /ruby/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | gemspec 6 | -------------------------------------------------------------------------------- /ruby/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cucumber Ltd and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ruby/README.md: -------------------------------------------------------------------------------- 1 | # Cucumber Messages for Ruby (JSON schema) 2 | 3 | See main [README](../README.md) 4 | -------------------------------------------------------------------------------- /ruby/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rubygems' 4 | require 'bundler' 5 | Bundler::GemHelper.install_tasks 6 | 7 | $LOAD_PATH.unshift File.expand_path('lib', __dir__) 8 | 9 | Dir['./rake/*.rb'].each do |f| 10 | require f 11 | end 12 | 13 | require 'rspec/core/rake_task' 14 | RSpec::Core::RakeTask.new(:spec) 15 | 16 | task default: :spec 17 | -------------------------------------------------------------------------------- /ruby/VERSION: -------------------------------------------------------------------------------- 1 | 27.2.0 2 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cucumber/messages/helpers/ndjson_to_message_enumerator' 4 | require 'cucumber/messages/helpers/time_conversion' 5 | require 'cucumber/messages/helpers/id_generator' 6 | require 'cucumber/messages/message' 7 | 8 | Dir["#{File.dirname(__FILE__)}/messages/*.rb"].each { |file| require file } 9 | 10 | module Cucumber 11 | module Messages 12 | VERSION = File.read(File.expand_path('../../VERSION', __dir__)).strip 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/attachment_content_encoding.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 4 | module Cucumber 5 | module Messages 6 | class AttachmentContentEncoding 7 | IDENTITY = 'IDENTITY' 8 | BASE64 = 'BASE64' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/helpers/id_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'id_generator/uuid' 4 | require_relative 'id_generator/incrementing' 5 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/helpers/id_generator/incrementing.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Cucumber 4 | module Messages 5 | module Helpers 6 | module IdGenerator 7 | class Incrementing 8 | def initialize 9 | @index = -1 10 | end 11 | 12 | def new_id 13 | @index += 1 14 | @index.to_s 15 | end 16 | end 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/helpers/id_generator/uuid.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'securerandom' 4 | 5 | module Cucumber 6 | module Messages 7 | module Helpers 8 | module IdGenerator 9 | class UUID 10 | def new_id 11 | SecureRandom.uuid 12 | end 13 | end 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/helpers/ndjson_to_message_enumerator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cucumber/messages' 4 | 5 | module Cucumber 6 | module Messages 7 | module Helpers 8 | class NdjsonToMessageEnumerator < Enumerator 9 | def initialize(io) 10 | super() do |yielder| 11 | io.each_line do |line| 12 | next if line.strip.empty? 13 | 14 | message = extract_message(line) 15 | yielder.yield(message) 16 | end 17 | end 18 | end 19 | 20 | private 21 | 22 | def extract_message(json_line) 23 | Envelope.from_json(json_line) 24 | rescue StandardError 25 | raise "Not JSON: #{json_line.strip}" 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/helpers/time_conversion.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Cucumber 4 | module Messages 5 | module Helpers 6 | module TimeConversion 7 | NANOSECONDS_PER_SECOND = 1_000_000_000 8 | 9 | def time_to_timestamp(time) 10 | { 'seconds' => time.to_i, 'nanos' => time.nsec } 11 | end 12 | 13 | def timestamp_to_time(timestamp) 14 | Time.at(timestamp['seconds'] + (timestamp['nanos'].to_f / NANOSECONDS_PER_SECOND)) 15 | end 16 | 17 | def seconds_to_duration(seconds_float) 18 | seconds, second_modulus = seconds_float.divmod(1) 19 | nanos = second_modulus * NANOSECONDS_PER_SECOND 20 | { 'seconds' => seconds, 'nanos' => nanos.to_i } 21 | end 22 | 23 | def duration_to_seconds(duration) 24 | seconds_part = duration['seconds'] 25 | nanos_part = duration['nanos'].to_f / NANOSECONDS_PER_SECOND 26 | seconds_part + nanos_part 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/hook_type.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 4 | module Cucumber 5 | module Messages 6 | class HookType 7 | BEFORE_TEST_RUN = 'BEFORE_TEST_RUN' 8 | AFTER_TEST_RUN = 'AFTER_TEST_RUN' 9 | BEFORE_TEST_CASE = 'BEFORE_TEST_CASE' 10 | AFTER_TEST_CASE = 'AFTER_TEST_CASE' 11 | BEFORE_TEST_STEP = 'BEFORE_TEST_STEP' 12 | AFTER_TEST_STEP = 'AFTER_TEST_STEP' 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/pickle_step_type.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 4 | module Cucumber 5 | module Messages 6 | class PickleStepType 7 | UNKNOWN = 'Unknown' 8 | CONTEXT = 'Context' 9 | ACTION = 'Action' 10 | OUTCOME = 'Outcome' 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/pickle_table.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 4 | module Cucumber 5 | module Messages 6 | ## 7 | # Represents the PickleTable message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. 8 | ## 9 | ## 10 | class PickleTable < Message 11 | attr_reader :rows 12 | 13 | def initialize( 14 | rows: [] 15 | ) 16 | @rows = rows 17 | super() 18 | end 19 | 20 | ## 21 | # Returns a new PickleTable from the given hash. 22 | # If the hash keys are camelCased, they are properly assigned to the 23 | # corresponding snake_cased attributes. 24 | # 25 | # Cucumber::Messages::PickleTable.from_h(some_hash) # => # 26 | ## 27 | def self.from_h(hash) 28 | return nil if hash.nil? 29 | 30 | new( 31 | rows: hash[:rows]&.map { |item| PickleTableRow.from_h(item) } 32 | ) 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/pickle_table_cell.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 4 | module Cucumber 5 | module Messages 6 | ## 7 | # Represents the PickleTableCell message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. 8 | ## 9 | ## 10 | class PickleTableCell < Message 11 | attr_reader :value 12 | 13 | def initialize( 14 | value: '' 15 | ) 16 | @value = value 17 | super() 18 | end 19 | 20 | ## 21 | # Returns a new PickleTableCell from the given hash. 22 | # If the hash keys are camelCased, they are properly assigned to the 23 | # corresponding snake_cased attributes. 24 | # 25 | # Cucumber::Messages::PickleTableCell.from_h(some_hash) # => # 26 | ## 27 | def self.from_h(hash) 28 | return nil if hash.nil? 29 | 30 | new( 31 | value: hash[:value] 32 | ) 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/source_media_type.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 4 | module Cucumber 5 | module Messages 6 | class SourceMediaType 7 | TEXT_X_CUCUMBER_GHERKIN_PLAIN = 'text/x.cucumber.gherkin+plain' 8 | TEXT_X_CUCUMBER_GHERKIN_MARKDOWN = 'text/x.cucumber.gherkin+markdown' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/step_definition_pattern_type.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 4 | module Cucumber 5 | module Messages 6 | class StepDefinitionPatternType 7 | CUCUMBER_EXPRESSION = 'CUCUMBER_EXPRESSION' 8 | REGULAR_EXPRESSION = 'REGULAR_EXPRESSION' 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/step_keyword_type.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 4 | module Cucumber 5 | module Messages 6 | class StepKeywordType 7 | UNKNOWN = 'Unknown' 8 | CONTEXT = 'Context' 9 | ACTION = 'Action' 10 | OUTCOME = 'Outcome' 11 | CONJUNCTION = 'Conjunction' 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /ruby/lib/cucumber/messages/test_step_result_status.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/codegen/codegen.rb] 4 | module Cucumber 5 | module Messages 6 | class TestStepResultStatus 7 | UNKNOWN = 'UNKNOWN' 8 | PASSED = 'PASSED' 9 | SKIPPED = 'SKIPPED' 10 | PENDING = 'PENDING' 11 | UNDEFINED = 'UNDEFINED' 12 | AMBIGUOUS = 'AMBIGUOUS' 13 | FAILED = 'FAILED' 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /ruby/spec/cucumber/messages/acceptance_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'json' 4 | require 'cucumber-compatibility-kit' 5 | 6 | module Cucumber 7 | module Messages 8 | describe 'messages acceptance tests' do 9 | CCK::Examples.gherkin.each do |example_name| 10 | context "with the '#{example_name}' example" do 11 | let(:ndjson_filepath) { "#{CCK::Examples.feature_code_for(example_name)}/#{example_name}.feature.ndjson" } 12 | 13 | it 'has a ndjson reference filepath' do 14 | expect(File).to exist(ndjson_filepath) 15 | end 16 | 17 | it 'deserializes and serializes messages in the ndjson file' do 18 | File.open(ndjson_filepath, 'r:utf-8') do |file| 19 | file.each_line do |message| 20 | # Check that the Envelope re-generated message equals the originally parsed message 21 | expect(JSON.parse(Envelope.from_json(message).to_json)).to eq(JSON.parse(message)) 22 | end 23 | end 24 | end 25 | end 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /ruby/spec/cucumber/messages/helpers/id_generator/incrementing_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe Cucumber::Messages::Helpers::IdGenerator::Incrementing do 4 | subject(:generator) { described_class.new } 5 | 6 | describe '#new_id' do 7 | it 'returns 0 the first time' do 8 | expect(generator.new_id).to eq('0') 9 | end 10 | 11 | it 'increments on every call' do 12 | rand(2..5).times do |value| 13 | expect(generator.new_id).to eq(value.to_s) 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /ruby/spec/cucumber/messages/helpers/id_generator/uuid_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | describe Cucumber::Messages::Helpers::IdGenerator::UUID do 4 | subject(:generator) { described_class.new } 5 | 6 | describe '#new_id' do 7 | it 'generates a new UUID' do 8 | expect(SecureRandom).to receive(:uuid) 9 | 10 | generator.new_id 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /ruby/spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rspec' 4 | 5 | require 'cucumber/messages' 6 | require 'cucumber/messages/message' 7 | 8 | require_relative 'support/comprehensive_message' 9 | require_relative 'support/enum_message' 10 | require_relative 'support/simple_message' 11 | -------------------------------------------------------------------------------- /ruby/spec/support/comprehensive_message.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'simple_message' 4 | 5 | module Cucumber 6 | module Messages 7 | class ComprehensiveMessage < Message 8 | attr_reader :simple_message, :message_array, :is_enum 9 | 10 | def initialize( 11 | simple_message: SimpleMessage.new, 12 | message_array: [SimpleMessage.new, SimpleMessage.new], 13 | is_enum: EnumMessage::ENUM 14 | ) 15 | @simple_message = simple_message 16 | @message_array = message_array 17 | @is_enum = is_enum 18 | super() 19 | end 20 | 21 | def self.message_array_from_h(hash) 22 | SimpleMessage.from_h(hash) 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /ruby/spec/support/enum_message.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Cucumber 4 | module Messages 5 | class EnumMessage 6 | ENUM = 'an enum' 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /ruby/spec/support/simple_message.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Cucumber 4 | module Messages 5 | class SimpleMessage < Message 6 | attr_reader :is_nil, :is_string, :is_array, :is_number 7 | 8 | def initialize(is_nil: nil, is_string: '', is_array: [], is_number: 0) 9 | @is_nil = is_nil 10 | @is_string = is_string 11 | @is_array = is_array 12 | @is_number = is_number 13 | super() 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /validate.cjs: -------------------------------------------------------------------------------- 1 | const Ajv = require('ajv/dist/2020') 2 | const fs = require('node:fs') 3 | 4 | const ajv = new Ajv({ strict: true }) 5 | const schemaPaths = process.argv.slice(2); 6 | for (const path of schemaPaths) { 7 | const schema = JSON.parse(fs.readFileSync(path, {encoding: 'utf-8'})); 8 | ajv.compile(schema) 9 | console.log(`${path} is a valid schema.`) 10 | } 11 | --------------------------------------------------------------------------------