Skip to content

Commit

Permalink
Add tests for prototype code (#7)
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Nowak <[email protected]>
  • Loading branch information
rynowak authored Dec 28, 2024
1 parent e98a642 commit 0f7cb1d
Show file tree
Hide file tree
Showing 12 changed files with 399 additions and 101 deletions.
13 changes: 9 additions & 4 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
node-version: '20'
- name: Enable Corepack
run: |
corepack enable
Expand All @@ -34,10 +34,13 @@ jobs:
run: yarn install --no-immutable
env:
YARN_ENABLE_HARDENED_MODE: 0
- name: Verify bicep-types Build Output
run: find bicep-types/src/bicep-types/lib | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"

- name: Build
run: yarn run build:all

- name: Verify bicep-types Build Output
run: find bicep-types/src/bicep-types/lib | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"
- name: Lint
run: yarn run lint:all
publish:
Expand All @@ -61,7 +64,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
node-version: '20'
registry-url: 'https://npm.pkg.github.com'
scope: '@radius-project'
- name: Enable Corepack
Expand All @@ -72,7 +75,9 @@ jobs:
run: yarn install --no-immutable
env:
YARN_ENABLE_HARDENED_MODE: 0

- name: Verify bicep-types Build Output
run: find bicep-types/src/bicep-types/lib | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"

- name: Publish
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
shell: bash
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
node-version: '20'
- name: Enable Corepack
run: |
corepack enable
Expand All @@ -33,6 +33,8 @@ jobs:
run: yarn install --no-immutable
env:
YARN_ENABLE_HARDENED_MODE: 0

- name: Verify bicep-types Build Output
run: find bicep-types/src/bicep-types/lib | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"

- name: Run tests
run: yarn run test:all
1 change: 1 addition & 0 deletions packages/manifest-to-bicep-extension/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ module.exports = {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
moduleNameMapper: {
'^src/(.*)': '<rootDir>/src/$1',
'^bicep-types$': '<rootDir>../../bicep-types/src/bicep-types/',
},
}
3 changes: 2 additions & 1 deletion packages/manifest-to-bicep-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"watch": "tsc -w",
"publish": "npm publish",
"prepublishOnly": "yarn build",
"preinstall": "cd ../../bicep-types/src/bicep-types && npm ci && npm run build",
"preinstall": "echo 'Building bicep-types...'; cd ../../bicep-types/src/bicep-types && npm ci && npm run build",
"postinstall": "echo 'Finished building bicep-types...';",
"version": "npm pkg set version=${0}"
}
}
172 changes: 96 additions & 76 deletions packages/manifest-to-bicep-extension/src/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,71 +11,27 @@ import {
writeIndexMarkdown,
writeTypesJson,
} from 'bicep-types'
import { ResourceProvider, Schema } from './manifest'
import { APIVersion, ResourceProvider, ResourceType, Schema } from './manifest'

