UNPKG

5.61 kBJavaScriptView Raw
1import {
2 LatticeFactory as LF,
3 GQLBase,
4 GQLEnum,
5 GQLInterface,
6 //GQLUnion,
7
8 GQLExpressMiddleware,
9
10 Schema,
11 Properties,
12 resolver,
13 gql,
14 typeOf,
15
16 META_KEY,
17 AUTO_PROPS
18} from '../es6/lattice'
19
20import Express from 'express'
21import { customDedent } from 'ne-tag-fns'
22
23const docTag = customDedent({dropLowest: true})
24const TYPE = LF.TYPE
25
26const jsCarPlans = {
27 name: 'JSCar',
28
29 schema: gql`
30 type JSCar {
31 make: String,
32 wheels: Int
33 }
34
35 type Query {
36 findQuad: JSCar
37 }
38 `,
39
40 resolvers: {
41 findQuad(Class, requestData, {make}) {
42 return new Class({make, wheels: 4}, requestData)
43 }
44 },
45
46 docs: {
47 JSCar: {
48 [TYPE]: docTag`
49 A sample GraphQL type denoting a, typically, 4 wheeled vehicle
50 `,
51 name: `The name of the car`,
52 wheels: `The total number of wheels connected to the drivetrain`
53 },
54
55 Query: {
56 findQuad: `Finds the nearest four wheeled vehicle`
57 }
58 }
59}
60
61@Schema(gql`
62 type Car {
63 make: String,
64 wheels: Int
65 }
66
67 type Query {
68 findQuad(make: String): Car
69 }
70`)
71class Car extends GQLBase {
72 @resolver findQuad(requestData, {make}) {
73 return new Car({make, wheels: 4}, requestData)
74 }
75
76 static apiDocs() {
77 const { DOC_CLASS, DOC_QUERIES, DOC_FIELDS } = this
78
79 return {
80 [DOC_CLASS]: docTag`
81 A sample GraphQL type denoting a, typically, 4 wheeled vehicle
82 `,
83
84 [DOC_FIELDS]: {
85 name: `The name of the car`,
86 wheels: `The total number of wheels connected to the drivetrain`
87 },
88
89 [DOC_QUERIES]: {
90 findQuad: `Finds the nearest four wheeled vehicle`
91 }
92 }
93 }
94}
95
96describe('Test out the functionality of LatticeFactory', () => {
97 let reqData = { req: 'request', res: 'response', next: 'next fn()' }
98 let JSCar = LF.build(jsCarPlans)
99 let car = new JSCar({make: 'Nissan', wheels: 4}, reqData)
100 let autoProps = JSCar[META_KEY][AUTO_PROPS]
101
102 it('has the built car auto-props function as expected', () => {
103 let make = JSCar.getProp('make', false)
104 let wheels = JSCar.getProp('wheels', false)
105
106 // We can guarantee that make and wheels are generated by the @Properties
107 // decorator as an automatic property, meaning there were no defined
108 // getters or functions for the named property and automatic ones were
109 // generated for the developer.
110 expect(make).toBe(autoProps.make.get)
111 expect(wheels).toBe(autoProps.wheels.get)
112 })
113
114 it('returns the model values as expected for an auto-prop', () => {
115 // Check the functionality of the auto-prop getters
116 expect(car.make).toEqual('Nissan')
117 expect(car.wheels).toBe(4)
118 })
119
120 it('has the same resolver function that we built in the plan', async () => {
121 // In a normal scenario, we would create a new instance of car with the
122 // model as the first parameter and the requestData as the second. This
123 // call to getResolver is made in the GQLBase.getMergedRoot() function
124 // which is used when the schema is put together at runtime.
125 let fn = await JSCar.getResolver('findQuad', reqData)
126
127 // Things to note here:
128 // LatticeFactory resolvers receive the type of class that they are as
129 // first parameter, followed by requestData, finally followed by the actual
130 // parameters supplied by the various GraphQL engines out there.
131
132 // To simulate that here in this test, we call the properly bound resolver
133 // with the model denoting the make for car1 and for car2 we have to copy
134 // this behavior by sending the JSCar class object as well as the request
135 // data automatically bound when the new instance of JSCar was created.
136 let car1 = fn({make: 'Dodge'})
137 let car2 = jsCarPlans.resolvers.findQuad(JSCar, reqData, {make: 'Dodge'})
138
139 // We should have nearly the same results in both instances of JSCar
140 expect(car1.make).toEqual(car2.make)
141 expect(car1 instanceof JSCar).toBe(true)
142 expect(car2 instanceof JSCar).toBe(true)
143 expect(car1.requestData).toBe(reqData)
144 expect(car2.requestData).toBe(reqData)
145 })
146})
147
148describe('Run the same tests on a non-lattice factory version', () => {
149 let reqData = { req: 'request', res: 'response', next: 'next fn()' }
150 let car = new Car({make: 'Nissan', wheels: 4}, reqData)
151 let autoProps = Car[META_KEY][AUTO_PROPS]
152
153 it('has the built car auto-props function as expected', () => {
154 let make = Car.getProp('make', false)
155 let wheels = Car.getProp('wheels', false)
156
157 // We can guarantee that make and wheels are generated by the @Properties
158 // decorator as an automatic property, meaning there were no defined
159 // getters or functions for the named property and automatic ones were
160 // generated for the developer.
161 expect(make).toBe(autoProps.make.get)
162 expect(wheels).toBe(autoProps.wheels.get)
163 })
164
165 it('returns the model values as expected for an auto-prop', () => {
166 // Check the functionality of the auto-prop getters
167 expect(car.make).toEqual('Nissan')
168 expect(car.wheels).toBe(4)
169 })
170
171 it('has the same resolver function that we built in the plan', async () => {
172 // Create a new instance of Car using the normal OOP path through
173 // Lattice. Fetch the resolver defined in the class and specify the
174 // make should be 'Dodge'. Verify we have an instance of the class as
175 // expected and that the model value has the `make` we expect.
176 let fn = await Car.getResolver('findQuad', reqData)
177 let car1 = fn({make: 'Dodge'})
178
179 expect(car1 instanceof Car).toBe(true)
180 expect(car1.make).toEqual('Dodge')
181 expect(car1.requestData).toBe(reqData)
182 })
183})