-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
No dependency runtime validators (#37)
* Added jest for automated testing * Created BaseValidator and CatalogValidator classes * Updated exports * Created basic jest test for Catalog objects * Added github action to run jest tests
- Loading branch information
1 parent
9d653a4
commit c16cdfb
Showing
9 changed files
with
3,971 additions
and
656 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
name: Jest CI | ||
on: push | ||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Install modules | ||
run: npm i | ||
- name: Run tests | ||
run: npm run test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** @type {import('ts-jest').JestConfigWithTsJest} */ | ||
module.exports = { | ||
preset: "ts-jest", | ||
testEnvironment: "node", | ||
modulePaths: ["<rootDir>"], | ||
}; |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { ScryfallCatalog } from "src/objects"; | ||
import CatalogValidator from "src/validators/objects/Catalog/CatalogValidator"; | ||
|
||
const cardNamesRequest: Promise<ScryfallCatalog> = fetch("https://api.scryfall.com/catalog/card-names").then((resp) => | ||
resp.json(), | ||
); | ||
|
||
describe("Catalog", () => { | ||
test("has expected fields", async () => { | ||
const cardNamesCatalog = await cardNamesRequest; | ||
const goodValidator = new CatalogValidator(cardNamesCatalog); | ||
|
||
expect(goodValidator.validKeys).toBe(true); | ||
}); | ||
|
||
test("expected fields are expected type", async () => { | ||
const cardNamesCatalog = await cardNamesRequest; | ||
const validator = new CatalogValidator(cardNamesCatalog); | ||
expect(validator.validKeyType).toBe(true); | ||
}); | ||
|
||
test("has no unexpected fields", async () => { | ||
const cardNamesCatalog = await cardNamesRequest; | ||
const mockKeyUpdates = { ...cardNamesCatalog, notAKey: true }; | ||
const validator = new CatalogValidator(mockKeyUpdates); | ||
expect(validator.validKeys).toBe(false); | ||
}); | ||
|
||
test("total_values matches data length", async () => { | ||
const cardNamesCatalog = await cardNamesRequest; | ||
const validator = new CatalogValidator(cardNamesCatalog); | ||
const dataLength = validator.validDataLength; | ||
expect(dataLength).toBe(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from "./objects"; | ||
export * from "./validators"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* Represents the most basic needs for a Validator class. | ||
* @abstract | ||
* @class BaseValidator | ||
*/ | ||
export default abstract class BaseValidator<T extends Record<string, unknown> = Record<string, unknown>> { | ||
/** The object passed to the Validator */ | ||
object: T; | ||
/** A list of keys we expect to exist in a given object. */ | ||
abstract expectedKeys: string[]; | ||
|
||
/** | ||
* @constructor | ||
* @param {object} object The object to test against. | ||
*/ | ||
constructor(object: T) { | ||
this.object = object; | ||
} | ||
|
||
/** The keys of the object */ | ||
get keys(): Array<keyof typeof this.object> { | ||
return Object.keys(this.object); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as BaseValidator } from "./BaseValidator"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { ScryfallCatalog } from "src/objects"; | ||
import { BaseValidator } from "src/validators"; | ||
|
||
/** | ||
* CatalogValidator | ||
* | ||
* @extends BaseValidator | ||
*/ | ||
export default class CatalogValidator extends BaseValidator { | ||
expectedKeys: string[] = <Array<keyof ScryfallCatalog>>["object", "uri", "total_values", "data"]; | ||
|
||
/** | ||
* @static | ||
* @param {object} obj An object to check | ||
* @returns {boolean} true if the object passes all expected checks | ||
*/ | ||
static isCatalogObject(obj: Record<string, unknown>): obj is ScryfallCatalog { | ||
const validator = new CatalogValidator(obj); | ||
|
||
return validator.validKeys && validator.validKeyType && validator.validDataType; | ||
} | ||
|
||
/** | ||
* true if the object matches all expected keys | ||
* @type {boolean} | ||
*/ | ||
get validKeys(): boolean { | ||
return this.keys.every((val) => this.expectedKeys.includes(val)); | ||
} | ||
|
||
/** | ||
* true if the all keys are of the expected type | ||
* @type {boolean} | ||
* */ | ||
get validKeyType(): boolean { | ||
const objectIsCatalog = this.object.object === "catalog"; | ||
const uriIsString = typeof this.object.uri === "string"; | ||
const totalValsIsNumber = typeof this.object.total_values === "number"; | ||
const dataIsStringArray = this.validDataType; | ||
return objectIsCatalog && uriIsString && totalValsIsNumber && dataIsStringArray; | ||
} | ||
|
||
/** | ||
* true if the 'data' field is the correct type | ||
* @type {boolean} | ||
*/ | ||
get validDataType(): boolean { | ||
if (!Array.isArray(this.object.data)) throw new Error("data is not an array"); | ||
|
||
const isJSObject = typeof this.object.data === "object"; | ||
const isArray = Array.isArray(this.object.data); | ||
const onlyHasStrings = this.object.data.every((val) => typeof val === "string"); | ||
return isJSObject && isArray && onlyHasStrings; | ||
} | ||
|
||
/** | ||
* true if the 'data' field length matches the 'total_values' number | ||
* @type {boolean} | ||
*/ | ||
get validDataLength(): boolean { | ||
if (!Array.isArray(this.object.data)) throw new Error("data is not an array"); | ||
|
||
return this.object.data.length === this.object.total_values; | ||
} | ||
} |