UNPKG

@nyteshade/lattice-legacy

Version:

OO Underpinnings for ease of GraphQL Implementation

184 lines (152 loc) 5.61 kB
import { LatticeFactory as LF, GQLBase, GQLEnum, GQLInterface, //GQLUnion, GQLExpressMiddleware, Schema, Properties, resolver, gql, typeOf, META_KEY, AUTO_PROPS } from '../es6/lattice' import Express from 'express' import { customDedent } from 'ne-tag-fns' const docTag = customDedent({dropLowest: true}) const TYPE = LF.TYPE const jsCarPlans = { name: 'JSCar', schema: gql` type JSCar { make: String, wheels: Int } type Query { findQuad: JSCar } `, resolvers: { findQuad(Class, requestData, {make}) { return new Class({make, wheels: 4}, requestData) } }, docs: { JSCar: { [TYPE]: docTag` A sample GraphQL type denoting a, typically, 4 wheeled vehicle `, name: `The name of the car`, wheels: `The total number of wheels connected to the drivetrain` }, Query: { findQuad: `Finds the nearest four wheeled vehicle` } } } @Schema(gql` type Car { make: String, wheels: Int } type Query { findQuad(make: String): Car } `) class Car extends GQLBase { @resolver findQuad(requestData, {make}) { return new Car({make, wheels: 4}, requestData) } static apiDocs() { const { DOC_CLASS, DOC_QUERIES, DOC_FIELDS } = this return { [DOC_CLASS]: docTag` A sample GraphQL type denoting a, typically, 4 wheeled vehicle `, [DOC_FIELDS]: { name: `The name of the car`, wheels: `The total number of wheels connected to the drivetrain` }, [DOC_QUERIES]: { findQuad: `Finds the nearest four wheeled vehicle` } } } } describe('Test out the functionality of LatticeFactory', () => { let reqData = { req: 'request', res: 'response', next: 'next fn()' } let JSCar = LF.build(jsCarPlans) let car = new JSCar({make: 'Nissan', wheels: 4}, reqData) let autoProps = JSCar[META_KEY][AUTO_PROPS] it('has the built car auto-props function as expected', () => { let make = JSCar.getProp('make', false) let wheels = JSCar.getProp('wheels', false) // We can guarantee that make and wheels are generated by the @Properties // decorator as an automatic property, meaning there were no defined // getters or functions for the named property and automatic ones were // generated for the developer. expect(make).toBe(autoProps.make.get) expect(wheels).toBe(autoProps.wheels.get) }) it('returns the model values as expected for an auto-prop', () => { // Check the functionality of the auto-prop getters expect(car.make).toEqual('Nissan') expect(car.wheels).toBe(4) }) it('has the same resolver function that we built in the plan', async () => { // In a normal scenario, we would create a new instance of car with the // model as the first parameter and the requestData as the second. This // call to getResolver is made in the GQLBase.getMergedRoot() function // which is used when the schema is put together at runtime. let fn = await JSCar.getResolver('findQuad', reqData) // Things to note here: // LatticeFactory resolvers receive the type of class that they are as // first parameter, followed by requestData, finally followed by the actual // parameters supplied by the various GraphQL engines out there. // To simulate that here in this test, we call the properly bound resolver // with the model denoting the make for car1 and for car2 we have to copy // this behavior by sending the JSCar class object as well as the request // data automatically bound when the new instance of JSCar was created. let car1 = fn({make: 'Dodge'}) let car2 = jsCarPlans.resolvers.findQuad(JSCar, reqData, {make: 'Dodge'}) // We should have nearly the same results in both instances of JSCar expect(car1.make).toEqual(car2.make) expect(car1 instanceof JSCar).toBe(true) expect(car2 instanceof JSCar).toBe(true) expect(car1.requestData).toBe(reqData) expect(car2.requestData).toBe(reqData) }) }) describe('Run the same tests on a non-lattice factory version', () => { let reqData = { req: 'request', res: 'response', next: 'next fn()' } let car = new Car({make: 'Nissan', wheels: 4}, reqData) let autoProps = Car[META_KEY][AUTO_PROPS] it('has the built car auto-props function as expected', () => { let make = Car.getProp('make', false) let wheels = Car.getProp('wheels', false) // We can guarantee that make and wheels are generated by the @Properties // decorator as an automatic property, meaning there were no defined // getters or functions for the named property and automatic ones were // generated for the developer. expect(make).toBe(autoProps.make.get) expect(wheels).toBe(autoProps.wheels.get) }) it('returns the model values as expected for an auto-prop', () => { // Check the functionality of the auto-prop getters expect(car.make).toEqual('Nissan') expect(car.wheels).toBe(4) }) it('has the same resolver function that we built in the plan', async () => { // Create a new instance of Car using the normal OOP path through // Lattice. Fetch the resolver defined in the class and specify the // make should be 'Dodge'. Verify we have an instance of the class as // expected and that the model value has the `make` we expect. let fn = await Car.getResolver('findQuad', reqData) let car1 = fn({make: 'Dodge'}) expect(car1 instanceof Car).toBe(true) expect(car1.make).toEqual('Dodge') expect(car1.requestData).toBe(reqData) }) })