/* eslint-disable max-len */
import { test } from '@japa/runner'
import { ApiSchemaValues } from '../../../src/amf/ApiSchemaValues.js'
import { IAmfDocument } from '../../../src/amf/definitions/Amf.js'
import { AmfNamespace as ns } from '../../../src/amf/definitions/Namespace.js'
import { IApiArrayShape, IApiScalarShape, IShapeUnion, scalarShape } from '../../../src/amf/definitions/Shapes.js'
import { AmfLoader } from './AmfLoader.js'

const loader = new AmfLoader()

test.group('readInputValues()', (group) => {
  let model: IAmfDocument

  group.setup(async () => {
    model = await loader.getGraph('schema-api')
  })

  test('generates the value for a string scalar with example', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'arrableStringWithExample')
    const result = ApiSchemaValues.readInputValues(param, param.schema as IShapeUnion, { fromExamples: true })
    assert.deepEqual(result, ['example 1', 'example 2'])
  })

  test('generates the value for a string scalar with examples', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'arrableStringWithExamples')
    const result = ApiSchemaValues.readInputValues(param, param.schema as IShapeUnion, { fromExamples: true })
    assert.deepEqual(result, ['example 1', 'example 2'])
  })

  test('generates the value for a number scalar with examples', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'arrableNumberWithExamples')
    const result = ApiSchemaValues.readInputValues(param, param.schema as IShapeUnion, { fromExamples: true })
    assert.deepEqual(result, [1, 2])
  })

  test('generates an empty array when no examples', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'arrableNumber')
    const result = ApiSchemaValues.readInputValues(param, param.schema as IShapeUnion)
    assert.deepEqual(result, [])
  })

  test('ignores optional parameters', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'notRequiredArray')
    const result = ApiSchemaValues.readInputValues(param, param.schema as IShapeUnion, { requiredOnly: true })
    assert.deepEqual(result, [])
  })

  test('reads default value', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'notRequiredArrayDefault')
    const result = ApiSchemaValues.readInputValues(param, param.schema as IShapeUnion)
    assert.deepEqual(result, ['test default'])
  })

  test('returns default value', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'notRequiredArray')
    const result = ApiSchemaValues.readInputValues(param, param.schema as IShapeUnion)
    assert.deepEqual(result, [])
  })
})

test.group('readInputValue()', (group) => {
  let model: IAmfDocument

  group.setup(async () => {
    model = await loader.getGraph('schema-api')
  })

  test('returns type default value for a string', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarString')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape)
    assert.typeOf(result, 'string')
  })

  test('returns schema default value for a string', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarStringWithDefault')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape)
    assert.strictEqual(result, 'test default')
  })

  test('returns schema example value for a string', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarStringWithExample')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape, { fromExamples: true })
    assert.strictEqual(result, 'a string')
  })

  test('returns schema example value from examples for a string', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarStringWithExamples')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape, { fromExamples: true })
    assert.strictEqual(result, 'a string 1')
  })

  test('returns type default value for a number', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarNumber')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape)
    assert.typeOf(result, 'number')
  })

  test('returns schema default value for a number', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarNumberWithDefault')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape)
    assert.strictEqual(result, 20)
  })

  test('returns schema example value for a number', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarNumberWithExample')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape, { fromExamples: true })
    assert.strictEqual(result, 10)
  })

  test('returns schema example value from examples for a number', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarNumberWithExamples')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape, { fromExamples: true })
    assert.strictEqual(result, 30)
  })

  test('returns type default value for a boolean', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarBoolean')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape)
    assert.typeOf(result, 'boolean')
  })

  test('returns schema default value for a boolean', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarBooleanWithDefault')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape)
    assert.strictEqual(result, false)
  })

  test('returns schema example value for a boolean', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarBooleanWithExample')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape, { fromExamples: true })
    assert.strictEqual(result, true)
  })

  test('returns schema example value from examples for a boolean', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'scalarBooleanWithExamples')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape, { fromExamples: true })
    assert.strictEqual(result, true)
  })

  test('returns undefined when required only', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'notRequired')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape, { requiredOnly: true })
    assert.strictEqual(result, undefined)
  })

  test('returns default value when not required only', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'notRequired')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape, { requiredOnly: false })
    assert.typeOf(result, 'string')
  })

  test('returns default value when not required only', async ({ assert }) => {
    const param = loader.getParameter(model, '/parameters', 'get', 'notRequiredDefault')
    const result = ApiSchemaValues.readInputValue(param, param.schema as IApiScalarShape)
    assert.strictEqual(result, 'test default')
  })
})

