koa-classic-server 1.0.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/OLD_launch.json +26 -0
- package/.vscode/launch.json +41 -0
- package/README.md +4 -0
- package/__tests__/index.test.js +337 -0
- package/__tests__/publicWwwTest/cartella/sottocartella/ciao.html +11 -0
- package/__tests__/publicWwwTest/cartella/sottocartella/provaEjs/testEjs.ejs +11 -0
- package/__tests__/publicWwwTest/cartella vuota con spazi nel nome /file con spazio nel nome .txt +1 -0
- package/__tests__/publicWwwTest/ile_vuoto.txt +0 -0
- package/__tests__/publicWwwTest/index.html +11 -0
- package/__tests__/publicWwwTest/prova file .txt +2 -0
- package/__tests__/publicWwwTest/semplicetxt.txt +1 -0
- package/__tests__/publicWwwTest/test.txt +1 -0
- package/customTest/README.md +6 -0
- package/customTest/loadConfig.util.js +41 -0
- package/customTest/serversToLoad.util.js +93 -0
- package/{index.js → index.cjs} +3 -2
- package/index.mjs +9 -0
- package/noteExports.md +148 -0
- package/package.json +15 -7
- package/index.test.js +0 -63
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Attach by Process ID",
|
|
9
|
+
"processId": "${command:PickProcess}",
|
|
10
|
+
"request": "attach",
|
|
11
|
+
"skipFiles": [
|
|
12
|
+
"<node_internals>/**"
|
|
13
|
+
],
|
|
14
|
+
"type": "node"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "node",
|
|
18
|
+
"request": "launch",
|
|
19
|
+
"name": "Launch Program",
|
|
20
|
+
"skipFiles": [
|
|
21
|
+
"<node_internals>/**"
|
|
22
|
+
],
|
|
23
|
+
"program": "${workspaceFolder}/index.cjs"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Attach by Process ID",
|
|
6
|
+
"processId": "${command:PickProcess}",
|
|
7
|
+
"request": "attach",
|
|
8
|
+
"skipFiles": [
|
|
9
|
+
"<node_internals>/**"
|
|
10
|
+
],
|
|
11
|
+
"type": "node"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"type": "node",
|
|
15
|
+
"request": "launch",
|
|
16
|
+
"name": "Launch Program",
|
|
17
|
+
"skipFiles": [
|
|
18
|
+
"<node_internals>/**"
|
|
19
|
+
],
|
|
20
|
+
"program": "${workspaceFolder}/index.cjs"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Debug Jest Tests",
|
|
24
|
+
"type": "node",
|
|
25
|
+
"request": "launch",
|
|
26
|
+
"runtimeExecutable": "node",
|
|
27
|
+
"runtimeArgs": [
|
|
28
|
+
"--inspect-brk",
|
|
29
|
+
"${workspaceFolder}/node_modules/jest/bin/jest.js",
|
|
30
|
+
"--runInBand"
|
|
31
|
+
],
|
|
32
|
+
"port": 9229,
|
|
33
|
+
"console": "integratedTerminal",
|
|
34
|
+
"internalConsoleOptions": "neverOpen",
|
|
35
|
+
"skipFiles": [
|
|
36
|
+
"<node_internals>/**"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
|
package/README.md
CHANGED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// ATTENZIONE QUESTO TEST NON COPRE SE NEL VISUALIZARE IL CONTENUTO DELLE CARTELLE TUTTO VIENE MOSTRATO COME SI DEVE
|
|
4
|
+
// ATTENZIONE MANCA IL TEST PER TESTARE I MOTORI DI RENDERING COME .ejs
|
|
5
|
+
// ERRORI NOTI:
|
|
6
|
+
// 1)QUANDO UNA RISORSA NON VIENE TROVATA IN UNA CARTELLO LO STATO NON È SETTATO SU 404 MA SU 200
|
|
7
|
+
// 2)IL PERCORSO RISERVATO UNZIONA SOLO SE NON VI SONO SPAZI NEL NOME
|
|
8
|
+
// FURURES:
|
|
9
|
+
// A) IMPLEMENTARE UNA ARRAY DI FILE INDEX ,MAGAI DANDO LA POSSIBILITA DI NON DISTINGURE FRA MINUSCOLE EMAIUSCOLE
|
|
10
|
+
//
|
|
11
|
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const supertest = require('supertest');
|
|
15
|
+
const koaClassicServer = require('../index.cjs');
|
|
16
|
+
const Koa = require('koa');
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const mime = require('mime-types'); //serve alla funzione getFilesRecursivelySync();
|
|
20
|
+
//const {configurations} = require('../customTest/serversToLoad.util'); --> inutile questo serve solo per testari manualmente
|
|
21
|
+
|
|
22
|
+
const rootDir = path.join(__dirname, 'publicWwwTest');
|
|
23
|
+
|
|
24
|
+
// Legge tutti i file ricorsivamente e li memorizza in un array
|
|
25
|
+
const filesAndDirArray = getFilesRecursivelySync(rootDir);
|
|
26
|
+
|
|
27
|
+
// Visualizza l'array risultante
|
|
28
|
+
//console.log(filesAndDirArray);
|
|
29
|
+
|
|
30
|
+
//START option0
|
|
31
|
+
|
|
32
|
+
// Configuriamo le opzioni per koa-classic-server
|
|
33
|
+
const options0 = {
|
|
34
|
+
urlPrefix: '/public', // Il prefisso URL che il middleware dovrà intercettare
|
|
35
|
+
method: ['GET'],// I metodi HTTP ammessi (default 'GET')
|
|
36
|
+
showDirContents: true,// Se mostrare il contenuto della directory in caso di richiesta ad una cartella
|
|
37
|
+
//index: 'index.html', // Nome del file index da cercare all'interno di una directory (se presente)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
describe(` koaClassicServer options0: ${JSON.stringify(options0)}`, () => {
|
|
41
|
+
let app;
|
|
42
|
+
let server;
|
|
43
|
+
|
|
44
|
+
// Avvia il server prima di eseguire i test
|
|
45
|
+
beforeAll(() => {
|
|
46
|
+
app = new Koa();
|
|
47
|
+
app.use(koaClassicServer(rootDir, options0)); // Monta il middleware
|
|
48
|
+
server = app.listen();// Avvia il server in modo che Supertest possa inviare richieste HTTP
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('controllo che se chiamo un percorso che non esiste mi venga restituito l\'errore apropiato ', async () => {
|
|
52
|
+
// Effettua una richiesta GET sull'endpoint configurato (il prefisso)
|
|
53
|
+
const res = await supertest(server).get('/public/percorso_di_una_cartella_o_file_che_non_esiste_fbrojngbornbo/gbrtbbbrbr/tbrbr/rtbrtbrt');
|
|
54
|
+
expect(res.status).toBe(200);
|
|
55
|
+
expect(res.type).toMatch(/text\/html/);// type sta per mimetype .... restituisce text/plain anche se dovrebbe essere text/html
|
|
56
|
+
expect(res.text.replace(/\s/g, '')).toBe(requestedUrlNotFound().replace(/\s/g, '')); //.replace(/\s/g, '') --> rimuoce gli spazi bianchi e le tabulazioni , il server agiunge degli spazi all'inizio facendo fallire il controllo
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('controllo che se l\'indirizzo non ricade nel urlPrefix allora debba essere passato al midlware successivo e se non c\'e allora errore 404 not founf', async () => {
|
|
60
|
+
// Effettua una richiesta GET sull'endpoint configurato (il prefisso)
|
|
61
|
+
const res = await supertest(server).get('/percorso al di fuori di url prefix public/gbrtbbbrbr/tbrbr/rtbrtbrt');
|
|
62
|
+
expect(res.status).toBe(404);
|
|
63
|
+
expect(res.type).toMatch("text/plain");// type sta per mimetype .... restituisce text/plain anche se dovrebbe essere text/html
|
|
64
|
+
expect(res.text.replace(/\s/g, '')).toBe("Not Found".replace(/\s/g, '')); //.replace(/\s/g, '') --> rimuoce gli spazi bianchi e le tabulazioni , il server agiunge degli spazi all'inizio facendo fallire il controllo
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
// queste rige generaranno test per ogni ile presente nella cartella di test
|
|
69
|
+
const testFnCallbacks = testAllPathByFileList(filesAndDirArray, () => server, options0);//Genera l'array di callback per i test
|
|
70
|
+
testFnCallbacks.forEach(cb => cb());// Esegui ogni callback per registrare il test nello scope del describe
|
|
71
|
+
|
|
72
|
+
afterAll(() => {// Chiude il server dopo aver completato tutti i test
|
|
73
|
+
server.close();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
//END option0
|
|
78
|
+
|
|
79
|
+
//START option1
|
|
80
|
+
const options1 = {
|
|
81
|
+
method: ['GET'],
|
|
82
|
+
showDirContents: true,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
describe(` koaClassicServer options1: ${JSON.stringify(options1)}`, () => {
|
|
86
|
+
let app;
|
|
87
|
+
let server;
|
|
88
|
+
|
|
89
|
+
// Avvia il server prima di eseguire i test
|
|
90
|
+
beforeAll(() => {
|
|
91
|
+
app = new Koa();
|
|
92
|
+
app.use(koaClassicServer(rootDir, options1)); // Monta il middleware
|
|
93
|
+
server = app.listen();// Avvia il server in modo che Supertest possa inviare richieste HTTP
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('controllo che se chiamo un percorso che non esiste mi venga restituito l\'errore apropiato [ANCHE SENZA URL PREFIX] ', async () => {
|
|
97
|
+
// Effettua una richiesta GET sull'endpoint configurato (il prefisso)
|
|
98
|
+
const res = await supertest(server).get('/BTBg h gh /percorso_di_una_cartella_o_file_che_non_esiste_fbrojngbornbo/gbrtbbbrbr/tbrbr/rtbrtbrt');
|
|
99
|
+
expect(res.status).toBe(200);
|
|
100
|
+
expect(res.type).toMatch(/text\/html/);// type sta per mimetype .... restituisce text/plain anche se dovrebbe essere text/html
|
|
101
|
+
expect(res.text.replace(/\s/g, '')).toBe(requestedUrlNotFound().replace(/\s/g, '')); //.replace(/\s/g, '') --> rimuoce gli spazi bianchi e le tabulazioni , il server agiunge degli spazi all'inizio facendo fallire il controllo
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const testFnCallbacks = testAllPathByFileList(filesAndDirArray, () => server, options1);//Genera l'array di callback per i test
|
|
105
|
+
testFnCallbacks.forEach(cb => cb());// Esegui ogni callback per registrare il test nello scope del describe
|
|
106
|
+
|
|
107
|
+
afterAll(() => {// Chiude il server dopo aver completato tutti i test
|
|
108
|
+
server.close();
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
//END option1
|
|
113
|
+
|
|
114
|
+
//STASRT option2
|
|
115
|
+
const options2 = {
|
|
116
|
+
method: ['GET'],
|
|
117
|
+
showDirContents: false,
|
|
118
|
+
index: 'index.html',
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
describe(` koaClassicServer options2: ${JSON.stringify(options2)}`, () => {
|
|
122
|
+
let app;
|
|
123
|
+
let server;
|
|
124
|
+
|
|
125
|
+
// Avvia il server prima di eseguire i test
|
|
126
|
+
beforeAll(() => {
|
|
127
|
+
app = new Koa();
|
|
128
|
+
app.use(koaClassicServer(rootDir, options2)); // Monta il middleware
|
|
129
|
+
server = app.listen();// Avvia il server in modo che Supertest possa inviare richieste HTTP
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const testFnCallbacks = testAllPathByFileList(filesAndDirArray, () => server, options2);//Genera l'array di callback per i test
|
|
133
|
+
testFnCallbacks.forEach(cb => cb());// Esegui ogni callback per registrare il test nello scope del describe
|
|
134
|
+
|
|
135
|
+
afterAll(() => {// Chiude il server dopo aver completato tutti i test
|
|
136
|
+
server.close();
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
//END option2
|
|
140
|
+
|
|
141
|
+
//STASRT option3
|
|
142
|
+
const options3 = {
|
|
143
|
+
method: ['GET'],
|
|
144
|
+
showDirContents: false,
|
|
145
|
+
urlsReserved : Array('/percorso_riservato', '/percorso riservato con spazi')
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
describe(` koaClassicServer options2: ${JSON.stringify(options2)}`, () => {
|
|
149
|
+
let app;
|
|
150
|
+
let server;
|
|
151
|
+
|
|
152
|
+
// Avvia il server prima di eseguire i test
|
|
153
|
+
beforeAll(() => {
|
|
154
|
+
app = new Koa();
|
|
155
|
+
app.use(koaClassicServer(rootDir, options3)); // Monta il middleware
|
|
156
|
+
server = app.listen();// Avvia il server in modo che Supertest possa inviare richieste HTTP
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('controllo che se l\'indirizzo ricate di un percorso riservato allora venga passato il tutto al midlware successivo e in questo caso errore not ound', async () => {
|
|
160
|
+
// Effettua una richiesta GET sull'endpoint configurato (il prefisso)
|
|
161
|
+
const res = await supertest(server).get('/percorso_riservato/ciao.txt');
|
|
162
|
+
expect(res.status).toBe(404);
|
|
163
|
+
expect(res.type).toMatch("text/plain");// type sta per mimetype .... restituisce text/plain anche se dovrebbe essere text/html
|
|
164
|
+
expect(res.text.replace(/\s/g, '')).toBe("Not Found".replace(/\s/g, '')); //.replace(/\s/g, '') --> rimuoce gli spazi bianchi e le tabulazioni , il server agiunge degli spazi all'inizio facendo fallire il controllo
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
/* test('lo stesso del precedente ma questa volta il percorso riservato con spazi', async () => {
|
|
168
|
+
// Effettua una richiesta GET sull'endpoint configurato (il prefisso)
|
|
169
|
+
const res = await supertest(server).get('/percorso riservato con spazi/ciao.txt');
|
|
170
|
+
expect(res.status).toBe(404);
|
|
171
|
+
expect(res.type).toMatch("text/plain");// type sta per mimetype .... restituisce text/plain anche se dovrebbe essere text/html
|
|
172
|
+
expect(res.text.replace(/\s/g, '')).toBe("Not Found".replace(/\s/g, '')); //.replace(/\s/g, '') --> rimuoce gli spazi bianchi e le tabulazioni , il server agiunge degli spazi all'inizio facendo fallire il controllo
|
|
173
|
+
}); */
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
const testFnCallbacks = testAllPathByFileList(filesAndDirArray, () => server, options2);//Genera l'array di callback per i test
|
|
177
|
+
testFnCallbacks.forEach(cb => cb());// Esegui ogni callback per registrare il test nello scope del describe
|
|
178
|
+
|
|
179
|
+
afterAll(() => {// Chiude il server dopo aver completato tutti i test
|
|
180
|
+
server.close();
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
//END option3
|
|
184
|
+
|
|
185
|
+
/* const options0 = {
|
|
186
|
+
// Il prefisso URL che il middleware dovrà intercettare
|
|
187
|
+
urlPrefix: '/public',
|
|
188
|
+
// I metodi HTTP ammessi (default 'GET')
|
|
189
|
+
method: ['GET'],
|
|
190
|
+
// Se mostrare il contenuto della directory in caso di richiesta ad una cartella
|
|
191
|
+
showDirContents: true,
|
|
192
|
+
// Nome del file index da cercare all'interno di una directory (se presente)
|
|
193
|
+
//index: 'index.html',
|
|
194
|
+
}; */
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
// questa funzione serve per leggere ricorsivamente il contenuto di una cartella in modo da leggere il contenuto oferto via __tests__/publicWwwTest e confrontarlo con quello via http
|
|
200
|
+
//in linux anhe le directory sono file quindi mi salvo :)
|
|
201
|
+
function getFilesRecursivelySync(dir) {
|
|
202
|
+
let results = [];
|
|
203
|
+
// Leggiamo il contenuto della directory, ottenendo anche informazioni sui file e le cartelle
|
|
204
|
+
const list = fs.readdirSync(dir, { withFileTypes: true });
|
|
205
|
+
|
|
206
|
+
list.forEach((entry) => {
|
|
207
|
+
const fullPath = path.join(dir, entry.name);
|
|
208
|
+
entry.fullPath = fullPath;
|
|
209
|
+
if (entry.isDirectory()) {
|
|
210
|
+
// Se l'entry è una cartella, la elaboriamo ricorsivamente
|
|
211
|
+
entry.type = 'directory';
|
|
212
|
+
results.push(entry);// inserisco anche la directory stessa nell'elenco
|
|
213
|
+
results = results.concat(getFilesRecursivelySync(fullPath));
|
|
214
|
+
} else if (entry.isFile()) {
|
|
215
|
+
// Se l'entry è un file, lo aggiungiamo all'array dei risultati
|
|
216
|
+
const mimeType = mime.lookup(entry.name) || 'false';//false --> mimetype non riconosciuto , cosi lo trasmette il server , da approfondire
|
|
217
|
+
entry.type = 'file';
|
|
218
|
+
entry.mimeType = mimeType;
|
|
219
|
+
results.push(entry);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
return results;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
//ATTENZIONE questa funzione è esattamente identicaa a quella contenuta nel file index.cjs serve per confrontarla e vedere se il risultato combacia
|
|
227
|
+
function requestedUrlNotFound() {
|
|
228
|
+
return `
|
|
229
|
+
<!DOCTYPE html>
|
|
230
|
+
<html>
|
|
231
|
+
<head>
|
|
232
|
+
<meta charset="UTF-8">
|
|
233
|
+
<meta http-equiv="X-UA-Compatible">
|
|
234
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
235
|
+
<title>URL not found</title>
|
|
236
|
+
</head>
|
|
237
|
+
<body>
|
|
238
|
+
<h1>Not Found</h1>
|
|
239
|
+
|
|
240
|
+
<h3>The requested URL was not found on this server.</h3>
|
|
241
|
+
|
|
242
|
+
</body>
|
|
243
|
+
</html>
|
|
244
|
+
`;
|
|
245
|
+
} // function requestedUrlNotFound(){
|
|
246
|
+
|
|
247
|
+
//ATENZIONE per questa funzione guardare la descrizione sotto : per funzionare deve evvere chiamata nel seguente modo :
|
|
248
|
+
// const testFnCallbacks = testAllPathByFileList(filesAndDirArray, () => server, options0);//Genera l'array di callback per i test
|
|
249
|
+
// testFnCallbacks.forEach(cb => cb());// Esegui ogni callback per registrare il test nello scope del describe
|
|
250
|
+
|
|
251
|
+
function testAllPathByFileList(filesAndDirArray, getServer, options) {
|
|
252
|
+
return filesAndDirArray.map((entry, index) => {
|
|
253
|
+
const relativePath = path.relative(rootDir, entry.fullPath);
|
|
254
|
+
// Restituisci una funzione che, se chiamata, definisce un test.
|
|
255
|
+
return () => {
|
|
256
|
+
test(
|
|
257
|
+
`testo l'elemento ${index} (type: ${entry.type}, name: ${entry.name}) con percorso: ${relativePath}`,
|
|
258
|
+
async () => {
|
|
259
|
+
const server = getServer(); // Usa il getter per ottenere il server al momento dell'esecuzione
|
|
260
|
+
const url = path.join(options.urlPrefix || '/', relativePath);
|
|
261
|
+
const res = await supertest(server).get(url);
|
|
262
|
+
expect(res.status).toBe(200);
|
|
263
|
+
// Se l'entry è un file, controlla il contenuto e il MIME type
|
|
264
|
+
if (entry.type === 'file') {
|
|
265
|
+
const content = fs.readFileSync(entry.fullPath, 'utf8');
|
|
266
|
+
expect(res.type).toBe(entry.mimeType);
|
|
267
|
+
expect(res.text).toBe(content);
|
|
268
|
+
} else {//è una directory
|
|
269
|
+
expect(res.type).toBe('text/html');
|
|
270
|
+
expect(res.text).toContain('<!DOCTYPE html>');
|
|
271
|
+
if( options.showDirContents === false ){
|
|
272
|
+
expect(res.text.replace(/\s/g, '')).toBe(requestedUrlNotFound().replace(/\s/g, '')); //.replace(/\s/g, '') --> rimuoce gli spazi bianchi e le tabulazioni , il server agiunge degli spazi all'inizio facendo fallire il controllo
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
};
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* ATTENZIONE QUESTA FUNZIONE [function testAllPathByFileList] È FATTA IN MANIERA STRANA PER AVER RISOLTO IL PROBLEMA DOPO LUNGA DISCUSSIONE CON CHATGPT
|
|
282
|
+
|
|
283
|
+
Spiegazione
|
|
284
|
+
|
|
285
|
+
Incapsulamento:
|
|
286
|
+
In testAllPathByFileList usiamo map per creare un array in cui ogni elemento è una funzione (callback) che, se invocata, definisce un test usando test().
|
|
287
|
+
Così facendo, non eseguiamo subito test(), ma ne restituiamo la definizione da chiamare in seguito.
|
|
288
|
+
|
|
289
|
+
Uso del Getter:
|
|
290
|
+
Passando () => server come secondo argomento, assicuriamo che al momento dell'esecuzione di ogni callback il server sia già inizializzato.
|
|
291
|
+
|
|
292
|
+
Registrazione dei Test:
|
|
293
|
+
Quando chiamiamo testFnCallbacks.forEach(cb => cb()); nello scope del blocco describe, ogni callback viene invocata e i test vengono definiti correttamente per Jest.
|
|
294
|
+
|
|
295
|
+
Idea di Base
|
|
296
|
+
|
|
297
|
+
Genera un array di callback:
|
|
298
|
+
Crea una funzione che, dato l'array dei file e directory (o dati dinamici), restituisca un array di funzioni. Ogni funzione (callback) quando invocata definirà un test tramite test() ed eseguirà le relative asserzioni con expect().
|
|
299
|
+
|
|
300
|
+
Esegui le callback nello scope del describe:
|
|
301
|
+
All'interno del blocco describe (dove Jest raccoglie i test) iteri sull'array di callback e invochi ciascuna, in modo che i test vengano registrati correttamente. In questo modo, l'errore "Your test suite must contain at least one test" non si verificherà perché i test saranno già stati definiti nello scope globale del describe
|
|
302
|
+
|
|
303
|
+
//END CONSIDERAZIONE IMPORTANTE
|
|
304
|
+
*/
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
/*
|
|
308
|
+
OLD//
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
function testAllPathByFileList(filesAndDirArray, getServer, options) {
|
|
312
|
+
return filesAndDirArray.map((entry, index) => {
|
|
313
|
+
const relativePath = path.relative(rootDir, entry.fullPath);
|
|
314
|
+
// Restituisci una funzione che, se chiamata, definisce un test.
|
|
315
|
+
return () => {
|
|
316
|
+
test(
|
|
317
|
+
`testo l'elemento ${index} (type: ${entry.type}, name: ${entry.name}) con percorso: ${relativePath}`,
|
|
318
|
+
async () => {
|
|
319
|
+
const server = getServer(); // Usa il getter per ottenere il server al momento dell'esecuzione
|
|
320
|
+
const url = path.join(options.urlPrefix || '/', relativePath);
|
|
321
|
+
const res = await supertest(server).get(url);
|
|
322
|
+
expect(res.status).toBe(200);
|
|
323
|
+
// Se l'entry è un file, controlla il contenuto e il MIME type
|
|
324
|
+
if (entry.type === 'file') {
|
|
325
|
+
const content = fs.readFileSync(entry.fullPath, 'utf8');
|
|
326
|
+
expect(res.type).toBe(entry.mimeType);
|
|
327
|
+
expect(res.text).toBe(content);
|
|
328
|
+
} else {
|
|
329
|
+
expect(res.type).toBe('text/html');
|
|
330
|
+
expect(res.text).toContain('<!DOCTYPE html>');
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
);
|
|
334
|
+
};
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
*/
|
package/__tests__/publicWwwTest/cartella vuota con spazi nel nome /file con spazio nel nome .txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
hello world
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
hello world
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
hello world
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
## questi ile servono per testare manualmente le vari conigurazioni
|
|
2
|
+
|
|
3
|
+
# digitando :
|
|
4
|
+
### npm run loadConfig
|
|
5
|
+
# potrai sceglire quale configurazione usare per caricare il server e testatarlo la directory puntata è la stessa contenuta nella directory __tests__
|
|
6
|
+
# cioè __tests__/publicWwwTest
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// questo script permetterà di scegliere la conigurazione con cui lanciare koa-classic-server al ine di essere testato
|
|
2
|
+
// ci sarà una lista interattive di configurazione fra cui scegliere :
|
|
3
|
+
|
|
4
|
+
// chooseCon.js
|
|
5
|
+
const { createServer, configurations } = require('../customTest/serversToLoad.util');
|
|
6
|
+
const inquirer = require('inquirer').default;
|
|
7
|
+
|
|
8
|
+
async function chooseConfiguration() {
|
|
9
|
+
// Costruiamo le scelte dall'array delle configurazioni
|
|
10
|
+
const choices = configurations.map(config => ({
|
|
11
|
+
name: `${config.name}: ${config.description}`,
|
|
12
|
+
value: config.name,
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
const answers = await inquirer.prompt([
|
|
16
|
+
{
|
|
17
|
+
type: 'list',
|
|
18
|
+
name: 'configName',
|
|
19
|
+
message: 'Seleziona la configurazione da visualizzare:',
|
|
20
|
+
choices: choices,
|
|
21
|
+
},
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
return answers.configName;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function main() {
|
|
28
|
+
const configName = await chooseConfiguration();
|
|
29
|
+
const app = createServer(configName);
|
|
30
|
+
const port = process.env.PORT || 3000;
|
|
31
|
+
|
|
32
|
+
app.listen(port, () => {
|
|
33
|
+
console.log(`Server avviato su http://localhost:${port} con configurazione "${configName}"`);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
main().catch(error => {
|
|
38
|
+
console.error('Errore durante l\'esecuzione:', error);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
});
|
|
41
|
+
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// quivi sarnno elencato in un array le varie possibili configurzioni di koaClassicServer in modo po sa poterle testare
|
|
2
|
+
|
|
3
|
+
// servers.js
|
|
4
|
+
const Koa = require('koa');
|
|
5
|
+
const koaClassicServer = require('../index.cjs');
|
|
6
|
+
const { join } = require('path');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Array (o raccolta) delle configurazioni disponibili.
|
|
10
|
+
* Aggiungendo nuovi oggetti qui potrai testare ulteriori configurazioni.
|
|
11
|
+
*/
|
|
12
|
+
rootDir = join(__dirname, '../' , '__tests__','publicWwwTest');
|
|
13
|
+
console.log( 'rootDir', rootDir);
|
|
14
|
+
const configurations = [
|
|
15
|
+
{
|
|
16
|
+
name: 'test generico',
|
|
17
|
+
description: ' urlPrefix: \',',
|
|
18
|
+
// Per i test, i file da servire sono quelli della cartella __tests__/publicWwwTest
|
|
19
|
+
rootDir: rootDir,
|
|
20
|
+
options: {
|
|
21
|
+
//urlPrefix: '/',
|
|
22
|
+
method: ['GET'],
|
|
23
|
+
showDirContents: true,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'test indicando l\'index file ',
|
|
28
|
+
description: "nelle urlPrefix: \'/public\', : //index: 'index.html',",
|
|
29
|
+
// In produzione potresti servire i file dalla cartella "public"
|
|
30
|
+
rootDir: rootDir,
|
|
31
|
+
options: {
|
|
32
|
+
urlPrefix: '/public',
|
|
33
|
+
method: ['GET'],
|
|
34
|
+
showDirContents: true,
|
|
35
|
+
index: 'index.html',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'test generico',
|
|
40
|
+
description: ' urlPrefix: \'/public\',',
|
|
41
|
+
// Per i test, i file da servire sono quelli della cartella __tests__/publicWwwTest
|
|
42
|
+
rootDir: rootDir,
|
|
43
|
+
options: {
|
|
44
|
+
urlPrefix: '/public',
|
|
45
|
+
method: ['GET'],
|
|
46
|
+
showDirContents: true,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'test con percorso riservato ',
|
|
51
|
+
description: "urlsReserved : Array('percorso_riservato/', 'percorso riservato con spazi')",
|
|
52
|
+
// Per i test, i file da servire sono quelli della cartella __tests__/publicWwwTest
|
|
53
|
+
rootDir: rootDir,
|
|
54
|
+
options: {
|
|
55
|
+
urlPrefix: '',
|
|
56
|
+
method: ['GET'],
|
|
57
|
+
showDirContents: true,
|
|
58
|
+
urlsReserved : Array('/percorso_riservato', '/percorso riservato con spazi')
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
// Puoi aggiungere ulteriori configurazioni qui
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Cerca e restituisce la configurazione in base al nome.
|
|
66
|
+
* Se non viene trovata, restituisce la prima (default).
|
|
67
|
+
*
|
|
68
|
+
* @param {string} configName - Il nome della configurazione da usare.
|
|
69
|
+
* @returns {object} La configurazione trovata.
|
|
70
|
+
*/
|
|
71
|
+
function getConfig(configName) {
|
|
72
|
+
return configurations.find(config => config.name === configName) || configurations[0];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Crea un'istanza di Koa configurata in base alla configurazione scelta.
|
|
77
|
+
*
|
|
78
|
+
* @param {string} configName - Il nome della configurazione da utilizzare (default: 'default').
|
|
79
|
+
* @returns {Koa} L'istanza dell'applicazione Koa.
|
|
80
|
+
*/
|
|
81
|
+
function createServer( configName ) {
|
|
82
|
+
const config = getConfig(configName);
|
|
83
|
+
const app = new Koa();
|
|
84
|
+
console.log('config.options', config.options, 'config.rootDir' , config.rootDir);
|
|
85
|
+
app.use(koaClassicServer(config.rootDir, config.options));
|
|
86
|
+
return app;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = {
|
|
90
|
+
configurations,
|
|
91
|
+
getConfig,
|
|
92
|
+
createServer,
|
|
93
|
+
};
|
package/{index.js → index.cjs}
RENAMED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
const { URL } = require("url");
|
|
2
3
|
const fs = require("fs");
|
|
3
4
|
const mime = require("mime-types");
|
|
@@ -6,7 +7,7 @@ const { error } = require("console");
|
|
|
6
7
|
|
|
7
8
|
// è la funzione che avierà il server rootDir = cartella dei file statici, UrlPrefix = prefisso del path dove guardare es localhost:3000\views
|
|
8
9
|
// questa funzione deve restituire un midlware
|
|
9
|
-
module.exports =
|
|
10
|
+
module.exports = function koaClassicServer(
|
|
10
11
|
rootDir,
|
|
11
12
|
opts = {}
|
|
12
13
|
|
|
@@ -270,4 +271,4 @@ module.exports = function koaClassicServer(
|
|
|
270
271
|
return toReturn;
|
|
271
272
|
} // function show_dir( dir ){
|
|
272
273
|
}; // return (ctx, next) => {
|
|
273
|
-
};
|
|
274
|
+
};
|
package/index.mjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
// index.js (ESM)
|
|
3
|
+
// index.esm.js
|
|
4
|
+
|
|
5
|
+
// Importa il modulo principale (anche se è scritto in CommonJS)
|
|
6
|
+
// Node gestirà l'interoperabilità e restituirà il valore presente in module.exports.
|
|
7
|
+
import koaClassicServer from './index.cjs';
|
|
8
|
+
export default koaClassicServer;
|
|
9
|
+
|
package/noteExports.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
|
|
2
|
+
## versione corta
|
|
3
|
+
Utilizzare Conditional Exports in package.json
|
|
4
|
+
|
|
5
|
+
Con Node.js (versione 12.20+, 14+ o successive) puoi sfruttare il campo exports nel file package.json per indicare percorsi diversi a seconda del metodo di importazione:
|
|
6
|
+
|
|
7
|
+
Esempio di package.json:
|
|
8
|
+
|
|
9
|
+
{
|
|
10
|
+
"name": "mia-libreria",
|
|
11
|
+
"version": "1.0.0",
|
|
12
|
+
"main": "./index.cjs", // entry point per CommonJS
|
|
13
|
+
"exports": {
|
|
14
|
+
"import": "./index.js", // entry point per ESM
|
|
15
|
+
"require": "./index.cjs" // entry point per CommonJS
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
Con questa configurazione, puoi scrivere la logica principale in un file (ad esempio lib/koaClassicServer.js) e poi creare due entry point:
|
|
20
|
+
|
|
21
|
+
Per ESM (index.js)
|
|
22
|
+
|
|
23
|
+
// index.js
|
|
24
|
+
export { default } from './lib/koaClassicServer.js';
|
|
25
|
+
|
|
26
|
+
Per CommonJS (index.cjs)
|
|
27
|
+
|
|
28
|
+
// index.cjs
|
|
29
|
+
module.exports = require('./lib/koaClassicServer.js').default;
|
|
30
|
+
|
|
31
|
+
In questo modo gli utenti potranno importare il modulo in ESM:
|
|
32
|
+
|
|
33
|
+
import koaClassicServer from "mia-libreria";
|
|
34
|
+
|
|
35
|
+
oppure in CommonJS:
|
|
36
|
+
|
|
37
|
+
const koaClassicServer = require("mia-libreria");
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## versione lunga
|
|
42
|
+
|
|
43
|
+
l'uso dei Conditional Exports nel file package.json, è un meccanismo introdotto nelle versioni moderne di Node.js (dalla 12.20 in poi, con supporto stabile a partire dalla 14) che ti permette di specificare percorsi di ingresso diversi a seconda di come il modulo viene importato:
|
|
44
|
+
|
|
45
|
+
ESM (quando usi import ... from 'modulo')
|
|
46
|
+
CommonJS (quando usi require('modulo'))
|
|
47
|
+
|
|
48
|
+
Questo approccio ti consente di mantenere una singola distribuzione del tuo modulo, fornendo però due "versioni" compatibili in base al sistema di moduli utilizzato dall'ambiente dell'utente.
|
|
49
|
+
Struttura di Base del package.json
|
|
50
|
+
|
|
51
|
+
Ecco un esempio di configurazione:
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
"name": "mia-libreria",
|
|
55
|
+
"version": "1.0.0",
|
|
56
|
+
"main": "./index.cjs",
|
|
57
|
+
"exports": {
|
|
58
|
+
"import": "./index.js",
|
|
59
|
+
"require": "./index.cjs"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
Spiegazione dei campi principali:
|
|
64
|
+
|
|
65
|
+
main:
|
|
66
|
+
Tradizionalmente questo campo specifica il file di ingresso per i moduli CommonJS. Anche se non è obbligatorio se usi il campo exports, è buona pratica inserirlo per mantenere la compatibilità con strumenti o ambienti che non supportano ancora i conditional exports.
|
|
67
|
+
|
|
68
|
+
exports:
|
|
69
|
+
Questo campo permette di definire in modo esplicito quali file (o percorsi) devono essere utilizzati quando il modulo viene importato, in base al contesto. In questo esempio, abbiamo due condizioni:
|
|
70
|
+
"import": "./index.js": Quando il modulo viene importato in un contesto ECMAScript (ESM), Node.js userà il file index.js.
|
|
71
|
+
"require": "./index.cjs": Quando il modulo viene importato tramite CommonJS (require()), verrà usato il file index.cjs.
|
|
72
|
+
|
|
73
|
+
Strutturare il Modulo per Supportare Entrambi gli Stili
|
|
74
|
+
|
|
75
|
+
Supponiamo di avere una struttura simile a questa:
|
|
76
|
+
|
|
77
|
+
mia-libreria/
|
|
78
|
+
├── lib/
|
|
79
|
+
│ └── koaClassicServer.js
|
|
80
|
+
├── index.js // Entry point per ESM
|
|
81
|
+
├── index.cjs // Entry point per CommonJS
|
|
82
|
+
└── package.json
|
|
83
|
+
|
|
84
|
+
1. File lib/koaClassicServer.js (la logica principale)
|
|
85
|
+
|
|
86
|
+
Scrivi qui il tuo modulo in sintassi moderna (ESM). Ad esempio:
|
|
87
|
+
|
|
88
|
+
// lib/koaClassicServer.js
|
|
89
|
+
export default function koaClassicServer(rootDir, opts = {}) {
|
|
90
|
+
// ... implementazione del middleware
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
2. File index.js (entry point per ESM)
|
|
94
|
+
|
|
95
|
+
Questo file importa il modulo principale e lo re-esporta:
|
|
96
|
+
|
|
97
|
+
// index.js (ESM)
|
|
98
|
+
export { default } from './lib/koaClassicServer.js';
|
|
99
|
+
|
|
100
|
+
3. File index.cjs (entry point per CommonJS)
|
|
101
|
+
|
|
102
|
+
In questo file, importa il modulo in modo compatibile con CommonJS e lo esporta:
|
|
103
|
+
|
|
104
|
+
// index.cjs (CommonJS)
|
|
105
|
+
module.exports = require('./lib/koaClassicServer.js').default;
|
|
106
|
+
|
|
107
|
+
Come Funziona in Pratica
|
|
108
|
+
|
|
109
|
+
Utilizzando ESM:
|
|
110
|
+
|
|
111
|
+
Se un utente importa il modulo in un file ESM:
|
|
112
|
+
|
|
113
|
+
import koaClassicServer from 'mia-libreria';
|
|
114
|
+
|
|
115
|
+
Node.js guarderà il campo exports nel package.json e, vedendo la chiave "import", caricherà il file index.js che esporta il modulo definito in koaClassicServer.js.
|
|
116
|
+
|
|
117
|
+
Utilizzando CommonJS:
|
|
118
|
+
|
|
119
|
+
Se invece un utente importa il modulo in un file CommonJS:
|
|
120
|
+
|
|
121
|
+
const koaClassicServer = require('mia-libreria');
|
|
122
|
+
|
|
123
|
+
Node.js, vedendo la chiave "require" nel campo exports, caricherà il file index.cjs che esporta correttamente il modulo.
|
|
124
|
+
|
|
125
|
+
Vantaggi di Questo Approccio
|
|
126
|
+
|
|
127
|
+
Compatibilità Doppia:
|
|
128
|
+
Permette agli utenti di utilizzare il modulo indipendentemente dal sistema di moduli scelto.
|
|
129
|
+
|
|
130
|
+
Manutenzione Centralizzata:
|
|
131
|
+
La logica principale è scritta in un solo file (koaClassicServer.js), riducendo la duplicazione del codice.
|
|
132
|
+
|
|
133
|
+
Supporto ai Nuovi Standard:
|
|
134
|
+
Utilizzando i conditional exports, ti prepari per il futuro, dove i moduli ESM diventeranno lo standard principale.
|
|
135
|
+
|
|
136
|
+
Controllo Esplicito dell'Interfaccia:
|
|
137
|
+
Il campo exports consente di definire in modo esplicito e sicuro quali file devono essere esposti agli utenti del modulo, evitando accessi accidentali a file interni non destinati alla pubblicazione.
|
|
138
|
+
|
|
139
|
+
Considerazioni Finali
|
|
140
|
+
|
|
141
|
+
Versione di Node.js:
|
|
142
|
+
Assicurati che i tuoi utenti utilizzino una versione di Node.js che supporti i conditional exports (Node 14+ è consigliato).
|
|
143
|
+
|
|
144
|
+
Compatibilità con Strumenti di Build:
|
|
145
|
+
Se utilizzi strumenti di build o bundler, verifica che siano configurati per gestire correttamente il campo exports.
|
|
146
|
+
|
|
147
|
+
Utilizzando i Conditional Exports nel package.json potrai distribuire il tuo modulo in modo elegante e compatibile con entrambi gli stili di moduli, offrendo un'esperienza di utilizzo migliore agli sviluppatori che lo importeranno.
|
|
148
|
+
|
package/package.json
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koa-classic-server",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "a server in style Apache 2",
|
|
5
|
-
"main": "index.
|
|
5
|
+
"main": "index.cjs",
|
|
6
|
+
"exports": {
|
|
7
|
+
"import": "./index.mjs",
|
|
8
|
+
"require": "./index.cjs"
|
|
9
|
+
},
|
|
6
10
|
"scripts": {
|
|
7
|
-
"start": "node index.
|
|
8
|
-
"test": "jest"
|
|
11
|
+
"start": "node index.cjs",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"loadConfig": "node ./customTest/loadConfig.util.js"
|
|
9
14
|
},
|
|
10
15
|
"keywords": [
|
|
11
16
|
"file",
|
|
@@ -14,8 +19,11 @@
|
|
|
14
19
|
"author": "Italo Paesano",
|
|
15
20
|
"license": "MIT",
|
|
16
21
|
"dependencies": {
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
"koa": "^2.13.4"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"inquirer": "^12.4.1",
|
|
26
|
+
"jest": "^29.7.0",
|
|
27
|
+
"supertest": "^7.0.0"
|
|
20
28
|
}
|
|
21
29
|
}
|
package/index.test.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
//const request = require('supertest');
|
|
2
|
-
//const Koa = require('koa');
|
|
3
|
-
const classicServer = require('koa-classic-server');
|
|
4
|
-
|
|
5
|
-
const testDir = __dirname + '/test' ;
|
|
6
|
-
|
|
7
|
-
const fakeApp = classicServer( testDir );
|
|
8
|
-
|
|
9
|
-
const fakeCtx = {
|
|
10
|
-
method: 'GET',
|
|
11
|
-
href: 'http://localhost:3000/', // da controllare
|
|
12
|
-
body: '',
|
|
13
|
-
response: {}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const fakeNext = () => {};
|
|
17
|
-
|
|
18
|
-
///console.log(fakeApp( fakeCtx, fakeNext));
|
|
19
|
-
|
|
20
|
-
test('prima prova', () => {
|
|
21
|
-
fakeApp( fakeCtx, fakeNext).then((result) => {
|
|
22
|
-
console.log('resuuultttttt',result);
|
|
23
|
-
expect( result ).not.toBe(3);
|
|
24
|
-
})//)).not.toBe(3);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
/* const app = new Koa();
|
|
28
|
-
app.use(classicServer( __dirname + '/test'));
|
|
29
|
-
|
|
30
|
-
const server = app.listen();
|
|
31
|
-
|
|
32
|
-
request(server)
|
|
33
|
-
.get('/')
|
|
34
|
-
.expect('Content-Type', 'text/html')
|
|
35
|
-
//.expect('Content-Length', '15')
|
|
36
|
-
.expect(200)
|
|
37
|
-
.end(function(err, res) {
|
|
38
|
-
if (err) throw err;
|
|
39
|
-
}); */
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
/* describe('koa-classic-server', () => {
|
|
44
|
-
let app;
|
|
45
|
-
|
|
46
|
-
beforeEach(() => {
|
|
47
|
-
app = new Koa();
|
|
48
|
-
app.use(classicServer());
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should return Hello World!', async () => {
|
|
52
|
-
const res = await request(app.callback()).get('/');
|
|
53
|
-
expect(res.status).toBe(200);
|
|
54
|
-
expect(res.text).toBe('Hello World!');
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should return 404 for invalid route', async () => {
|
|
58
|
-
const res = await request(app.callback()).get('/invalid');
|
|
59
|
-
expect(res.status).toBe(404);
|
|
60
|
-
expect(res.text).toBe('Not Found');
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
*/
|