export function convert(manifest: ResourceProvider): {
typesContent: string
indexContent: string
documentationContent: string
} {
const factory = new TypeFactory()

for (const resourceType of manifest.types) {
for (const apiVersion of resourceType.apiVersions) {
const qualifiedName = `${manifest.name}/${resourceType.name}@${apiVersion.name}`

const propertyType = factory.addObjectType(
`${resourceType.name}Properties`,
schemaProperties(apiVersion.schema, factory)
)

const bodyType = factory.addObjectType(qualifiedName, {
name: {
type: factory.addStringType(),
flags:
ObjectTypePropertyFlags.Required |
ObjectTypePropertyFlags.Identifier,
description: 'The resource name.',
},
location: {
type: factory.addStringType(),
flags: ObjectTypePropertyFlags.None,
description: 'The resource location.',
},
properties: {
type: propertyType,
flags: ObjectTypePropertyFlags.Required,
description: 'The resource properties.',
},
apiVersion: {
type: factory.addStringLiteralType(apiVersion.name),
flags:
ObjectTypePropertyFlags.ReadOnly |
ObjectTypePropertyFlags.DeployTimeConstant,
description: 'The API version.',
},
type: {
type: factory.addStringLiteralType(
`${manifest.name}/${resourceType.name}`
),
flags:
ObjectTypePropertyFlags.ReadOnly |
ObjectTypePropertyFlags.DeployTimeConstant,
description: 'The resource type.',
},
id: {
type: factory.addStringType(),
flags: ObjectTypePropertyFlags.ReadOnly,
description: 'The resource id.',
},
})
factory.addResourceType(
qualifiedName,
ScopeType.Unknown,
undefined,
bodyType,
ResourceFlags.None,
{}
for (const [resourceTypeName, resourceType] of Object.entries(
manifest.types
)) {
for (const [apiVersionName, apiVersion] of Object.entries(
resourceType.apiVersions
)) {
addResourceTypeForApiVersion(
manifest,
resourceTypeName,
resourceType,
apiVersionName,
apiVersion,
factory
)
}
}
Expand All @@ -99,24 +55,102 @@ export function convert(manifest: ResourceProvider): {
}
}

function schemaProperties(
export function addResourceTypeForApiVersion(
manifest: ResourceProvider,
resourceTypeName: string,
_: ResourceType,
apiVersionName: string,
apiVersion: APIVersion,
factory: TypeFactory
): TypeReference {
const qualifiedName = `${manifest.name}/${resourceTypeName}@${apiVersionName}`

const propertyType = factory.addObjectType(
`${resourceTypeName}Properties`,
addObjectProperties(apiVersion.schema, factory)
)

const bodyType = factory.addObjectType(qualifiedName, {
name: {
type: factory.addStringType(),
flags:
ObjectTypePropertyFlags.Required | ObjectTypePropertyFlags.Identifier,
description: 'The resource name.',
},
location: {
type: factory.addStringType(),
flags: ObjectTypePropertyFlags.None,
description: 'The resource location.',
},
properties: {
type: propertyType,
flags: ObjectTypePropertyFlags.Required,
description: 'The resource properties.',
},
apiVersion: {
type: factory.addStringLiteralType(apiVersionName),
flags:
ObjectTypePropertyFlags.ReadOnly |
ObjectTypePropertyFlags.DeployTimeConstant,
description: 'The API version.',
},
type: {
type: factory.addStringLiteralType(
`${manifest.name}/${resourceTypeName}`
),
flags:
ObjectTypePropertyFlags.ReadOnly |
ObjectTypePropertyFlags.DeployTimeConstant,
description: 'The resource type.',
},
id: {
type: factory.addStringType(),
flags: ObjectTypePropertyFlags.ReadOnly,
description: 'The resource id.',
},
})
return factory.addResourceType(
qualifiedName,
ScopeType.Unknown,
undefined,
bodyType,
ResourceFlags.None,
{}
)
}

export function addSchemaType(
schema: Schema,
name: string,
factory: TypeFactory
): TypeReference {
if (schema.type === 'string') {
return factory.addStringType()
} else if (schema.type === 'object') {
return factory.addObjectType(name, addObjectProperties(schema, factory))
} else {
throw new Error(`Unsupported schema type: ${schema.type}`)
}
}

export function addObjectProperties(
parent: Schema,
factory: TypeFactory
): Record<string, ObjectTypeProperty> {
const results: Record<string, ObjectTypeProperty> = {}
for (const [key, value] of Object.entries(parent.properties ?? {})) {
results[key] = addSchemaProperty(parent, key, value, factory)
results[key] = addObjectProperty(parent, key, value, factory)
}
return results
}

function addSchemaProperty(
export function addObjectProperty(
parent: Schema,
key: string,
property: Schema,
factory: TypeFactory
): ObjectTypeProperty {
const propertyType = addSchema(property, key, factory)
const propertyType = addSchemaType(property, key, factory)

let flags = ObjectTypePropertyFlags.None
if (parent.required?.includes(key)) {
Expand All @@ -132,17 +166,3 @@ function addSchemaProperty(
flags: flags,
}
}

function addSchema(
schema: Schema,
name: string,
factory: TypeFactory
): TypeReference {
if (schema.type === 'string') {
return factory.addStringType()
} else if (schema.type === 'object') {
return factory.addObjectType(name, schemaProperties(schema, factory))
} else {
throw new Error(`Unsupported schema type: ${schema.type}`)
}
}
15 changes: 10 additions & 5 deletions packages/manifest-to-bicep-extension/src/manifest.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import { parse } from 'yaml'

export interface ResourceProvider {
name: string
types: ResourceType[]
types: Record<string, ResourceType>
}

export interface ResourceType {
name: string
defaultApiVersion?: string
apiVersions: APIVersion[]
apiVersions: Record<string, APIVersion>
}

export interface APIVersion {
name: string
schema: Schema
capabilities?: string[]
}

export interface Schema {
type: 'string' | 'object'
description?: string
properties?: Schema[]
properties?: Record<string, Schema>
required?: string[]
readOnly?: boolean
}

export function parseManifest(input: string): ResourceProvider {
const parsed = parse(input) as ResourceProvider
return parsed
}
3 changes: 0 additions & 3 deletions packages/manifest-to-bicep-extension/src/math.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/manifest-to-bicep-extension/src/program.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { parse } from 'yaml'
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'
import fs from 'node:fs'
import { convert } from './converter'
import { parseManifest } from './manifest'

async function generate(manifest: string, output: string) {
const data = fs.readFileSync(manifest, 'utf8')
const parsed = parse(data)
const parsed = parseManifest(data)
const converted = convert(parsed)

fs.rmSync(`${output}/types.json`, { force: true })
Expand Down
Loading

0 comments on commit 0f7cb1d

Please sign in to comment.