@coding-blocks/jsonapi-server
Version:
A config driven NodeJS framework implementing json:api
522 lines (521 loc) • 19.1 kB
HTML
<html lang="en">
<head>
<title>Code coverage report for lib/MemoryHandler.js</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../prettify.css" />
<link rel="stylesheet" href="../base.css" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(../sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>
<a href="../index.html">All files</a> / <a href="index.html">lib</a> MemoryHandler.js
</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">20.31% </span>
<span class="quiet">Statements</span>
<span class='fraction'>13/64</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Branches</span>
<span class='fraction'>0/22</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/14</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">22.41% </span>
<span class="quiet">Lines</span>
<span class='fraction'>13/58</span>
</div>
</div>
</div>
<div class='status-line low'></div>
<pre><table class="coverage">
<tr><td class="line-count quiet">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153</td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-no"> </span>
<span class="cline-any cline-neutral"> </span>
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">'use strict'
const _ = {
assign: require('lodash.assign')
}
const MemoryStore = module.exports = function <span class="fstat-no" title="function not covered" >MemoryStore </span>() {
}
// resources represents out in-memory data store
const resources = { }
/**
Handlers readiness status. This should be set to `true` once all handlers are ready to process requests.
*/
MemoryStore.prototype.ready = false
/**
initialise gets invoked once for each resource that uses this hander.
In this instance, we're allocating an array in our in-memory data store.
*/
MemoryStore.prototype.initialise = <span class="fstat-no" title="function not covered" >fu</span>nction (resourceConfig) {
<span class="cstat-no" title="statement not covered" > resources[resourceConfig.resource] = resourceConfig.examples || [ ]</span>
<span class="cstat-no" title="statement not covered" > this.ready = true</span>
}
/**
Search for a list of resources, given a resource type.
*/
MemoryStore.prototype.search = <span class="fstat-no" title="function not covered" >fu</span>nction (request, callback) {
const self = <span class="cstat-no" title="statement not covered" >this</span>
let results = <span class="cstat-no" title="statement not covered" >[].concat(resources[request.params.type])</span>
<span class="cstat-no" title="statement not covered" > self._sortList(request, results)</span>
const resultCount = <span class="cstat-no" title="statement not covered" >results.length</span>
<span class="cstat-no" title="statement not covered" > if (request.params.page) {</span>
<span class="cstat-no" title="statement not covered" > results = results.slice(request.params.page.offset, request.params.page.offset + request.params.page.limit)</span>
}
<span class="cstat-no" title="statement not covered" > return callback(null, MemoryStore._clone(results), resultCount)</span>
}
/**
Find a specific resource, given a resource type and and id.
*/
MemoryStore.prototype.find = <span class="fstat-no" title="function not covered" >(r</span>equest, callback) => {
// Pull the requested resource from the in-memory store
const theResource = <span class="cstat-no" title="statement not covered" >resources[request.params.type].filter(<span class="fstat-no" title="function not covered" >an</span>yResource => <span class="cstat-no" title="statement not covered" >anyResource.id === request.params.id)</span>.pop()</span>
// If the resource doesn't exist, error
<span class="cstat-no" title="statement not covered" > if (!theResource) {</span>
<span class="cstat-no" title="statement not covered" > return callback({ // eslint-disable-line standard/no-callback-literal</span>
status: '404',
code: 'ENOTFOUND',
title: 'Requested resource does not exist',
detail: `There is no ${request.params.type} with id ${request.params.id}`
})
}
// Return the requested resource
<span class="cstat-no" title="statement not covered" > return callback(null, MemoryStore._clone(theResource))</span>
}
/**
Create (store) a new resource given a resource type and an object.
*/
MemoryStore.prototype.create = <span class="fstat-no" title="function not covered" >(r</span>equest, newResource, callback) => {
// Check to see if the ID already exists
const index = <span class="cstat-no" title="statement not covered" >MemoryStore._indexOf(resources[request.params.type], newResource)</span>
<span class="cstat-no" title="statement not covered" > if (index !== -1) {</span>
<span class="cstat-no" title="statement not covered" > return callback({ // eslint-disable-line standard/no-callback-literal</span>
status: '403',
code: 'EFORBIDDEN',
title: 'Requested resource already exists',
detail: `The requested resource already exists of type ${request.params.type} with id ${request.params.id}`
})
}
// Push the newResource into our in-memory store.
<span class="cstat-no" title="statement not covered" > resources[request.params.type].push(newResource)</span>
// Return the newly created resource
<span class="cstat-no" title="statement not covered" > return callback(null, MemoryStore._clone(newResource))</span>
}
/**
Delete a resource, given a resource type and and id.
*/
MemoryStore.prototype.delete = <span class="fstat-no" title="function not covered" >fu</span>nction (request, callback) {
// Find the requested resource
<span class="cstat-no" title="statement not covered" > this.find(request, <span class="fstat-no" title="function not covered" >(e</span>rr, theResource) => {</span>
<span class="cstat-no" title="statement not covered" > if (err) <span class="cstat-no" title="statement not covered" >return callback(err)</span></span>
// Remove the resource from the in-memory store.
const index = <span class="cstat-no" title="statement not covered" >MemoryStore._indexOf(resources[request.params.type], theResource)</span>
<span class="cstat-no" title="statement not covered" > resources[request.params.type].splice(index, 1)</span>
// Return with no error
<span class="cstat-no" title="statement not covered" > return callback()</span>
})
}
/**
Update a resource, given a resource type and id, along with a partialResource.
partialResource contains a subset of changes that need to be merged over the original.
*/
MemoryStore.prototype.update = <span class="fstat-no" title="function not covered" >fu</span>nction (request, partialResource, callback) {
// Find the requested resource
<span class="cstat-no" title="statement not covered" > this.find(request, <span class="fstat-no" title="function not covered" >(e</span>rr, theResource) => {</span>
<span class="cstat-no" title="statement not covered" > if (err) <span class="cstat-no" title="statement not covered" >return callback(err)</span></span>
// Merge the partialResource over the original
<span class="cstat-no" title="statement not covered" > theResource = _.assign(theResource, partialResource)</span>
// Push the newly updated resource back into the in-memory store
const index = <span class="cstat-no" title="statement not covered" >MemoryStore._indexOf(resources[request.params.type], theResource)</span>
<span class="cstat-no" title="statement not covered" > resources[request.params.type][index] = theResource</span>
// Return the newly updated resource
<span class="cstat-no" title="statement not covered" > return callback(null, MemoryStore._clone(theResource))</span>
})
}
/**
Internal helper function to sort data
*/
MemoryStore.prototype._sortList = <span class="fstat-no" title="function not covered" >(r</span>equest, list) => {
let attribute = <span class="cstat-no" title="statement not covered" >request.params.sort</span>
<span class="cstat-no" title="statement not covered" > if (!attribute) <span class="cstat-no" title="statement not covered" >return</span></span>
let ascending = <span class="cstat-no" title="statement not covered" >1</span>
<span class="cstat-no" title="statement not covered" > attribute = (`${attribute}`)</span>
<span class="cstat-no" title="statement not covered" > if (attribute[0] === '-') {</span>
<span class="cstat-no" title="statement not covered" > ascending = -1</span>
<span class="cstat-no" title="statement not covered" > attribute = attribute.substring(1, attribute.length)</span>
}
<span class="cstat-no" title="statement not covered" > list.sort(<span class="fstat-no" title="function not covered" >(a</span>, b) => {</span>
<span class="cstat-no" title="statement not covered" > if (typeof a[attribute] === 'string') {</span>
<span class="cstat-no" title="statement not covered" > return a[attribute].localeCompare(b[attribute]) * ascending</span>
} else <span class="cstat-no" title="statement not covered" >if (typeof a[attribute] === 'number') {</span>
<span class="cstat-no" title="statement not covered" > return (a[attribute] - b[attribute]) * ascending</span>
} else {
<span class="cstat-no" title="statement not covered" > return 0</span>
}
})
}
MemoryStore._clone = <span class="fstat-no" title="function not covered" >ob</span>j => <span class="cstat-no" title="statement not covered" >JSON.parse(JSON.stringify(obj))</span>
MemoryStore._indexOf = <span class="fstat-no" title="function not covered" >(l</span>ist, obj) => {
<span class="cstat-no" title="statement not covered" > for (const i in list) {</span>
<span class="cstat-no" title="statement not covered" > if (list[i].id === obj.id) <span class="cstat-no" title="statement not covered" >return i</span></span>
}
<span class="cstat-no" title="statement not covered" > return -1</span>
}
</pre></td></tr>
</table></pre>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage
generated by <a href="https://istanbul.js.org/" target="_blank">istanbul</a> at Sat Jan 27 2018 19:59:16 GMT+0530 (IST)
</div>
</div>
<script src="../prettify.js"></script>
<script>
window.onload = function () {
if (typeof prettyPrint === 'function') {
prettyPrint();
}
};
</script>
<script src="../sorter.js"></script>
</body>
</html>