Skip to content

Commit

Permalink
feat: make binary installable via go install
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikaverpil committed Nov 4, 2024
1 parent c205cb0 commit 6758d5b
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 58 deletions.
9 changes: 8 additions & 1 deletion .sage/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ func (Proto) ProtocGenGoGRPC(ctx context.Context) error {

func (Proto) ProtocGenGoAIPTest(ctx context.Context) error {
sg.Logger(ctx).Println("building binary...")
return sg.Command(ctx, "go", "build", "-o", sg.FromBinDir("protoc-gen-go-aip-test"), ".").Run()
return sg.Command(
ctx,
"go",
"build",
"-o",
sg.FromBinDir("protoc-gen-go-aip-test"),
"./cmd/protoc-gen-go-aip-test",
).Run()
}

func (Proto) BufGenerate(ctx context.Context) error {
Expand Down
79 changes: 22 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ service FreightService {

### Step 2: Install the generator

Download a prebuilt binary from [releases](./releases) and put it in your PATH.
Either install using `go install`:

```bash
go install github.com/einride/protoc-gen-go-aip-test/cmd/protoc-gen-go-aip-test@latest
```

Or download a prebuilt binary from [releases](./releases) and put it in your
PATH.

The generator can also be built from source using Go.

Expand All @@ -52,11 +59,7 @@ This can also be done via a

### Step 4: Run tests

There are two alternative ways of bootstrapping the tests.

#### Alternative 1:

Instantiate the generated test suites and call the methods you want to test.
The generated test suites must be provided with some input data.

```go
package example
Expand Down Expand Up @@ -94,42 +97,6 @@ func Test_FreightService(t *testing.T) {
}
```

#### Alternative 2:

Implement the generated configure provider interface
(`FreightServiceTestSuiteConfigProvider`) and pass the implementation to
`TestServices` to start the tests.

A benefit of using `TestServices` (over alternative 1) is that as new services
or resources are added to the API the test code won't compile until the required
inputs are also added (or explicitly ignored). This makes it harder to forget to
add the test implementations for new services/resources.

```go
package example

import "testing"

func Test_FreightService(t *testing.T) {
// Even though no implementation exists, the tests will pass but be skipped.
examplefreightv1.TestServices(t, &aipTests{})
}

type aipTests struct{}

var _ examplefreightv1.FreightServiceTestSuiteConfigProvider = &aipTests{}

func (a aipTests) FreightServiceShipper(_ *testing.T) *examplefreightv1.FreightServiceShipperTestSuiteConfig {
// Returns nil to indicate that it's not ready to be tested.
return nil
}

func (a aipTests) FreightServiceSite(_ *testing.T) *examplefreightv1.FreightServiceSiteTestSuiteConfig {
// Returns nil to indicate that it's not ready to be tested.
return nil
}
```

### Skipping tests

There may be multiple reasons for an API to deviate from the guidance for
Expand All @@ -152,19 +119,17 @@ Sample skips:

### Create

| Name | Description | Only if |
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| missing parent | Method should fail with InvalidArgument if no parent is provided. | Generated only if all are true: <ul><li>has Create method</li><li>resource has a parent</li></ul> |
| invalid parent | Method should fail with InvalidArgument if provided parent is invalid. | Generated only if all are true: <ul><li>has Create method</li><li>resource has a parent</li></ul> |
| create time | Field create_time should be populated when the resource is created. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has field 'create_time'</li></ul> |
| persisted | The created resource should be persisted and reachable with Get. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has Get method</li></ul> |
| user settable id | If method support user settable IDs, when set the resource should be returned with the provided ID. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has user settable ID</li></ul> |
| invalid user settable id | Method should fail with InvalidArgument if the user settable id doesn't conform to RFC-1034, see [doc](https://google.aip.dev/122#resource-id-segments). | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has user settable ID</li></ul> |
| invalid user settable id - uuid | Method should fail with InvalidArgument if the user settable ID appears to be a UUID, see [doc](https://google.aip.dev/122#resource-id-segments). | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has user settable ID</li></ul> |
| already exists | If method support user settable IDs and the same ID is reused the method should return AlreadyExists. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has user settable ID</li></ul> |
| required fields | The method should fail with InvalidArgument if the resource has any required fields and they are not provided. | Generated only if all are true: <ul><li>has Create method</li><li>resource has any required fields</li></ul> |
| resource references | The method should fail with InvalidArgument if the resource has any resource references and they are invalid. | Generated only if all are true: <ul><li>has Create method</li><li>resource has any mutable resource references</li></ul> |
| etag populated | Field etag should be populated when the resource is created. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has field 'etag'</li></ul> |
| Name | Description | Only if |
| ------------------- | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| missing parent | Method should fail with InvalidArgument if no parent is provided. | Generated only if all are true: <ul><li>has Create method</li><li>resource has a parent</li></ul> |
| invalid parent | Method should fail with InvalidArgument if provided parent is invalid. | Generated only if all are true: <ul><li>has Create method</li><li>resource has a parent</li></ul> |
| create time | Field create_time should be populated when the resource is created. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has field 'create_time'</li></ul> |
| persisted | The created resource should be persisted and reachable with Get. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has Get method</li></ul> |
| user settable id | If method support user settable IDs, when set the resource should be returned with the provided ID. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has user settable ID</li></ul> |
| already exists | If method support user settable IDs and the same ID is reused the method should return AlreadyExists. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has user settable ID</li></ul> |
| required fields | The method should fail with InvalidArgument if the resource has any required fields and they are not provided. | Generated only if all are true: <ul><li>has Create method</li><li>resource has any required fields</li></ul> |
| resource references | The method should fail with InvalidArgument if the resource has any resource references and they are invalid. | Generated only if all are true: <ul><li>has Create method</li><li>resource has any mutable resource references</li></ul> |
| etag populated | Field etag should be populated when the resource is created. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has field 'etag'</li></ul> |

### Get

Expand Down Expand Up @@ -200,8 +165,8 @@ Sample skips:
| update time | Field update_time should be updated when the resource is updated. | Generated only if all are true: <ul><li>has Create method</li><li>Create method does not return long-running operation</li><li>has Update method</li><li>Update method does not return long-running operation</li><li>has field 'update_time'</li></ul> |
| persisted | The updated resource should be persisted and reachable with Get. | Generated only if all are true: <ul><li>has Update method</li><li>Update method does not return long-running operation</li><li>has Get method</li></ul> |
| preserve create_time | The field create_time should be preserved when a '\*'-update mask is used. | Generated only if all are true: <ul><li>has Update method</li><li>Update method does not return long-running operation</li><li>has field 'create_time'</li><li>resource has any required fields</li></ul> |
| etag mismatch | Method should fail with Aborted if the supplied etag doesnt match the current etag value. | Generated only if all are true: <ul><li>has Update method</li><li>has field 'etag'</li></ul> |
| etag updated | Field etag should have a new value when the resource is successfully updated. | Generated only if all are true: <ul><li>has Update method</li><li>has field 'etag'</li></ul> |
| etag mismatch | Method should fail with Aborted if the supplied etag doesnt match the current etag value. | Generated only if all are true: <ul><li>has Update method</li><li>request has etag field</li><li>has field 'etag'</li></ul> |
| etag updated | Field etag should have a new value when the resource is successfully updated. | Generated only if all are true: <ul><li>has Update method</li><li>request has etag field</li><li>has field 'etag'</li></ul> |
| not found | Method should fail with NotFound if the resource does not exist. | Generated only if all are true: <ul><li>has Update method</li></ul> |
| invalid update mask | The method should fail with InvalidArgument if the update_mask is invalid. | Generated only if all are true: <ul><li>has Update method</li><li>Update method has update_mask</li></ul> |
| required fields | Method should fail with InvalidArgument if any required field is missing when called with '\*' update_mask. | Generated only if all are true: <ul><li>has Update method</li><li>resource has any required fields</li></ul> |
Expand Down
File renamed without changes.

0 comments on commit 6758d5b

Please sign in to comment.