test.group('parseScalarInput()', () => {
  ;[
    [ns.w3.xmlSchema.number, 10, 10],
    [ns.w3.xmlSchema.number, '10', 10],
    [ns.w3.xmlSchema.number, 'test', undefined],
    [ns.aml.vocabularies.shapes.number, 'test', undefined],
    [ns.w3.xmlSchema.integer, '20', 20],
    [ns.aml.vocabularies.shapes.integer, '20', 20],
    [ns.w3.xmlSchema.float, 30.5, 30.5],
    [ns.aml.vocabularies.shapes.float, 30.5, 30.5],
    [ns.w3.xmlSchema.long, '40.75', 40.75],
    [ns.aml.vocabularies.shapes.long, '40.75', 40.75],
    [ns.w3.xmlSchema.double, '50', 50],
    [ns.aml.vocabularies.shapes.double, '50', 50],
  ].forEach(([key, value, expected]) => {
    test(`parses input for ${key}`, ({ assert }) => {
      const shape = scalarShape('')
      shape.dataType = key as string
      const result = ApiSchemaValues.parseScalarInput(value, shape)
      assert.strictEqual(result, expected)
    })
  })
  ;[
    [ns.w3.xmlSchema.boolean, true, true],
    [ns.w3.xmlSchema.boolean, 'true', true],
    [ns.w3.xmlSchema.boolean, false, false],
    [ns.w3.xmlSchema.boolean, 'false', false],
    [ns.aml.vocabularies.shapes.boolean, 'false', false],
    [ns.w3.xmlSchema.boolean, 'test', undefined],
  ].forEach(([key, value, expected]) => {
    test(`parses input for ${key} type with ${value}`, ({ assert }) => {
      const shape = scalarShape('')
      shape.dataType = key as string
      const result = ApiSchemaValues.parseScalarInput(value, shape)
      assert.strictEqual(result, expected)
    })
  })
  ;[
    [ns.w3.xmlSchema.date, '2021-08-03', '2021-08-03'],
    [ns.w3.xmlSchema.date, 'error', undefined],
    [ns.w3.xmlSchema.time, '20:21:22', '20:21:22'],
    [ns.w3.xmlSchema.time, '20:21', '20:21:00'],
    [ns.w3.xmlSchema.time, 'error', undefined],
    [ns.aml.vocabularies.shapes.dateTimeOnly, '2021-08-03T20:21:22.012Z', '2021-08-03T20:21:22'],
    [ns.aml.vocabularies.shapes.dateTimeOnly, 'invalid', undefined],
  ].forEach(([key, value, expected]) => {
    test(`parses input for ${key} type with ${value}`, ({ assert }) => {
      const shape = scalarShape('')
      shape.dataType = key as string
      const result = ApiSchemaValues.parseScalarInput(value, shape)
      assert.strictEqual(result, expected)
    })
  })

  test(`parses input for dateTime, rfc3339`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'rfc3339'
    const result = ApiSchemaValues.parseScalarInput('2021-08-03T20:21:22.012Z', shape)
    assert.strictEqual(result, '2021-08-03T20:21:22.012Z')
  })

  test(`parses input for dateTime, rfc3339 as OAS date-time`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'date-time'
    const result = ApiSchemaValues.parseScalarInput('2021-08-03T20:21:22.012Z', shape)
    assert.strictEqual(result, '2021-08-03T20:21:22.012Z')
  })

  test(`parses input for dateTime, rfc2616`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'rfc2616'
    const result = ApiSchemaValues.parseScalarInput('2021-08-03T20:21:22.012Z', shape)
    assert.strictEqual(result, 'Tue, 03 Aug 2021 20:21:22 GMT')
  })

  test(`parses input for dateTime with invalid value`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'rfc2616'
    const result = ApiSchemaValues.parseScalarInput('bla', shape)
    assert.strictEqual(result, undefined)
  })

  test(`parses input for dateTime with invalid format`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'invalid'
    const result = ApiSchemaValues.parseScalarInput('2021-08-03T20:21:22.012Z', shape)
    assert.strictEqual(result, undefined)
  })
})

