Skip to content

Commit

Permalink
feat golang: fixed all the tests, added 'goIncludeTags' flag, added t…
Browse files Browse the repository at this point in the history
…est for go description, removed previously added -i flag, removed unused code and fixed formatting, added modelina_cli/test/fixtures/generate to linter exclusions
  • Loading branch information
Владислав Муранов committed Nov 5, 2024
1 parent ddf971c commit 9c471ce
Show file tree
Hide file tree
Showing 23 changed files with 319 additions and 132 deletions.
19 changes: 14 additions & 5 deletions docs/languages/Go.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ There are special use-cases that each language supports; this document pertains
<!-- toc is generated with GitHub Actions do not remove toc markers -->
<!-- toc -->

- [Generate serializer and deserializer functionality](#generate-serializer-and-deserializer-functionality)
* [To and from JSON](#to-and-from-json)
* [To and from XML](#to-and-from-xml)
* [To and from binary](#to-and-from-binary)
- [Go](#go)
- [Generate serializer and deserializer functionality](#generate-serializer-and-deserializer-functionality)
- [To and from JSON](#to-and-from-json)
- [JSON Tags](#json-tags)
- [To and from XML](#to-and-from-xml)
- [To and from binary](#to-and-from-binary)
- [Rendering comments from description and example fields](#rendering-comments-from-description-and-example-fields)

<!-- tocstop -->

Expand All @@ -24,7 +27,7 @@ Here are all the supported presets and the libraries they use for converting to

#### JSON Tags

To generate go models that work correctly with JSON marshal functions we need to generate appropriate JSON `struct-tags`, use the preset `GO_COMMON_PRESET` and provide the option `addJsonTag: true`.
To generate go models that work correctly with JSON marshal functions we need to generate appropriate JSON `struct-tags`, use the preset `GO_COMMON_PRESET` and provide the option `addJsonTag: true` (added in CLI by default).

check out this [example for a live demonstration](../../examples/go-json-tags/)

Expand All @@ -33,3 +36,9 @@ Currently not supported, [let everyone know you need it](https://github.com/asyn

### To and from binary
Currently not supported, [let everyone know you need it](https://github.com/asyncapi/modelina/issues/new?assignees=&labels=enhancement&template=enhancement.md)!

## Rendering comments from description and example fields

You can use the `GO_DESCRIPTION_PRESET` to generate comments from description fields in your model.

See [this example](../../examples/generate-go-asyncapi-comments) for how this can be used.
17 changes: 17 additions & 0 deletions examples/generate-go-asyncapi-comments/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Go Data Models from AsyncAPI

A basic example of how to use Modelina and output a Go data model from AsyncAPI, including data tags and comments from description.

## How to run this example

Run this example using:

```sh
npm i && npm run start
```

If you are on Windows, use the `start:windows` script instead:

```sh
npm i && npm run start:windows
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Should be able to render Go Models and should log expected output to console 1`] = `
Array [
"// this is an object
type ExampleStruct struct {
Id int \`json:\\"id,omitempty\\"\`
// this is example msg uid
MsgUid string \`json:\\"msgUid\\" binding:\\"required\\"\`
// this is example event name
EvtName string \`json:\\"evtName,omitempty\\"\`
}",
]
`;
15 changes: 15 additions & 0 deletions examples/generate-go-asyncapi-comments/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const spy = jest.spyOn(global.console, 'log').mockImplementation(() => {
return;
});
import { generate } from './index';

describe('Should be able to render Go Models', () => {
afterAll(() => {
jest.restoreAllMocks();
});
test('and should log expected output to console', async () => {
await generate();
expect(spy.mock.calls.length).toEqual(1);
expect(spy.mock.calls[0]).toMatchSnapshot();
});
});
64 changes: 64 additions & 0 deletions examples/generate-go-asyncapi-comments/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {
GoGenerator,
GO_DESCRIPTION_PRESET,
GO_COMMON_PRESET,
GoCommonPresetOptions
} from '../../src';
import { Parser } from '@asyncapi/parser';
import { TypeScriptGenerator } from '../../src';
const generatorts = new TypeScriptGenerator();
const options: GoCommonPresetOptions = { addJsonTag: true };
const generator = new GoGenerator({
presets: [GO_DESCRIPTION_PRESET, { preset: GO_COMMON_PRESET, options }]
});

const AsyncAPIDocumentText = `
asyncapi: 3.0.0
info:
title: example
version: 0.0.1
channels:
root:
address: /
messages:
exampleRequest:
summary: example operation
payload:
title: exampleStruct
type: object
description: this is an object
required:
- msgUid
additionalProperties: false
properties:
id:
type: integer
msgUid:
type: string
description: this is example msg uid
evtName:
type: string
description: this is example event name
operations:
exampleOperation:
title: This is an example operation
summary: To do something
channel:
$ref: '#/channels/root'
action: send
messages:
- $ref: '#/channels/root/messages/exampleRequest'
`;

export async function generate(): Promise<void> {
const parser = new Parser();
const { document } = await parser.parse(AsyncAPIDocumentText);
const models = await generator.generate(document);
for (const model of models) {
console.log(model.result);
}
}

if (require.main === module) {
generate();
}
10 changes: 10 additions & 0 deletions examples/generate-go-asyncapi-comments/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions examples/generate-go-asyncapi-comments/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"config": {
"example_name": "generate-go-asyncapi-comments"
},
"scripts": {
"install": "cd ../.. && npm i",
"start": "../../node_modules/.bin/ts-node --cwd ../../ ./examples/$npm_package_config_example_name/index.ts",
"start:windows": "..\\..\\node_modules\\.bin\\ts-node --cwd ..\\..\\ .\\examples\\%npm_package_config_example_name%\\index.ts",
"test": "../../node_modules/.bin/jest --config=../../jest.config.js ./examples/$npm_package_config_example_name/index.spec.ts",
"test:windows": "..\\..\\node_modules\\.bin\\jest --config=..\\..\\jest.config.js examples/%npm_package_config_example_name%/index.spec.ts"
}
}
9 changes: 3 additions & 6 deletions examples/generate-go-enums/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

exports[`Should be able to render Go Enums and should log expected output to console 1`] = `
Array [
"// Root represents a Root model.
type Root struct {
"type Root struct {
Cities *Cities
Options *Options
}",
Expand All @@ -12,8 +11,7 @@ type Root struct {

exports[`Should be able to render Go Enums and should log expected output to console 2`] = `
Array [
"// Cities represents an enum of Cities.
type Cities uint
"type Cities uint
const (
CitiesLondon Cities = iota
Expand Down Expand Up @@ -41,8 +39,7 @@ var ValuesToCities = map[any]Cities{

exports[`Should be able to render Go Enums and should log expected output to console 3`] = `
Array [
"// Options represents an enum of Options.
type Options uint
"type Options uint
const (
OptionsNumber_123 Options = iota
Expand Down
3 changes: 1 addition & 2 deletions examples/generate-go-models/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

exports[`Should be able to render Go Models and should log expected output to console 1`] = `
Array [
"// Root represents a Root model.
type Root struct {
"type Root struct {
Email string
}",
]
Expand Down
9 changes: 3 additions & 6 deletions examples/go-json-tags/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

exports[`Should be able to render json-tags in struct and should log expected output to console 1`] = `
Array [
"// Root represents a Root model.
type Root struct {
"type Root struct {
Cities *Cities \`json:\\"cities,omitempty\\"\`
Options *Options \`json:\\"options,omitempty\\"\`
}",
Expand All @@ -12,8 +11,7 @@ type Root struct {
exports[`Should be able to render json-tags in struct and should log expected output to console 2`] = `
Array [
"// Cities represents an enum of Cities.
type Cities uint
"type Cities uint
const (
CitiesLondon Cities = iota
Expand Down Expand Up @@ -54,8 +52,7 @@ func (op Cities) MarshalJSON() ([]byte, error) {
exports[`Should be able to render json-tags in struct and should log expected output to console 3`] = `
Array [
"// Options represents an enum of Options.
type Options uint
"type Options uint
const (
OptionsNumber_123 Options = iota
Expand Down
15 changes: 5 additions & 10 deletions examples/go-union-type/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

exports[`Should be able to render union types and should log expected output to console 1`] = `
Array [
"// AdditionalProperty represents a AdditionalProperty model.
type AdditionalProperty struct {
"type AdditionalProperty struct {
AdditionalPropertyOneOf_0
AdditionalPropertyOneOf_1
string
Expand All @@ -17,8 +16,7 @@ type AdditionalProperty struct {

exports[`Should be able to render union types and should log expected output to console 2`] = `
Array [
"// Union represents a Union model.
type Union struct {
"type Union struct {
string
float64
ModelinaAnyType interface{}
Expand All @@ -28,8 +26,7 @@ type Union struct {

exports[`Should be able to render union types and should log expected output to console 3`] = `
Array [
"// AdditionalPropertyOneOf_6 represents a AdditionalPropertyOneOf_6 model.
type AdditionalPropertyOneOf_6 struct {
"type AdditionalPropertyOneOf_6 struct {
string
float64
bool
Expand All @@ -45,8 +42,7 @@ Array [

exports[`Should be able to render union types and should log expected output to console 5`] = `
Array [
"// AdditionalPropertyOneOf_0 represents a AdditionalPropertyOneOf_0 model.
type AdditionalPropertyOneOf_0 struct {
"type AdditionalPropertyOneOf_0 struct {
Ref string
AdditionalProperties map[string]interface{}
}",
Expand All @@ -55,8 +51,7 @@ type AdditionalPropertyOneOf_0 struct {

exports[`Should be able to render union types and should log expected output to console 6`] = `
Array [
"// AdditionalPropertyOneOf_1 represents a AdditionalPropertyOneOf_1 model.
type AdditionalPropertyOneOf_1 struct {
"type AdditionalPropertyOneOf_1 struct {
Id string
AdditionalProperties map[string]interface{}
}",
Expand Down
3 changes: 2 additions & 1 deletion modelina-cli/.eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/lib
/tmp
/scripts
/test/helpers/init.js
/test/helpers/init.js
/test/fixtures/generate
16 changes: 1 addition & 15 deletions modelina-cli/src/commands/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,7 @@ export default class Models extends ModelinaCommand {
try {
document = await readFile(file, 'utf8');
} catch {
if (flags.input) {
try {
let fname = ""
if (flags.input) {
fname = flags.input
}

document = await readFile(fname, 'utf8');
} catch {
throw new Error(`Unable to read input file content: ${flags.input}`);
}
}
else {
throw new Error(`Unable to read input file content: ${file}`);
}
throw new Error(`Unable to read input file content: ${file}`);
}

const logger = {
Expand Down
5 changes: 0 additions & 5 deletions modelina-cli/src/helpers/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,6 @@ export const ModelinaFlags = {
description: 'The output directory where the models should be written to. Omitting this flag will write the models to `stdout`.',
required: false
}),
input: Flags.string({
char: 'i',
description: 'The input file with the API definition.',
required: false
}),
/**
* Go and Java specific package name to use for the generated models
*/
Expand Down
14 changes: 11 additions & 3 deletions modelina-cli/src/helpers/go.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ export const GoOclifFlags = {
required: false,
default: false,
}),
goIncludeTags: Flags.boolean({
description: 'Golang specific, if enabled add tags while generating models.',
required: false,
default: false,
}),
}

/**
Expand All @@ -17,15 +22,18 @@ export const GoOclifFlags = {
* @returns
*/
export function buildGoGenerator(flags: any): BuilderReturnType {
const { packageName, goIncludeComments } = flags;
const { packageName, goIncludeComments, goIncludeTags } = flags;

if (packageName === undefined) {
throw new Error('In order to generate models to Go, we need to know which package they are under. Add `--packageName=PACKAGENAME` to set the desired package name.');
}

const presets = []
const options: GoCommonPresetOptions = { addJsonTag: true };
presets.push({ preset: GO_COMMON_PRESET, options })
if (goIncludeTags) {
const options: GoCommonPresetOptions = { addJsonTag: true };
presets.push({ preset: GO_COMMON_PRESET, options })
}

if (goIncludeComments) { presets.push(GO_DESCRIPTION_PRESET); }
const fileGenerator = new GoFileGenerator({ presets });
const fileOptions = {
Expand Down
Loading

0 comments on commit 9c471ce

Please sign in to comment.