Skip to content

Commit 4b5cb4d

Browse files
committed
Added detailed assertions for vehicles with indication of missing data. Integrated custom asymmetric matchers for Jest.
1 parent 28bce2c commit 4b5cb4d

File tree

2 files changed

+259
-4
lines changed

2 files changed

+259
-4
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* We make ourselves compatible with AsymmetricMatcher class used by Jest
3+
* @see https://github.com/facebook/jest/blob/master/packages/expect/src/asymmetric_matchers.js
4+
*
5+
* Perhaps we can simplify that a bit and write only Jasmine-compatible matchers.
6+
* @see https://jasmine.github.io/2.4/introduction.html#section-Custom_asymmetric_equality_tester
7+
*/
8+
class CustomAsymmetricMatcher {
9+
constructor() {
10+
// $$typeof is used internally by Jest and just to be sure let's use jest Symbol
11+
this.$$typeof = Symbol.for("jest.asymmetricMatcher")
12+
}
13+
}
14+
15+
/**
16+
* Expect metric and imperial volume numbers in object.
17+
*/
18+
class SpacexVolume extends CustomAsymmetricMatcher {
19+
asymmetricMatch(any) {
20+
expect(any).toEqual(expect.anything())
21+
expect(any).toHaveProperty("cubic_meters", expect.any(Number))
22+
expect(any).toHaveProperty("cubic_feet", expect.any(Number))
23+
expect(any.cubic_meters).toBeGreaterThanOrEqual(0)
24+
expect(any.cubic_feet).toBeGreaterThanOrEqual(0)
25+
return true
26+
}
27+
28+
toString() {
29+
return "SpacexVolume"
30+
}
31+
32+
getExpectedType() {
33+
return "object"
34+
}
35+
36+
toAsymmetricMatcher() {
37+
return "SpacexVolume"
38+
}
39+
}
40+
41+
/**
42+
* Expect metric and imperial length (or dimension) numbers in object.
43+
*/
44+
class SpacexLength extends CustomAsymmetricMatcher {
45+
asymmetricMatch(any) {
46+
expect(any).toEqual(expect.anything())
47+
expect(any).toHaveProperty("meters", expect.any(Number))
48+
expect(any).toHaveProperty("feet", expect.any(Number))
49+
expect(any.meters).toBeGreaterThanOrEqual(0)
50+
expect(any.feet).toBeGreaterThanOrEqual(0)
51+
return true
52+
}
53+
54+
toString() {
55+
return "SpacexLength"
56+
}
57+
58+
getExpectedType() {
59+
return "object"
60+
}
61+
62+
toAsymmetricMatcher() {
63+
return "SpacexLength"
64+
}
65+
}
66+
67+
/**
68+
* Expect metric and imperial mass numbers in object.
69+
*/
70+
class SpacexMass extends CustomAsymmetricMatcher {
71+
asymmetricMatch(any) {
72+
expect(any).toEqual(expect.anything())
73+
expect(any).toHaveProperty("kg", expect.any(Number))
74+
expect(any).toHaveProperty("lb", expect.any(Number))
75+
expect(any.kg).toBeGreaterThanOrEqual(0)
76+
expect(any.lb).toBeGreaterThanOrEqual(0)
77+
return true
78+
}
79+
80+
toString() {
81+
return "SpacexMass"
82+
}
83+
84+
getExpectedType() {
85+
return "object"
86+
}
87+
88+
toAsymmetricMatcher() {
89+
return "SpacexMass"
90+
}
91+
}
92+
93+
module.exports = {
94+
volume: () => {
95+
return new SpacexVolume()
96+
},
97+
length: () => {
98+
return new SpacexLength()
99+
},
100+
mass: () => {
101+
return new SpacexMass()
102+
}
103+
}

test/v1-all.test.js

Lines changed: 156 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
const app = require("../app")
33
const request = require("supertest")
4+
const customMatchers = require("./utilities/custom-asymmetric-matchers")
45