test.group('parseUserInput()', (group) => {
  let scalar: IApiScalarShape
  let array: IApiArrayShape
  let model: IAmfDocument

  group.setup(async () => {
    model = await loader.getGraph('schema-api')
    scalar = loader.getShape(model, 'ScalarNumber') as IApiScalarShape
    array = loader.getShape(model, 'NumberArray') as IApiArrayShape
  })

  test('returns the value when no schema', ({ assert }) => {
    // @ts-expect-error Used in testing
    const result = ApiSchemaValues.parseUserInput('test', undefined)
    assert.strictEqual(result, 'test')
  })

  test('returns the value when value = undefined', ({ assert }) => {
    const result = ApiSchemaValues.parseUserInput(undefined, scalar)
    assert.strictEqual(result, undefined)
  })

  test('returns the value when value = null', ({ assert }) => {
    const result = ApiSchemaValues.parseUserInput(null, scalar)
    assert.strictEqual(result, null)
  })

  test('returns the parsed value', ({ assert }) => {
    const result = ApiSchemaValues.parseUserInput('125', scalar)
    assert.strictEqual(result, 125)
  })

  test('returns the parsed value for an array', ({ assert }) => {
    const result = ApiSchemaValues.parseUserInput('126', array)
    assert.strictEqual(result, 126)
  })

  test('returns string value when no "items"', ({ assert }) => {
    const cp = { ...array, items: undefined }
    const result = ApiSchemaValues.parseUserInput('126', cp)
    assert.strictEqual(result, '126')
  })

  test('returns the value for unsupported types', async ({ assert }) => {
    const type = loader.getShape(model, 'ScalarObjectUnion')
    const result = ApiSchemaValues.parseUserInput('126', type)
    assert.strictEqual(result, '126')
  })
})

test.group('readInputType()', () => {
  ;[
    [ns.w3.xmlSchema.number, 'number'],
    [ns.aml.vocabularies.shapes.number, 'number'],
    [ns.w3.xmlSchema.integer, 'number'],
    [ns.aml.vocabularies.shapes.integer, 'number'],
    [ns.w3.xmlSchema.float, 'number'],
    [ns.aml.vocabularies.shapes.float, 'number'],
    [ns.w3.xmlSchema.long, 'number'],
    [ns.aml.vocabularies.shapes.long, 'number'],
    [ns.w3.xmlSchema.double, 'number'],
    [ns.aml.vocabularies.shapes.double, 'number'],
    [ns.w3.xmlSchema.date, 'date'],
    [ns.w3.xmlSchema.time, 'time'],
    [ns.w3.xmlSchema.dateTime, 'datetime-local'],
    [ns.aml.vocabularies.shapes.dateTimeOnly, 'datetime-local'],
    [ns.aml.vocabularies.shapes.boolean, 'boolean'],
    [ns.w3.xmlSchema.boolean, 'boolean'],
    [ns.w3.xmlSchema.string, 'text'],
  ].forEach(([key, expected]) => {
    test(`recognizes a type for ${key}`, ({ assert }) => {
      const result = ApiSchemaValues.readInputType(key)
      assert.strictEqual(result, expected)
    })
  })
})

test.group('readTypedValue()', () => {
  ;[
    [ns.w3.xmlSchema.number, 10, 10],
    [ns.w3.xmlSchema.number, '10', 10],
    [ns.w3.xmlSchema.number, 'test', 0],
    [ns.aml.vocabularies.shapes.number, 'test', 0],
    [ns.w3.xmlSchema.integer, '20', 20],
    [ns.aml.vocabularies.shapes.integer, '20', 20],
    [ns.w3.xmlSchema.float, 30.5, 30.5],
    [ns.aml.vocabularies.shapes.float, 30.5, 30.5],
    [ns.w3.xmlSchema.long, '40.75', 40.75],
    [ns.aml.vocabularies.shapes.long, '40.75', 40.75],
    [ns.w3.xmlSchema.double, '50', 50],
    [ns.aml.vocabularies.shapes.double, '50', 50],
    [ns.w3.xmlSchema.boolean, true, true],
    [ns.w3.xmlSchema.boolean, 'true', true],
    [ns.w3.xmlSchema.boolean, false, false],
    [ns.w3.xmlSchema.boolean, 'false', false],
    [ns.aml.vocabularies.shapes.boolean, 'false', false],
    [ns.w3.xmlSchema.boolean, 'test', false],
    [ns.aml.vocabularies.shapes.nil, 'null', null],
    [ns.w3.xmlSchema.nil, 'null', null],
    ['', null, null],
    ['', undefined, undefined],
    [ns.w3.xmlSchema.string, 'test', 'test'],
  ].forEach(([key, value, expected]) => {
    test(`reads value for ${key}`, ({ assert }) => {
      const result = ApiSchemaValues.readTypedValue(value, String(key))
      assert.strictEqual(result, expected)
    })
  })
})

