Skip to content

Latest commit

 

History

History
90 lines (67 loc) · 3.73 KB

CONTRIBUTING.md

File metadata and controls

90 lines (67 loc) · 3.73 KB

Project structure

  • root: Contains tests and nothing else
    • codegen: Codegen core. Defines algebras and default interpreters.
    • sample: Contains integration tests for generated code. May be generated via example in the sbt console.

Coding guidelines

Writing integration Tests

It is difficult to tell if the code generated by the tool is functional and type sound by structure alone. As unit tests are not enough, integration tests actually run guardrail as a CLI tool to generate complete clients and servers, ensuring everything works as expected.

The project defined at modules/sample is divided into two parts:

  • src/main: Completely generated code, .gitignore explicitly prevents these files from being tracked.
  • src/test: Manually written integration tests against the generated code. These tests are run by the testSuite command.

By running guardrail, then attempting to compile the generated code, then running integration tests against the generated code, we can ensure quality.

Adding a new swagger spec

Adding new specifications is accomplished by:

  • creating a file in modules/sample/src/main/resources
  • adding an entry in runExample defined in build.sbt. The available flags are largely undocumented, so reading the parser is necessary.
lazy val runExample: TaskKey[Unit] = taskKey[Unit]("Run with example args")

fullRunTask(
  runExample,
  Test,
  "com.twilio.guardrail.CLI",
  """
  --defaults --import support.PositiveLong
  --client --specPath modules/sample/src/main/resources/petstore.json --outputPath modules/sample/src/main/scala --packageName clients.http4s --framework http4s

  --client --specPath modules/sample/src/main/resources/edgecases/defaults.yaml --outputPath modules/sample/src/main/scala --packageName edgecases.defaults
  --client --specPath modules/sample/src/main/resources/custom-header-type.yaml --outputPath modules/sample/src/main/scala --packageName tests.customTypes.customHeader
""".replaceAllLiterally("\n", " ").split(' ').filter(_.nonEmpty): _*
)
  • --specPath has to point to the newly added specification file
  • --outputPath must point to modules/sample/src/main/scala
  • --packageName a unique, semantic name for your generated files. Good names:
    • issues.issue42
    • frameworks.akka.fileUploader

Adding tests

Define your tests in ./modules/sample/src/test/scala make sure to use imports corresponding the previously defined packageName

Running the tests

Use the example command inside of an SBT session to run code generation and execute the tests

Useful commands inside sbt console

  • testSuite: Compile, test codegen, run sample codegen, compile sample, run tests inside sample
  • runtimeSuite: Run guardrail, then run all tests against the generated code
  • cli: Useful for scripting: sbt 'cli --client ...'
  • format: Runs scalafmt against codebase
  • checkFormatting: Verifies formatting, run as part of CI against PRs

Resources