56
beforeAll((done) => {
67
app.on("ready", () => {
@@ -102,9 +103,56 @@ test("It should return all vehicle info", () => {
102103
expect(response.body[3]).toHaveProperty("name", "Dragon 1")
103104

104105
response.body.forEach(item => {
105-
expect(item).toHaveProperty("id")
106-
expect(item).toHaveProperty("name")
107-
expect(item).toHaveProperty("active")
106+
expect(item).toHaveProperty("id", expect.any(String))
107+
expect(item).toHaveProperty("name", expect.any(String))
108+
expect(item).toHaveProperty("type", expect.stringMatching(/^(?:rocket|capsule)$/))
109+
expect(item).toHaveProperty("active", expect.any(Boolean))
110+
if (item.type === "rocket") {
111+
expect(item).toHaveProperty("stages", expect.any(Number))
112+
// expect(item).toHaveProperty("boosters", expect.any(Number)) // missing from falcon1
113+
expect(item).toHaveProperty("cost_per_launch", expect.any(Number))
114+
// expect(item).toHaveProperty("orbit_duration_yr", expect.any(Number)) // missing from falcon1
115+
// expect(item).toHaveProperty("success_rate_pct", expect.any(Number)) // missing from FH
116+
expect(item).toHaveProperty("first_flight", expect.stringMatching(/^(?:[0-9]{4}-[0-9]{2}-[0-9]{2}|TBD)$/))
117+
// expect(item).toHaveProperty("launchpad", expect.any(String)) // missing from falcon9
118+
expect(item).toHaveProperty("country", expect.any(String))
119+
expect(item).toHaveProperty("company", expect.any(String))
120+
expect(item).toHaveProperty("height", customMatchers.length())
121+
// expect(item).toHaveProperty("diameter", customMatchers.length()) // missing from FH
122+
// expect(item).toHaveProperty("total_width",customMatchers.length()) // missing from falcon1
123+
expect(item).toHaveProperty("mass", customMatchers.mass())
124+
expect(item).toHaveProperty("payload_weights", expect.any(Array)) // TODO test it deeper
125+
expect(item).toHaveProperty("first_stage", expect.any(Object)) // TODO test it deeper
126+
expect(item).toHaveProperty("second_stage", expect.any(Object)) // TODO test it deeper
127+
// expect(item).toHaveProperty("landing_legs", expect.any(Number)) // missing from falcon1
128+
expect(item).toHaveProperty("description", expect.any(String))
129+
}
130+
else if (item.type === "capsule") {
131+
expect(item).toHaveProperty("sidewall_angle_deg", expect.any(Number))
132+
expect(item).toHaveProperty("orbit_duration_yr", expect.any(Number))
133+
expect(item).toHaveProperty("variations", expect.any(Object)) // TODO test it deeper
134+
expect(item).toHaveProperty("heat_shield.dev_partner", expect.any(String))
135+
expect(item).toHaveProperty("heat_shield.material", expect.any(String))
136+
expect(item).toHaveProperty("heat_shield.size_meters", expect.any(Number))
137+
expect(item).toHaveProperty("heat_shield.temp_degrees", expect.any(Number))
138+
expect(item).toHaveProperty("thrusters.amount", expect.any(Number))
139+
expect(item).toHaveProperty("thrusters.fuel_1", expect.any(String))
140+
expect(item).toHaveProperty("thrusters.fuel_2", expect.any(String))
141+
expect(item).toHaveProperty("thrusters.pods", expect.any(Number))
142+
expect(item).toHaveProperty("thrusters.thrust.kN", expect.any(Number))
143+
expect(item).toHaveProperty("thrusters.thrust.lbf", expect.any(Number))
144+
expect(item).toHaveProperty("thrusters.type", expect.any(String))
145+
expect(item).toHaveProperty("launch_payload_mass", customMatchers.mass())
146+
expect(item).toHaveProperty("launch_payload_vol", customMatchers.volume())
147+
expect(item).toHaveProperty("return_payload_mass", customMatchers.mass())
148+
expect(item).toHaveProperty("return_payload_vol", customMatchers.volume())
149+
expect(item).toHaveProperty("pressurized_capsule.payload_volume", customMatchers.volume())
150+
expect(item).toHaveProperty("trunk.cargo.solar_array", expect.any(Number))
151+
expect(item).toHaveProperty("trunk.cargo.unpressurized_cargo", expect.any(Boolean))
152+
expect(item).toHaveProperty("trunk.trunk_volume", customMatchers.volume())
153+
expect(item).toHaveProperty("height_w_trunk", customMatchers.length())
154+
expect(item).toHaveProperty("diameter", customMatchers.length())
155+
}
108156
})
109157
})
110158
})
@@ -116,10 +164,34 @@ test("It should return Falcon 1 info", () => {
116164
expect(response.body).toHaveProperty("stages", 2)
117165
expect(response.body).toHaveProperty("cost_per_launch")
118166
expect(response.body).toHaveProperty("success_rate_pct")
119-
expect(response.body).toHaveProperty("first_flight", "2016-03-24")
167+
expect(response.body).toHaveProperty("first_flight", "2006-03-24")
120168
expect(response.body).toHaveProperty("country")
121169
expect(response.body).toHaveProperty("company", "SpaceX")
122170
expect(response.body).toHaveProperty("description")
171+
expect(Object.keys(response.body)).toEqual([
172+
"id",
173+
"name",
174+
"type",
175+
"active",
176+
"stages",
177+
// "boosters",
178+
"cost_per_launch",
179+
"success_rate_pct",
180+
"first_flight",
181+
"launchpad",
182+
"country",
183+
"company",
184+
"height",
185+
"diameter",
186+
// "total_width",
187+
"mass",
188+
"payload_weights",
189+
"first_stage",
190+
"second_stage",
191+
// "engines",
192+
// "landing_legs",
193+
"description"
194+
])
123195
})
124196
})
125197