test.group('arrayValuesFromExamples()', (group) => {
  let model: IAmfDocument

  group.setup(async () => {
    model = await loader.getGraph('schema-api')
  })

  test('returns default value when no argument', ({ assert }) => {
    const result = ApiSchemaValues.arrayValuesFromExamples(undefined)
    assert.deepEqual(result, [])
  })

  test('returns default value when empty argument', ({ assert }) => {
    const result = ApiSchemaValues.arrayValuesFromExamples([])
    assert.deepEqual(result, [])
  })

  test('returns default value when not an array', async ({ assert }) => {
    const scalar = loader.getShape(model, 'ScalarWithExample') as IApiScalarShape
    const result = ApiSchemaValues.arrayValuesFromExamples(scalar.examples)
    assert.deepEqual(result, [])
  })

  test('processes the structured value', async ({ assert }) => {
    const scalar = loader.getShape(model, 'StringArrayExample') as IApiScalarShape
    const result = ApiSchemaValues.arrayValuesFromExamples(scalar.examples)
    assert.deepEqual(result, ['test', 'other'])
  })

  test('applies data types', async ({ assert }) => {
    const scalar = loader.getShape(model, 'NumberArrayExample') as IApiScalarShape
    const result = ApiSchemaValues.arrayValuesFromExamples(scalar.examples)
    assert.deepEqual(result, [1, 2])
  })
})

test.group('inputValueFromExamples()', (group) => {
  let model: IAmfDocument

  group.setup(async () => {
    model = await loader.getGraph('schema-api')
  })

  test('returns default value when no argument', ({ assert }) => {
    // @ts-expect-error Used in testing
    const result = ApiSchemaValues.inputValueFromExamples(undefined)
    assert.strictEqual(result, undefined)
  })

  test('returns default value when empty argument', ({ assert }) => {
    const result = ApiSchemaValues.inputValueFromExamples([])
    assert.strictEqual(result, undefined)
  })

  test('returns default value when not a scalar', async ({ assert }) => {
    const scalar = loader.getShape(model, 'StringArrayExample') as IApiScalarShape
    const result = ApiSchemaValues.inputValueFromExamples(scalar.examples)
    assert.strictEqual(result, undefined)
  })

  test('processes the structured value', async ({ assert }) => {
    const scalar = loader.getShape(model, 'ScalarWithExample') as IApiScalarShape
    const result = ApiSchemaValues.inputValueFromExamples(scalar.examples)
    assert.strictEqual(result, 'A string')
  })

  test('applies data types', async ({ assert }) => {
    const scalar = loader.getShape(model, 'ScalarNumberWithExample') as IApiScalarShape
    const result = ApiSchemaValues.inputValueFromExamples(scalar.examples)
    assert.strictEqual(result, 24)
  })
})

test.group('generateDefaultValue()', () => {
  ;[
    ns.w3.xmlSchema.number,
    ns.aml.vocabularies.shapes.number,
    ns.w3.xmlSchema.integer,
    ns.aml.vocabularies.shapes.integer,
    ns.w3.xmlSchema.float,
    ns.aml.vocabularies.shapes.float,
    ns.w3.xmlSchema.long,
    ns.aml.vocabularies.shapes.long,
    ns.w3.xmlSchema.double,
    ns.aml.vocabularies.shapes.double,
  ].forEach((key) => {
    test(`returns a default type value for ${key}`, ({ assert }) => {
      const shape = scalarShape('')
      shape.dataType = key as string
      const result = ApiSchemaValues.generateDefaultValue(shape)
      assert.typeOf(result, 'number')
    })
  })
  ;[ns.w3.xmlSchema.boolean, ns.aml.vocabularies.shapes.boolean].forEach((key) => {
    test(`returns a default type value for ${key}`, ({ assert }) => {
      const shape = scalarShape('')
      shape.dataType = key as string
      const result = ApiSchemaValues.generateDefaultValue(shape)
      assert.typeOf(result, 'boolean')
    })
  })

  test(`returns a default value for ${ns.w3.xmlSchema.date}`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.date
    const result = ApiSchemaValues.generateDefaultValue(shape)
    assert.equal(result, '')
  })

  test(`returns a default value for ${ns.w3.xmlSchema.time}`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.time
    const result = ApiSchemaValues.generateDefaultValue(shape)
    assert.equal(result, '')
  })

  test(`returns a default value for ${ns.aml.vocabularies.shapes.dateTimeOnly}`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.aml.vocabularies.shapes.dateTimeOnly
    const result = ApiSchemaValues.generateDefaultValue(shape)
    assert.equal(result, '')
  })

  test(`returns a default value for ${ns.w3.xmlSchema.dateTime} without format`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    const result = ApiSchemaValues.generateDefaultValue(shape)
    assert.equal(result, '')
  })

  test(`returns a default value for ${ns.w3.xmlSchema.dateTime} with rfc3339 format`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'rfc3339'
    const result = ApiSchemaValues.generateDefaultValue(shape)
    assert.equal(result, '')
  })

  test(`returns a default value for ${ns.w3.xmlSchema.dateTime} with date-time format`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'date-time'
    const result = ApiSchemaValues.generateDefaultValue(shape)
    assert.equal(result, '')
  })

  test(`returns a default value for ${ns.w3.xmlSchema.dateTime} with rfc2616 format`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'rfc2616'
    const result = ApiSchemaValues.generateDefaultValue(shape)
    assert.equal(result, '')
  })
})

