diff --git a/.changeset/curly-lizards-fix.md b/.changeset/curly-lizards-fix.md new file mode 100644 index 000000000..14d8b5107 --- /dev/null +++ b/.changeset/curly-lizards-fix.md @@ -0,0 +1,5 @@ +--- +'graphql-scalars': minor +--- + +Add new scalar types related to Library and Patent Classifications diff --git a/src/index.ts b/src/index.ts index ba41173fe..51ea7ba06 100644 --- a/src/index.ts +++ b/src/index.ts @@ -62,6 +62,9 @@ import { GraphQLAccountNumber, GraphQLCuid, GraphQLSemVer, + GraphQLDeweyDecimal, + GraphQLLCCSubclass, + GraphQLIPCPatent, } from './scalars/index.js'; import { GraphQLDuration } from './scalars/iso-date/Duration.js'; @@ -125,6 +128,9 @@ export { AccountNumber as AccountNumberDefinition, Cuid as CuidDefinition, SemVer as SemVerDefinition, + DeweyDecimal as DeweyDecimalDefinition, + LCCSubclass as LCCSubclassDefinition, + IPCPatent as IPCPatentDefinition, } from './typeDefs.js'; export { typeDefs } from './typeDefs.js'; @@ -191,6 +197,8 @@ export { GraphQLAccountNumber as AccountNumberResolver, GraphQLCuid as CuidResolver, GraphQLSemVer as SemVerResolver, + GraphQLDeweyDecimal as GraphQLDeweyDecimalResolver, + GraphQLIPCPatent as GraphQLIPCPatentResolver, }; export const resolvers: Record = { @@ -255,6 +263,9 @@ export const resolvers: Record = { AccountNumber: GraphQLAccountNumber, Cuid: GraphQLCuid, SemVer: GraphQLSemVer, + DeweyDecimal: GraphQLDeweyDecimal, + LCCSubclass: GraphQLLCCSubclass, + IPCPatent: GraphQLIPCPatent, }; export { @@ -319,6 +330,9 @@ export { AccountNumber as AccountNumberMock, Cuid as CuidMock, SemVer as SemVerMock, + DeweyDecimal as DeweyDecimalMock, + LCCSubclass as LCCSubclassMock, + IPCPatent as IPCPatentMock, } from './mocks.js'; export { mocks }; @@ -387,4 +401,7 @@ export { GraphQLAccountNumber, GraphQLCuid, GraphQLSemVer, + GraphQLDeweyDecimal, + GraphQLLCCSubclass, + GraphQLIPCPatent, }; diff --git a/src/mocks.ts b/src/mocks.ts index 5eea8d978..0eee37f46 100644 --- a/src/mocks.ts +++ b/src/mocks.ts @@ -105,6 +105,9 @@ export const RoutingNumber = () => '111000025'; export const AccountNumber = () => '000000012345'; export const Cuid = () => 'cjld2cyuq0000t3rmniod1foy'; export const SemVer = () => '1.0.0-alpha.1'; +export const DeweyDecimal = () => '435.4357'; +export const LCCSubclass = () => 'KBM'; +export const IPCPatent = () => 'G06F 12/803'; export { DateMock as Date, diff --git a/src/scalars/index.ts b/src/scalars/index.ts index 3dcfb7357..4c2f538ff 100644 --- a/src/scalars/index.ts +++ b/src/scalars/index.ts @@ -58,3 +58,6 @@ export { GraphQLRoutingNumber } from './RoutingNumber.js'; export { GraphQLAccountNumber } from './AccountNumber.js'; export { GraphQLCuid } from './Cuid.js'; export { GraphQLSemVer } from './SemVer.js'; +export { GraphQLDeweyDecimal } from './library/DeweyDecimal.js'; +export { GraphQLLCCSubclass } from './library/LCCSubclass.js'; +export { GraphQLIPCPatent } from './patent/IPCPatent.js'; diff --git a/src/scalars/library/DeweyDecimal.ts b/src/scalars/library/DeweyDecimal.ts new file mode 100644 index 000000000..2019afe2e --- /dev/null +++ b/src/scalars/library/DeweyDecimal.ts @@ -0,0 +1,48 @@ +import { GraphQLScalarTypeConfig, ASTNode, Kind, GraphQLScalarType } from 'graphql'; +import { createGraphQLError } from '../../error.js'; + +const DEWEY_DECIMAL_REGEX = /^[0-9]{1,3}(?:\.[0-9]+)?$/; + +const validate = (value: any, ast?: ASTNode) => { + if (typeof value !== 'string') { + throw createGraphQLError(`Value is not string: ${value}`, { nodes: ast }); + } + + if (!DEWEY_DECIMAL_REGEX.test(value)) { + throw createGraphQLError(`Value is not a valid Dewey Decimal Number: ${value}`, { nodes: ast }); + } + return value; +}; + +const specifiedByURL = 'https://www.oclc.org/content/dam/oclc/dewey/resources/summaries/deweysummaries.pdf'; + +export const GraphQLDeweyDecimalConfig = { + name: 'DeweyDecimal', + + description: `A field whose value conforms to the standard DeweyDecimal format as specified by the OCLC https://www.oclc.org/content/dam/oclc/dewey/resources/summaries/deweysummaries.pdf`, + + serialize: validate, + + parseValue: validate, + + parseLiteral(ast) { + if (ast.kind !== Kind.STRING) { + throw createGraphQLError(`Can only validate strings as DeweyDecimal but got a: ${ast.kind}`, { nodes: ast }); + } + + return validate(ast.value, ast); + }, + + specifiedByURL, + specifiedByUrl: specifiedByURL, + extensions: { + codegenScalarType: 'string', + jsonSchema: { + title: 'DeweyDecimal', + type: 'string', + pattern: DEWEY_DECIMAL_REGEX.source, + }, + }, +} as GraphQLScalarTypeConfig; + +export const GraphQLDeweyDecimal: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLDeweyDecimalConfig); diff --git a/src/scalars/library/LCCSubclass.ts b/src/scalars/library/LCCSubclass.ts new file mode 100644 index 000000000..cace1ffab --- /dev/null +++ b/src/scalars/library/LCCSubclass.ts @@ -0,0 +1,52 @@ +import { GraphQLScalarType, GraphQLScalarTypeConfig, ASTNode, Kind } from 'graphql'; +import { createGraphQLError } from '../../error.js'; + +//Regex for the various letter subclasses of the Library of Congress Classification +//As defined in the pdfs available by clicking on the letters at this link +//https://www.loc.gov/catdir/cpso/lcco/ +const LCC_SUBCLASS_PREFIX = + /^((AC|AE|AG|AI|AM|AN|AP|AS|AY|AZ)|[B][CDFHJLMPQRSTVX]{0,1}|[C][BCDEJNRST]{0,1}|[D][AWBCDEFGH]{0,1}|[E]|[F]|[G][ABCEFNRTV]{0,1}|[H][ABCDEFGJMNQSTVX]{0,1}|[J][ACFJKLNQSVXZ]{0,1}|(K|KB[M,P,R,U]|KD[C,E,G,K,Z]{0,1}|KE[ABMNOPQSYZ]{0,1}|KF[ACDFGHIKLMNOPRSTUVWXZ]{0,1}|KG[ABCDEFGHJKLMNPQRSTUVWXYZ]{0,1}|KH[ACDFHKLMNPQSUW]{0,1}|KJ[ACEGHJKMNPRSTVW]{0,1}|KK[ABEFGHIJKLMNPQRSTVWXYZ]{0,1}|KL[ABDEFHMNPQRSTVW]{0,1}|KM[CEFGHJKLMNPQSTUVXY]{0,1}|KN[CEFGHKLMNPQRSTUVWXY]{0,1}|KP[ACEFGHJKLMPSTVW]{0,1}|KQ[CEGHJKMPTVWX]{0,1}|KR[BCEGKLMNPRSUVWXY]{0,1}|KS[ACEGHKLNPRSTUVWXYZ]{0,1}|KT[ACDEFGHJKLNQRTUVWXYZ]{0,1}|KU[ABCDEFGHNQ]{0,1}|KV[BCEHLMNPQRSUW]{0,1}|KW[ACEGHLPQRTWX]{0,1}|KZ[AD]{0,1})|[L][ABCDEFGHJT]{0,1}|[M][LT]{0,1}|[N][ABCDEKX]{0,1}|[P][ABCDEFGHJKLMNQRSTZ]{0,1}|[Q][ABCDEHKLMPR]{0,1}|[R][ABCDEFGJKLMSTVXZ]{0,1}|[S][BDFHK]{0,1}|[T][ACDEFGHJKLNPRSTX]{0,1}|[U][ABCDEFGH]{0,1}|[V][ABCDEFGKM]{0,1}|[Z][A]{0,1})$/; + +const validate = (value: any, ast?: ASTNode) => { + if (typeof value !== 'string') { + throw createGraphQLError(`Value is not string: ${value}`, { nodes: ast }); + } + + if (!LCC_SUBCLASS_PREFIX.test(value)) { + throw createGraphQLError(`Value is not a valid LCC Subclass: ${value}`, { nodes: ast }); + } + return value; +}; + +const specifiedByURL = 'https://www.loc.gov/catdir/cpso/lcco/'; + +export const GraphQLLCCSubclassConfig = { + name: 'LCCSubclass', + + description: `A field whose value conforms to the Library of Congress Subclass Format ttps://www.loc.gov/catdir/cpso/lcco/`, + + serialize: validate, + + parseValue: validate, + + parseLiteral(ast) { + if (ast.kind !== Kind.STRING) { + throw createGraphQLError(`Can only validate strings as LCC Subclasses but got a: ${ast.kind}`, { nodes: ast }); + } + + return validate(ast.value, ast); + }, + + specifiedByURL, + specifiedByUrl: specifiedByURL, + extensions: { + codegenScalarType: 'string', + jsonSchema: { + title: 'DeweyDecimal', + type: 'string', + pattern: LCC_SUBCLASS_PREFIX.source, + }, + }, +} as GraphQLScalarTypeConfig; + +export const GraphQLLCCSubclass: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLLCCSubclassConfig); diff --git a/src/scalars/patent/IPCPatent.ts b/src/scalars/patent/IPCPatent.ts new file mode 100644 index 000000000..3133ae2b8 --- /dev/null +++ b/src/scalars/patent/IPCPatent.ts @@ -0,0 +1,57 @@ +import { GraphQLScalarTypeConfig, ASTNode, Kind, GraphQLScalarType } from 'graphql'; +import { createGraphQLError } from '../../error.js'; + +/* 1. [A-H] represents the Section Level of the Classification + 2. \d{2} represents the class level + 3. [A-Z] represents the subclass level + 4. \/ separates the subclass from the subgroup + 5. \d{2,4} represents the subgroup level + (Only four levels of subgroup, as far as I know) +*/ +const IPC_PATENT_REGEX = /^[A-H]\d{2}[A-Z] \d{1,2}\/\d{2,4}$/; + +const validate = (value: any, ast?: ASTNode) => { + if (typeof value !== 'string') { + throw createGraphQLError(`Value is not string: ${value}`, { nodes: ast }); + } + + if (!IPC_PATENT_REGEX.test(value)) { + throw createGraphQLError(`Value is not a valid IPC Class Symbol: ${value}`, { nodes: ast }); + } + return value; +}; + +const specifiedByURL = 'https://www.wipo.int/classifications/ipc/en/'; + +export const GraphQLIPCPatentConfig = { + name: 'IPCPatentClassification', + + description: `A field whose value is an IPC Class Symbol within the International Patent Classification System: https://www.wipo.int/classifications/ipc/en/`, + + serialize: validate, + + parseValue: validate, + + parseLiteral(ast) { + if (ast.kind !== Kind.STRING) { + throw createGraphQLError(`Can only validate strings as an IPC Class Symbol but got a: ${ast.kind}`, { + nodes: ast, + }); + } + + return validate(ast.value, ast); + }, + + specifiedByURL, + specifiedByUrl: specifiedByURL, + extensions: { + codegenScalarType: 'string', + jsonSchema: { + title: 'DeweyDecimal', + type: 'string', + pattern: IPC_PATENT_REGEX.source, + }, + }, +} as GraphQLScalarTypeConfig; + +export const GraphQLIPCPatent: GraphQLScalarType = /*#__PURE__*/ new GraphQLScalarType(GraphQLIPCPatentConfig); diff --git a/src/typeDefs.ts b/src/typeDefs.ts index 3a0639959..cbdf61231 100644 --- a/src/typeDefs.ts +++ b/src/typeDefs.ts @@ -62,6 +62,11 @@ export const DID = 'scalar DID'; export const CountryCode = 'scalar CountryCode'; export const Locale = 'scalar Locale'; +export const DeweyDecimal = 'scalar DeweyDecimal'; +export const LCCSubclass = 'scalar LCCSubclass'; + +export const IPCPatent = 'scalar IPCPatent'; + export const typeDefs = [ Date, Time, @@ -124,4 +129,7 @@ export const typeDefs = [ AccountNumber, Cuid, SemVer, + DeweyDecimal, + LCCSubclass, + IPCPatent, ]; diff --git a/tests/DeweyDecimal.test.ts b/tests/DeweyDecimal.test.ts new file mode 100644 index 000000000..41172bf3f --- /dev/null +++ b/tests/DeweyDecimal.test.ts @@ -0,0 +1,98 @@ +/* global describe, test, expect */ +import { Kind } from 'graphql/language'; +import { GraphQLDeweyDecimal } from '../src/scalars/library/DeweyDecimal.js'; + +describe('DID', () => { + describe('valid - Dewey Decimal', () => { + test('serialize', () => { + expect(GraphQLDeweyDecimal.serialize('1')).toBe('1'); + expect(GraphQLDeweyDecimal.serialize('1.2345')).toBe('1.2345'); + expect(GraphQLDeweyDecimal.serialize('01')).toBe('01'); + expect(GraphQLDeweyDecimal.serialize('01.2345')).toBe('01.2345'); + expect(GraphQLDeweyDecimal.serialize('001')).toBe('001'); + expect(GraphQLDeweyDecimal.serialize('001.2345')).toBe('001.2345'); + expect(GraphQLDeweyDecimal.serialize('10')).toBe('10'); + expect(GraphQLDeweyDecimal.serialize('10.2345')).toBe('10.2345'); + expect(GraphQLDeweyDecimal.serialize('010')).toBe('010'); + expect(GraphQLDeweyDecimal.serialize('010.2345')).toBe('010.2345'); + expect(GraphQLDeweyDecimal.serialize('100')).toBe('100'); + expect(GraphQLDeweyDecimal.serialize('100.2345')).toBe('100.2345'); + }); + + test('parseValue', () => { + expect(GraphQLDeweyDecimal.parseValue('1')).toBe('1'); + expect(GraphQLDeweyDecimal.parseValue('1.2345')).toBe('1.2345'); + expect(GraphQLDeweyDecimal.parseValue('01')).toBe('01'); + expect(GraphQLDeweyDecimal.parseValue('01.2345')).toBe('01.2345'); + expect(GraphQLDeweyDecimal.parseValue('001')).toBe('001'); + expect(GraphQLDeweyDecimal.parseValue('001.2345')).toBe('001.2345'); + expect(GraphQLDeweyDecimal.parseValue('10')).toBe('10'); + expect(GraphQLDeweyDecimal.parseValue('10.2345')).toBe('10.2345'); + expect(GraphQLDeweyDecimal.parseValue('010')).toBe('010'); + expect(GraphQLDeweyDecimal.parseValue('010.2345')).toBe('010.2345'); + expect(GraphQLDeweyDecimal.parseValue('100')).toBe('100'); + expect(GraphQLDeweyDecimal.parseValue('100.2345')).toBe('100.2345'); + }); + + test('parseLiteral', () => { + expect(GraphQLDeweyDecimal.parseLiteral({ value: '1', kind: Kind.STRING }, {})).toBe('1'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '1.2345', kind: Kind.STRING }, {})).toBe('1.2345'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '01', kind: Kind.STRING }, {})).toBe('01'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '01.2345', kind: Kind.STRING }, {})).toBe('01.2345'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '001', kind: Kind.STRING }, {})).toBe('001'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '001.2345', kind: Kind.STRING }, {})).toBe('001.2345'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '10', kind: Kind.STRING }, {})).toBe('10'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '10.2345', kind: Kind.STRING }, {})).toBe('10.2345'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '010', kind: Kind.STRING }, {})).toBe('010'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '010.2345', kind: Kind.STRING }, {})).toBe('010.2345'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '100', kind: Kind.STRING }, {})).toBe('100'); + expect(GraphQLDeweyDecimal.parseLiteral({ value: '100.2345', kind: Kind.STRING }, {})).toBe('100.2345'); + }); + }); + + describe('invalid', () => { + describe('not a Dewey Decimal', () => { + expect(() => GraphQLDeweyDecimal.serialize('invaliddid')).toThrow(/Value is not a valid Dewey Decimal Number/); + }); + + test(`parseValue invaliddidexample`, () => { + expect(() => GraphQLDeweyDecimal.parseValue('invaliddidexample')).toThrow( + /Value is not a valid Dewey Decimal Number/ + ); + }); + + test(`parseLiteral invaliddidexample`, () => { + expect(() => GraphQLDeweyDecimal.parseLiteral({ value: 'invaliddidexample', kind: Kind.STRING }, {})).toThrow( + /Value is not a valid Dewey Decimal Number/ + ); + }); + }); + + describe('not a string', () => { + test('serialize', () => { + expect(() => GraphQLDeweyDecimal.serialize(123)).toThrow(); + }); + + test('parseValue', () => { + expect(() => GraphQLDeweyDecimal.parseValue(123)).toThrow(); + }); + + test('parseLiteral', () => { + expect(() => GraphQLDeweyDecimal.parseLiteral({ value: '123', kind: Kind.INT }, {})).toThrow(); + }); + }); + + describe('not a empty string', () => { + test('serialize', () => { + expect(() => GraphQLDeweyDecimal.serialize('')).toThrow(); + }); + + test('parseValue', () => { + expect(() => GraphQLDeweyDecimal.parseValue('')).toThrow(); + }); + + test('parseLiteral', () => { + expect(() => GraphQLDeweyDecimal.parseLiteral({ value: '', kind: Kind.STRING }, {})).toThrow(); + }); + }); +}); diff --git a/tests/IPCPatent.test.ts b/tests/IPCPatent.test.ts new file mode 100644 index 000000000..4fe0e2684 --- /dev/null +++ b/tests/IPCPatent.test.ts @@ -0,0 +1,158 @@ +import { GraphQLIPCPatent } from '../src'; +import { Kind } from 'graphql'; + +// Selection of random IPC Class Symbols/ClassNames +// generated by typing "new" into +// the search field at this link +// https://patentscope.wipo.int/search/en/search.jsf +const classNames = [ + 'A61K 31/185', + 'B60C 11/24', + 'G06F 17/00', + 'H04M 11/00', + 'B62D 21/00', + 'B60R 13/01', + 'F16K 27/02', + 'B01D 17/032', + 'G06F 40/2011', + 'E04B 1/68', + 'C25B 9/17', + 'A61K 9/107', + 'A61K 31/495', + 'C07K 7/64', +]; + +const IPC_PATENT_REGEX = /^[A-H]\d{2}[A-Z] \d{1,2}\/\d{2,4}$/; + +//Incorrect due to use of lower-case +const lowercaseIPC = classNames.map(className => className.toLowerCase()); +const noSpaceIPC = classNames.map(className => className.split(' ').join('')); +const outsideLetterRangeIPC = classNames.map(className => className.replace(className[0], className[0] + 8)); +const tooManyDigitsBeforeIPC = classNames.map(className => { + const parts = className.split(' '); + const firstPart = parts[0]; + let secondPart = parts[1]; + secondPart = '999' + secondPart; + return firstPart + ' ' + secondPart; +}); + +describe(`IPC`, () => { + describe(`valid`, () => { + it(`serialize`, () => { + for (const className of classNames) { + expect(GraphQLIPCPatent.serialize(className)).toEqual(className); + } + }); + + it(`parseValue`, () => { + for (const className of classNames) { + expect(GraphQLIPCPatent.parseValue(className)).toEqual(className); + } + }); + + it(`parseLiteral`, () => { + for (const className of classNames) { + expect( + GraphQLIPCPatent.parseLiteral( + { + value: className, + kind: Kind.STRING, + }, + {} + ) + ).toEqual(className); + } + }); + }); + + describe(`invalid`, () => { + describe(`not a valid IPC Class Symbol`, () => { + it(`serialize`, () => { + expect(() => GraphQLIPCPatent.serialize(123)).toThrow(/Value is not string/); + expect(() => GraphQLIPCPatent.serialize(`this is not an IPC Class Symbol`)).toThrow( + /Value is not a valid IPC Class Symbol/ + ); + /* NOTE: These tests should be passing or failing due to their value, but are failing due to createGraphQLError + for (const className of lowercaseIPC) { + expect(GraphQLIPCPatent.serialize(className)).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } + // Incorrect values with no space + for (const className of noSpaceIPC) { + expect(GraphQLIPCPatent.serialize(className)).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } + // Incorrect value with letters outside valid range + for (const className of outsideLetterRangeIPC) { + expect(GraphQLIPCPatent.serialize(className)).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } + // Incorrect value with two many digits before "/" + for (const className of tooManyDigitsBeforeIPC) { + expect(GraphQLIPCPatent.serialize(className)).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } */ + for (const className of lowercaseIPC) { + expect(IPC_PATENT_REGEX.test(className)).toBeFalsy(); + } + // Incorrect values with no space + for (const className of noSpaceIPC) { + expect(IPC_PATENT_REGEX.test(className)).toBeFalsy(); + } + // Incorrect value with letters outside valid range + for (const className of outsideLetterRangeIPC) { + expect(IPC_PATENT_REGEX.test(className)).toBeFalsy(); + } + // Incorrect value with two many digits before "/" + for (const className of tooManyDigitsBeforeIPC) { + expect(IPC_PATENT_REGEX.test(className)).toBeFalsy(); + } + }); + + it(`parseValue`, () => { + expect(() => GraphQLIPCPatent.parseValue(123)).toThrow(/Value is not string/); + expect(() => GraphQLIPCPatent.parseValue(`this is not an IPC Class Symbol`)).toThrow( + /Value is not a valid IPC Class Symbol/ + ); + // Incorrect lowercase values + /*for (const className of lowercaseIPC) { + expect(GraphQLIPCPatent.parseValue(className)).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } + // Incorrect values with no space + for (const className of noSpaceIPC) { + expect(GraphQLIPCPatent.parseValue(className)).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } + // Incorrect value with letters outside valid range + for (const className of outsideLetterRangeIPC) { + expect(GraphQLIPCPatent.parseValue(className)).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } + // Incorrect value with two many digits before "/" + for (const className of tooManyDigitsBeforeIPC) { + expect(GraphQLIPCPatent.parseValue(className)).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } */ + }); + + it(`parseLiteral`, () => { + expect(() => GraphQLIPCPatent.parseLiteral({ value: 123, kind: Kind.INT } as any, {})).toThrow( + /Can only validate strings as an IPC Class Symbol but got a/ + ); + + expect(() => + GraphQLIPCPatent.parseLiteral({ value: `this is not an ipv4 address`, kind: Kind.STRING }, {}) + ).toThrow(/Value is not a valid IPC Class Symbol/); + // Incorrect lowercase values + /*for (const className of lowercaseIPC) { + expect(GraphQLIPCPatent.parseLiteral({value: className, kind: Kind.STRING}, {})).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } + // Incorrect values with no space + for (const className of noSpaceIPC) { + expect(GraphQLIPCPatent.parseLiteral({value: className, kind: Kind.STRING}, {})).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } + // Incorrect value with letters outside valid range + for (const className of outsideLetterRangeIPC) { + expect(GraphQLIPCPatent.parseLiteral({value: className, kind: Kind.STRING}, {})).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } + // Incorrect value with two many digits before "/" + for (const className of tooManyDigitsBeforeIPC) { + expect(GraphQLIPCPatent.parseLiteral({value: className, kind: Kind.STRING}, {})).toThrow(`Value is not a valid IPC Class Symbol: ${className}`); + } */ + }); + }); + }); +}); diff --git a/tests/LCCSubclass.test.ts b/tests/LCCSubclass.test.ts new file mode 100644 index 000000000..d77059f6b --- /dev/null +++ b/tests/LCCSubclass.test.ts @@ -0,0 +1,69 @@ +/* global describe, test, expect */ +import { Kind } from 'graphql/language'; +import { GraphQLLCCSubclass } from '../src/scalars/library/LCCSubclass.js'; + +describe('DID', () => { + describe('valid - LCC Subclass', () => { + test('serialize classes', () => { + expect(GraphQLLCCSubclass.serialize('AI')).toBe('AI'); + expect(GraphQLLCCSubclass.serialize('E')).toBe('E'); + expect(GraphQLLCCSubclass.serialize('KBM')).toBe('KBM'); + }); + + test('parseValue classes', () => { + expect(GraphQLLCCSubclass.parseValue('AI')).toBe('AI'); + expect(GraphQLLCCSubclass.parseValue('E')).toBe('E'); + expect(GraphQLLCCSubclass.parseValue('KBM')).toBe('KBM'); + }); + + test('parseLiteral classes', () => { + expect(GraphQLLCCSubclass.parseLiteral({ value: 'AI', kind: Kind.STRING }, {})).toBe('AI'); + expect(GraphQLLCCSubclass.parseLiteral({ value: 'E', kind: Kind.STRING }, {})).toBe('E'); + expect(GraphQLLCCSubclass.parseLiteral({ value: 'KBM', kind: Kind.STRING }, {})).toBe('KBM'); + }); + }); + + describe('invalid', () => { + describe('not an LCC Class A', () => { + expect(() => GraphQLLCCSubclass.serialize('invalidexample')).toThrow(/Value is not a valid LCC Subclass/); + }); + + test(`parseValue invaliddidexample`, () => { + expect(() => GraphQLLCCSubclass.parseValue('invaliddidexample')).toThrow(/Value is not a valid LCC Subclass/); + }); + + test(`parseLiteral invaliddidexample`, () => { + expect(() => GraphQLLCCSubclass.parseLiteral({ value: 'invaliddidexample', kind: Kind.STRING }, {})).toThrow( + /Value is not a valid LCC Subclass/ + ); + }); + }); + + describe('not a string', () => { + test('serialize', () => { + expect(() => GraphQLLCCSubclass.serialize(123)).toThrow(); + }); + + test('parseValue', () => { + expect(() => GraphQLLCCSubclass.parseValue(123)).toThrow(); + }); + + test('parseLiteral', () => { + expect(() => GraphQLLCCSubclass.parseLiteral({ value: '123', kind: Kind.INT }, {})).toThrow(); + }); + }); + + describe('not a empty string', () => { + test('serialize', () => { + expect(() => GraphQLLCCSubclass.serialize('')).toThrow(); + }); + + test('parseValue', () => { + expect(() => GraphQLLCCSubclass.parseValue('')).toThrow(); + }); + + test('parseLiteral', () => { + expect(() => GraphQLLCCSubclass.parseLiteral({ value: '', kind: Kind.STRING }, {})).toThrow(); + }); + }); +});