@@ -134,6 +206,30 @@ test("It should return Falcon 9 info", () => {
134206
expect(response.body).toHaveProperty("country")
135207
expect(response.body).toHaveProperty("company", "SpaceX")
136208
expect(response.body).toHaveProperty("description")
209+
expect(Object.keys(response.body)).toEqual([
210+
"id",
211+
"name",
212+
"type",
213+
"active",
214+
"stages",
215+
// "boosters",
216+
"cost_per_launch",
217+
"success_rate_pct",
218+
"first_flight",
219+
// "launchpad",
220+
"country",
221+
"company",
222+
"height",
223+
"diameter",
224+
// "total_width",
225+
"mass",
226+
"payload_weights",
227+
"first_stage",
228+
"second_stage",
229+
"engines",
230+
"landing_legs",
231+
"description"
232+
])
137233
})
138234
})
139235

@@ -148,13 +244,69 @@ test("It should return Falcon Heavy info", () => {
148244
expect(response.body).toHaveProperty("country")
149245
expect(response.body).toHaveProperty("company", "SpaceX")
150246
expect(response.body).toHaveProperty("description")
247+
expect(Object.keys(response.body)).toEqual([
248+
"id",
249+
"name",
250+
"type",
251+
"active",
252+
"stages",
253+
"boosters",
254+
"cost_per_launch",
255+
// "success_rate_pct",
256+
"first_flight",
257+
// "launchpad",
258+
"country",
259+
"company",
260+
"height",
261+
// "diameter",
262+
"total_width",
263+
"mass",
264+
"payload_weights",
265+
"first_stage",
266+
"second_stage",
267+
"engines",
268+
"landing_legs",
269+
"description"
270+
])
151271
})
152272
})
153273

154274
test("It should return Dragon info", () => {
155275
return request(app).get("/v1/vehicles/dragon").then(response => {
156276
expect(response.statusCode).toBe(200)
157277
expect(response.body).toHaveProperty("name", "Dragon 1")
278+
expect(Object.keys(response.body)).toEqual([
279+
"id",
280+
"name",
281+
"type",
282+
"active",
283+
// "stages",
284+
// "cost_per_launch",
285+
// "success_rate_pct",
286+
// "first_flight",
287+
// "launchpad",
288+
// "country",
289+
// "company",
290+
// "height",
291+
"sidewall_angle_deg", // capsule specific field
292+
"orbit_duration_yr", // capsule specific field
293+
"variations", // capsule specific field
294+
"heat_shield", // capsule specific field
295+
"thrusters", // capsule specific field
296+
"launch_payload_mass", // capsule specific field
297+
"launch_payload_vol", // capsule specific field
298+
"return_payload_mass", // capsule specific field
299+
"return_payload_vol", // capsule specific field
300+
"pressurized_capsule", // capsule specific field
301+
"trunk", // capsule specific field
302+
"height_w_trunk", // capsule specific field
303+
"diameter",
304+
// "mass",
305+
// "payload_weights",
306+
// "first_stage",
307+
// "second_stage",
308+
// "description"
309+
])
158310
})
159311
})
160312

0 commit comments

Comments
 (0)