test.group('generateMockedValue()', () => {
  ;[
    ns.w3.xmlSchema.number,
    ns.aml.vocabularies.shapes.number,
    ns.w3.xmlSchema.integer,
    ns.aml.vocabularies.shapes.integer,
    ns.w3.xmlSchema.float,
    ns.aml.vocabularies.shapes.float,
    ns.w3.xmlSchema.long,
    ns.aml.vocabularies.shapes.long,
    ns.w3.xmlSchema.double,
    ns.aml.vocabularies.shapes.double,
  ].forEach((key) => {
    test(`returns a default type value for ${key}`, ({ assert }) => {
      const shape = scalarShape('')
      shape.dataType = key as string
      const result = ApiSchemaValues.generateMockedValue(shape)
      assert.typeOf(result, 'number')
    })
  })
  ;[ns.w3.xmlSchema.boolean, ns.aml.vocabularies.shapes.boolean].forEach((key) => {
    test(`returns a default type value for ${key}`, ({ assert }) => {
      const shape = scalarShape('')
      shape.dataType = key as string
      const result = ApiSchemaValues.generateMockedValue(shape)
      assert.typeOf(result, 'boolean')
    })
  })

  test(`returns a random value for ${ns.w3.xmlSchema.date}`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.date
    const result = ApiSchemaValues.generateMockedValue(shape) as string
    assert.match(result, /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/)
  })

  test(`returns a random value for ${ns.w3.xmlSchema.time}`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.time
    const result = ApiSchemaValues.generateMockedValue(shape) as string
    assert.match(result, /^[0-9]{2}:[0-9]{2}:[0-9]{2}$/)
  })

  test(`returns a random value for ${ns.aml.vocabularies.shapes.dateTimeOnly}`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.aml.vocabularies.shapes.dateTimeOnly
    const result = ApiSchemaValues.generateMockedValue(shape) as string
    assert.match(result, /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/)
  })

  test(`returns a random value for ${ns.w3.xmlSchema.dateTime} without format`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    const result = ApiSchemaValues.generateMockedValue(shape) as string
    assert.match(result, /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$/)
  })

  test(`returns a random value for ${ns.w3.xmlSchema.dateTime} with rfc3339 format`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'rfc3339'
    const result = ApiSchemaValues.generateMockedValue(shape) as string
    assert.match(result, /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$/)
  })

  test(`returns a random value for ${ns.w3.xmlSchema.dateTime} with date-time format`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'date-time'
    const result = ApiSchemaValues.generateMockedValue(shape) as string
    assert.match(result, /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$/)
  })

  test(`returns a random value for ${ns.w3.xmlSchema.dateTime} with rfc2616 format`, ({ assert }) => {
    const shape = scalarShape('')
    shape.dataType = ns.w3.xmlSchema.dateTime
    shape.format = 'rfc2616'
    const result = ApiSchemaValues.generateMockedValue(shape) as string
    assert.match(
      result,
      /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), ([0-3][0-9]) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([0-9]{4}) ([01][0-9]|2[0-3])(:[0-5][0-9]){2} GMT$/
    )
  })
})
