@devquest/cli 1.1.2 → 1.1.5
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/dist/utils/tests/build-your-own-ai-framework.js +21 -24
- package/dist/utils/tests/build-your-own-compiler.js +6 -7
- package/dist/utils/tests/build-your-own-formatter.js +5 -6
- package/dist/utils/tests/build-your-own-git.js +17 -18
- package/dist/utils/tests/build-your-own-http-framework.js +21 -16
- package/dist/utils/tests/build-your-own-interpreter.js +16 -15
- package/dist/utils/tests/build-your-own-redis.js +26 -30
- package/dist/utils/tests/build-your-own-shell.js +26 -15
- package/dist/utils/tests/build-your-own-vercel.js +7 -8
- package/package.json +1 -1
|
@@ -15,15 +15,14 @@ function runStage(stageOrder, cwd) {
|
|
|
15
15
|
const code = `
|
|
16
16
|
let userApp: any;
|
|
17
17
|
try { userApp = require('./src/index'); }
|
|
18
|
-
catch(e
|
|
18
|
+
catch(e) { console.error('[!] Falha ao importar src/index.ts: ' + e.message); process.exit(1); }
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
function assert(condition, failMsg, expected, got) {
|
|
21
21
|
if (!condition) {
|
|
22
|
-
console.error('
|
|
23
|
-
console.error('📝 ' + failMsg);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
console.error('');
|
|
22
|
+
console.error('\n[FALHA DE ASSERÇÃO]\n');
|
|
23
|
+
console.error('📝 Resumo: ' + failMsg + '\n');
|
|
24
|
+
console.error('🎯 ESPERADO\n' + expected + '\n');
|
|
25
|
+
console.error('💥 RECEBIDO\n' + got + '\n');
|
|
27
26
|
process.exit(1);
|
|
28
27
|
}
|
|
29
28
|
}
|
|
@@ -63,7 +62,7 @@ function runStage(stageOrder, cwd) {
|
|
|
63
62
|
assert(result === 'DevQuest LLM Response', 'Retorno da função incorreto.', 'DevQuest LLM Response', result);
|
|
64
63
|
|
|
65
64
|
console.log('PASS');
|
|
66
|
-
} catch(e
|
|
65
|
+
} catch(e) {
|
|
67
66
|
console.error(e.message);
|
|
68
67
|
process.exit(1);
|
|
69
68
|
}
|
|
@@ -90,15 +89,14 @@ function runStage(stageOrder, cwd) {
|
|
|
90
89
|
const code = `
|
|
91
90
|
let userApp: any;
|
|
92
91
|
try { userApp = require('./src/index'); }
|
|
93
|
-
catch(e
|
|
92
|
+
catch(e) { console.error('[!] Erro de importação: ' + e.message); process.exit(1); }
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
function assert(condition, failMsg, expected, got) {
|
|
96
95
|
if (!condition) {
|
|
97
|
-
console.error('
|
|
98
|
-
console.error('📝 ' + failMsg);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
console.error('');
|
|
96
|
+
console.error('\n[FALHA DE ASSERÇÃO]\n');
|
|
97
|
+
console.error('📝 Resumo: ' + failMsg + '\n');
|
|
98
|
+
console.error('🎯 ESPERADO\n' + expected + '\n');
|
|
99
|
+
console.error('💥 RECEBIDO\n' + got + '\n');
|
|
102
100
|
process.exit(1);
|
|
103
101
|
}
|
|
104
102
|
}
|
|
@@ -112,7 +110,7 @@ function runStage(stageOrder, cwd) {
|
|
|
112
110
|
assert(typeof model.doGenerate === 'function', 'O adaptador instanciado via openai() deve ter o método doGenerate().', 'function', typeof model.doGenerate);
|
|
113
111
|
|
|
114
112
|
console.log('PASS');
|
|
115
|
-
} catch(e
|
|
113
|
+
} catch(e) {
|
|
116
114
|
console.error(e.message);
|
|
117
115
|
process.exit(1);
|
|
118
116
|
}
|
|
@@ -139,15 +137,14 @@ function runStage(stageOrder, cwd) {
|
|
|
139
137
|
const code = `
|
|
140
138
|
let userApp: any;
|
|
141
139
|
try { userApp = require('./src/index'); }
|
|
142
|
-
catch(e
|
|
140
|
+
catch(e) { console.error('[!] Erro de importação: ' + e.message); process.exit(1); }
|
|
143
141
|
|
|
144
|
-
|
|
142
|
+
function assert(condition, failMsg, expected, got) {
|
|
145
143
|
if (!condition) {
|
|
146
|
-
console.error('
|
|
147
|
-
console.error('📝 ' + failMsg);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
console.error('');
|
|
144
|
+
console.error('\n[FALHA DE ASSERÇÃO]\n');
|
|
145
|
+
console.error('📝 Resumo: ' + failMsg + '\n');
|
|
146
|
+
console.error('🎯 ESPERADO\n' + expected + '\n');
|
|
147
|
+
console.error('💥 RECEBIDO\n' + got + '\n');
|
|
151
148
|
process.exit(1);
|
|
152
149
|
}
|
|
153
150
|
}
|
|
@@ -180,7 +177,7 @@ function runStage(stageOrder, cwd) {
|
|
|
180
177
|
assert(result.finishReason === 'stop', 'Propriedade \\'finishReason\\' ausente ou incorreta no retorno.', 'stop', result.finishReason);
|
|
181
178
|
|
|
182
179
|
console.log('PASS');
|
|
183
|
-
} catch(e
|
|
180
|
+
} catch(e) {
|
|
184
181
|
console.error(e.message);
|
|
185
182
|
process.exit(1);
|
|
186
183
|
}
|
|
@@ -17,13 +17,12 @@ function runStage(stageOrder, cwd) {
|
|
|
17
17
|
const fs = require('fs');
|
|
18
18
|
const path = require('path');
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
function assert(condition, failMsg, expected, got) {
|
|
21
21
|
if (!condition) {
|
|
22
|
-
console.error('
|
|
23
|
-
console.error('📝 ' + failMsg);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
console.error('');
|
|
22
|
+
console.error('\n[FALHA DE ASSERÇÃO]\n');
|
|
23
|
+
console.error('📝 Resumo: ' + failMsg + '\n');
|
|
24
|
+
console.error('🎯 ESPERADO\n' + expected + '\n');
|
|
25
|
+
console.error('💥 RECEBIDO\n' + got + '\n');
|
|
27
26
|
process.exit(1);
|
|
28
27
|
}
|
|
29
28
|
}
|
|
@@ -41,7 +40,7 @@ function runStage(stageOrder, cwd) {
|
|
|
41
40
|
|
|
42
41
|
console.log('PASS');
|
|
43
42
|
if (fs.existsSync(testFile)) fs.unlinkSync(testFile);
|
|
44
|
-
} catch(e
|
|
43
|
+
} catch(e) {
|
|
45
44
|
console.error(e.stderr?.toString() || e.message);
|
|
46
45
|
process.exit(1);
|
|
47
46
|
}
|
|
@@ -36,12 +36,11 @@ async function testStage1(cwd) {
|
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
38
|
if (runValid.stdout.trim() !== sampleContent.trim()) {
|
|
39
|
-
console.
|
|
40
|
-
console.
|
|
41
|
-
console.
|
|
42
|
-
console.
|
|
43
|
-
console.log(chalk_1.default.
|
|
44
|
-
console.log(chalk_1.default.yellow(`\n💡 Dica: Verifique se você não está imprimindo mensagens de depuração ou espaços extras.`));
|
|
39
|
+
console.error('\n' + chalk_1.default.bgRed.white.bold(' ❌ FALHA DE ASSERÇÃO ') + '\n');
|
|
40
|
+
console.error(chalk_1.default.yellow('📝 Resumo: ') + 'O conteúdo impresso no stdout não coincide exatamente com o esperado.\n');
|
|
41
|
+
console.error(chalk_1.default.bgBlue.white.bold(' 🎯 ESPERADO ') + '\n' + chalk_1.default.blue(sampleContent) + '\n');
|
|
42
|
+
console.error(chalk_1.default.bgMagenta.white.bold(' 💥 RECEBIDO ') + '\n' + chalk_1.default.magenta(runValid.stdout) + '\n');
|
|
43
|
+
console.log(chalk_1.default.yellow(`💡 Dica: Verifique se você não está imprimindo mensagens de depuração ou espaços extras.`));
|
|
45
44
|
return false;
|
|
46
45
|
}
|
|
47
46
|
console.log(chalk_1.default.green(`✅ Conteúdo lido e impresso corretamente.`));
|
|
@@ -16,14 +16,13 @@ function runStage(stageOrder, cwd) {
|
|
|
16
16
|
const fs = require('fs');
|
|
17
17
|
const path = require('path');
|
|
18
18
|
const { execSync } = require('child_process');
|
|
19
|
-
|
|
20
|
-
function assert(condition
|
|
19
|
+
|
|
20
|
+
function assert(condition, failMsg, expected, got) {
|
|
21
21
|
if (!condition) {
|
|
22
|
-
console.error('
|
|
23
|
-
console.error('📝 ' + failMsg);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
console.error('');
|
|
22
|
+
console.error('\n[FALHA DE ASSERÇÃO]\n');
|
|
23
|
+
console.error('📝 Resumo: ' + failMsg + '\n');
|
|
24
|
+
console.error('🎯 ESPERADO\n' + expected + '\n');
|
|
25
|
+
console.error('💥 RECEBIDO\n' + got + '\n');
|
|
27
26
|
process.exit(1);
|
|
28
27
|
}
|
|
29
28
|
}
|
|
@@ -43,7 +42,7 @@ function runStage(stageOrder, cwd) {
|
|
|
43
42
|
|
|
44
43
|
console.log('PASS');
|
|
45
44
|
fs.rmSync(repoPath, { recursive: true, force: true });
|
|
46
|
-
} catch(e
|
|
45
|
+
} catch(e) {
|
|
47
46
|
console.error(e.stderr?.toString() || e.message);
|
|
48
47
|
process.exit(1);
|
|
49
48
|
}
|
|
@@ -56,7 +55,7 @@ function runStage(stageOrder, cwd) {
|
|
|
56
55
|
return stdout.toString().includes('PASS');
|
|
57
56
|
}
|
|
58
57
|
catch (err) {
|
|
59
|
-
console.log(
|
|
58
|
+
console.log(err.stdout?.toString().trim() || err.stderr?.toString().trim() || err.message);
|
|
60
59
|
return false;
|
|
61
60
|
}
|
|
62
61
|
finally {
|
|
@@ -72,14 +71,13 @@ function runStage(stageOrder, cwd) {
|
|
|
72
71
|
const path = require('path');
|
|
73
72
|
const zlib = require('zlib');
|
|
74
73
|
const { execSync } = require('child_process');
|
|
75
|
-
|
|
76
|
-
function assert(condition
|
|
74
|
+
|
|
75
|
+
function assert(condition, failMsg, expected, got) {
|
|
77
76
|
if (!condition) {
|
|
78
|
-
console.error('
|
|
79
|
-
console.error('📝 ' + failMsg);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
console.error('');
|
|
77
|
+
console.error('\n[FALHA DE ASSERÇÃO]\n');
|
|
78
|
+
console.error('📝 Resumo: ' + failMsg + '\n');
|
|
79
|
+
console.error('🎯 ESPERADO\n' + expected + '\n');
|
|
80
|
+
console.error('💥 RECEBIDO\n' + got + '\n');
|
|
83
81
|
process.exit(1);
|
|
84
82
|
}
|
|
85
83
|
}
|
|
@@ -104,7 +102,7 @@ function runStage(stageOrder, cwd) {
|
|
|
104
102
|
|
|
105
103
|
console.log('PASS');
|
|
106
104
|
fs.rmSync(repoPath, { recursive: true, force: true });
|
|
107
|
-
} catch(e
|
|
105
|
+
} catch(e) {
|
|
108
106
|
console.error(e.stderr?.toString() || e.message);
|
|
109
107
|
process.exit(1);
|
|
110
108
|
}
|
|
@@ -117,7 +115,7 @@ function runStage(stageOrder, cwd) {
|
|
|
117
115
|
return stdout.toString().includes('PASS');
|
|
118
116
|
}
|
|
119
117
|
catch (err) {
|
|
120
|
-
console.log(
|
|
118
|
+
console.log(err.stdout?.toString().trim() || err.stderr?.toString().trim() || err.message);
|
|
121
119
|
return false;
|
|
122
120
|
}
|
|
123
121
|
finally {
|
|
@@ -125,5 +123,6 @@ function runStage(stageOrder, cwd) {
|
|
|
125
123
|
fs_1.default.unlinkSync(testFilePath);
|
|
126
124
|
}
|
|
127
125
|
}
|
|
126
|
+
console.log(chalk_1.default.yellow(`⚠️ Nenhuma suite implementada ainda para Stage ${stageOrder} deste desafio. Bypass (Aprovado).`));
|
|
128
127
|
return true;
|
|
129
128
|
}
|
|
@@ -8,38 +8,43 @@ const child_process_1 = require("child_process");
|
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
async function runStage(stageOrder, cwd) {
|
|
10
10
|
if (stageOrder === 1) {
|
|
11
|
-
console.log(chalk_1.default.blue(`[Stage 1: HTTP Server]
|
|
11
|
+
console.log(chalk_1.default.blue(`[Stage 1: HTTP Server] Verificando resposta "Hello, World!" na porta 3000...`));
|
|
12
12
|
return new Promise(async (resolve) => {
|
|
13
13
|
let child = null;
|
|
14
14
|
try {
|
|
15
|
-
console.log(chalk_1.default.gray(`Iniciando servidor
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
console.log(chalk_1.default.gray(`Iniciando seu servidor (npx ts-node src/index.ts)...`));
|
|
16
|
+
// Use TS-Node directly for consistency in tests
|
|
17
|
+
child = (0, child_process_1.spawn)('npx', ['ts-node', 'src/index.ts'], { cwd });
|
|
18
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
19
19
|
let passed = true;
|
|
20
|
-
// TestCase 1: Invalid Route
|
|
21
20
|
try {
|
|
22
|
-
const res = await fetch('http://localhost:3000/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
const res = await fetch('http://localhost:3000/');
|
|
22
|
+
const text = await res.text();
|
|
23
|
+
if (res.status === 200 && text.includes('Hello, World!')) {
|
|
24
|
+
console.log(chalk_1.default.green('✅ Servidor respondeu com 200 OK e "Hello, World!"'));
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
console.error('\n' + chalk_1.default.bgRed.white.bold(' ❌ FALHA DE ASSERÇÃO ') + '\n');
|
|
28
|
+
console.error(chalk_1.default.yellow('📝 Resumo: ') + 'O servidor deve retornar "Hello, World!" com status 200.\n');
|
|
29
|
+
console.error(chalk_1.default.bgBlue.white.bold(' 🎯 ESPERADO ') + '\n' + chalk_1.default.blue('Status: 200, Body: Hello, World!') + '\n');
|
|
30
|
+
console.error(chalk_1.default.bgMagenta.white.bold(' 💥 RECEBIDO ') + '\n' + chalk_1.default.magenta(`Status: ${res.status}, Body: ${text.trim()}`) + '\n');
|
|
31
|
+
passed = false;
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
34
|
catch (e) {
|
|
30
|
-
console.
|
|
35
|
+
console.error('\n' + chalk_1.default.bgRed.white.bold(' ❌ FALHA DE CONEXÃO ') + '\n');
|
|
36
|
+
console.error(chalk_1.default.yellow('📝 Resumo: ') + 'Não foi possível conectar ao servidor na porta 3000.\n');
|
|
37
|
+
console.error(chalk_1.default.bgBlue.white.bold(' 🎯 ESPERADO ') + '\n' + chalk_1.default.blue('Servidor escutando na porta 3000') + '\n');
|
|
38
|
+
console.error(chalk_1.default.bgMagenta.white.bold(' 💥 RECEBIDO ') + '\n' + chalk_1.default.magenta(e.message) + '\n');
|
|
31
39
|
passed = false;
|
|
32
40
|
}
|
|
33
|
-
// Testcase 2: Valid Param
|
|
34
|
-
// HTTP framework challenge stage 1 generally involves simply binding a socket server.
|
|
35
|
-
// Once bound, it passes.
|
|
36
41
|
child.kill();
|
|
37
42
|
resolve(passed);
|
|
38
43
|
}
|
|
39
44
|
catch (e) {
|
|
40
45
|
if (child)
|
|
41
46
|
child.kill();
|
|
42
|
-
console.log(chalk_1.default.red('❌ Falha fatal ao executar
|
|
47
|
+
console.log(chalk_1.default.red('❌ Falha fatal ao executar seu servidor local.'));
|
|
43
48
|
resolve(false);
|
|
44
49
|
}
|
|
45
50
|
});
|
|
@@ -16,14 +16,13 @@ function runStage(stageOrder, cwd) {
|
|
|
16
16
|
const { execSync } = require('child_process');
|
|
17
17
|
const fs = require('fs');
|
|
18
18
|
const path = require('path');
|
|
19
|
-
|
|
20
|
-
function assert(condition
|
|
19
|
+
|
|
20
|
+
function assert(condition, failMsg, expected, got) {
|
|
21
21
|
if (!condition) {
|
|
22
|
-
console.error('
|
|
23
|
-
console.error('📝 ' + failMsg);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
console.error('');
|
|
22
|
+
console.error('\n[FALHA DE ASSERÇÃO]\n');
|
|
23
|
+
console.error('📝 Resumo: ' + failMsg + '\n');
|
|
24
|
+
console.error('🎯 ESPERADO\n' + expected + '\n');
|
|
25
|
+
console.error('💥 RECEBIDO\n' + got + '\n');
|
|
27
26
|
process.exit(1);
|
|
28
27
|
}
|
|
29
28
|
}
|
|
@@ -35,16 +34,17 @@ function runStage(stageOrder, cwd) {
|
|
|
35
34
|
|
|
36
35
|
console.log('-> Testando subcomando: tokenize');
|
|
37
36
|
const outputTokenize = execSync('npx ts-node src/index.ts tokenize test.lox', { cwd: '${cwd}', stdio: 'pipe' });
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
console.log('-> Testando subcomando: run');
|
|
41
|
-
const outputRun = execSync('npx ts-node src/index.ts run test.lox', { cwd: '${cwd}', stdio: 'pipe' });
|
|
42
|
-
// Even if it doesn't run yet, it should at least not crash if implemented properly.
|
|
43
|
-
// But we expect it to output 'hello' if implemented.
|
|
37
|
+
const outStr = outputTokenize.toString().toUpperCase();
|
|
44
38
|
|
|
39
|
+
assert(outStr.includes('PRINT') || outStr.includes('STRING'),
|
|
40
|
+
'O subcomando tokenize deve imprimir os tokens encontrados.',
|
|
41
|
+
'PRINT, STRING "hello" null',
|
|
42
|
+
outStr.trim()
|
|
43
|
+
);
|
|
44
|
+
|
|
45
45
|
console.log('PASS');
|
|
46
46
|
if (fs.existsSync(testFile)) fs.unlinkSync(testFile);
|
|
47
|
-
} catch(e
|
|
47
|
+
} catch(e) {
|
|
48
48
|
console.error(e.stderr?.toString() || e.message);
|
|
49
49
|
process.exit(1);
|
|
50
50
|
}
|
|
@@ -57,7 +57,7 @@ function runStage(stageOrder, cwd) {
|
|
|
57
57
|
return stdout.toString().includes('PASS');
|
|
58
58
|
}
|
|
59
59
|
catch (err) {
|
|
60
|
-
console.log(
|
|
60
|
+
console.log(err.stdout?.toString().trim() || err.stderr?.toString().trim() || err.message);
|
|
61
61
|
return false;
|
|
62
62
|
}
|
|
63
63
|
finally {
|
|
@@ -65,5 +65,6 @@ function runStage(stageOrder, cwd) {
|
|
|
65
65
|
fs_1.default.unlinkSync(testFilePath);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
+
console.log(chalk_1.default.yellow(`⚠️ Nenhuma suite implementada ainda para Stage ${stageOrder} deste desafio. Bypass (Aprovado).`));
|
|
68
69
|
return true;
|
|
69
70
|
}
|
|
@@ -8,15 +8,12 @@ const child_process_1 = require("child_process");
|
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
async function runStage(stageOrder, cwd) {
|
|
10
10
|
if (stageOrder === 1) {
|
|
11
|
-
console.log(chalk_1.default.blue(`[Stage 1: Redis TCP Bind] Verificando servidor TCP
|
|
11
|
+
console.log(chalk_1.default.blue(`[Stage 1: Redis TCP Bind] Verificando servidor TCP na porta 6379...`));
|
|
12
12
|
return new Promise(async (resolve) => {
|
|
13
13
|
let child = null;
|
|
14
14
|
try {
|
|
15
|
-
console.log(chalk_1.default.gray(`Iniciando servidor
|
|
16
|
-
|
|
17
|
-
// Assuming the Redis template follows the same pattern.
|
|
18
|
-
child = (0, child_process_1.spawn)('npx', ['ts-node', '-T', 'src/index.ts'], { cwd });
|
|
19
|
-
// Wait for bind
|
|
15
|
+
console.log(chalk_1.default.gray(`Iniciando servidor (npx ts-node src/index.ts)...`));
|
|
16
|
+
child = (0, child_process_1.spawn)('npx', ['ts-node', 'src/index.ts'], { cwd });
|
|
20
17
|
await new Promise(r => setTimeout(r, 2000));
|
|
21
18
|
let passed = false;
|
|
22
19
|
const net = require('net');
|
|
@@ -28,29 +25,25 @@ async function runStage(stageOrder, cwd) {
|
|
|
28
25
|
client.destroy();
|
|
29
26
|
resolveSocket();
|
|
30
27
|
});
|
|
31
|
-
client.on('error',
|
|
32
|
-
rejectSocket(err);
|
|
33
|
-
});
|
|
28
|
+
client.on('error', rejectSocket);
|
|
34
29
|
setTimeout(() => rejectSocket(new Error('Timeout ao conectar')), 1000);
|
|
35
30
|
});
|
|
36
31
|
}
|
|
37
32
|
catch (e) {
|
|
38
|
-
console.error('\n❌ FALHA DE
|
|
39
|
-
console.error('📝 O servidor não aceitou conexão TCP na porta 6379
|
|
40
|
-
console.error('🎯
|
|
41
|
-
console.error('💥
|
|
33
|
+
console.error('\n' + chalk_1.default.bgRed.white.bold(' ❌ FALHA DE CONEXÃO ') + '\n');
|
|
34
|
+
console.error(chalk_1.default.yellow('📝 Resumo: ') + 'O servidor não aceitou conexão TCP na porta 6379.\n');
|
|
35
|
+
console.error(chalk_1.default.bgBlue.white.bold(' 🎯 ESPERADO ') + '\n' + chalk_1.default.blue('Conexão Estabelecida (Port 6379)') + '\n');
|
|
36
|
+
console.error(chalk_1.default.bgMagenta.white.bold(' 💥 RECEBIDO ') + '\n' + chalk_1.default.magenta(e.message || 'ECONNREFUSED') + '\n');
|
|
42
37
|
passed = false;
|
|
43
38
|
}
|
|
44
|
-
if (passed)
|
|
45
|
-
console.log(chalk_1.default.green('✅ Conexão TCP na porta 6379
|
|
46
|
-
}
|
|
39
|
+
if (passed)
|
|
40
|
+
console.log(chalk_1.default.green('✅ Conexão TCP na porta 6379 estabelecida!'));
|
|
47
41
|
child.kill();
|
|
48
42
|
resolve(passed);
|
|
49
43
|
}
|
|
50
44
|
catch (e) {
|
|
51
45
|
if (child)
|
|
52
46
|
child.kill();
|
|
53
|
-
console.error(chalk_1.default.red(`[!] Erro fatal: ${e.message}`));
|
|
54
47
|
resolve(false);
|
|
55
48
|
}
|
|
56
49
|
});
|
|
@@ -60,7 +53,7 @@ async function runStage(stageOrder, cwd) {
|
|
|
60
53
|
return new Promise(async (resolve) => {
|
|
61
54
|
let child = null;
|
|
62
55
|
try {
|
|
63
|
-
child = (0, child_process_1.spawn)('npx', ['ts-node', '
|
|
56
|
+
child = (0, child_process_1.spawn)('npx', ['ts-node', 'src/index.ts'], { cwd });
|
|
64
57
|
await new Promise(r => setTimeout(r, 2000));
|
|
65
58
|
let passed = false;
|
|
66
59
|
const net = require('net');
|
|
@@ -69,29 +62,29 @@ async function runStage(stageOrder, cwd) {
|
|
|
69
62
|
await new Promise((resolveSocket, rejectSocket) => {
|
|
70
63
|
let receivedData = '';
|
|
71
64
|
client.connect(6379, '127.0.0.1', () => {
|
|
72
|
-
client.write('PING
|
|
65
|
+
client.write('PING\r\n');
|
|
73
66
|
});
|
|
74
67
|
client.on('data', (data) => {
|
|
75
68
|
receivedData += data.toString();
|
|
76
|
-
if (receivedData.includes('+PONG
|
|
69
|
+
if (receivedData.includes('+PONG')) {
|
|
77
70
|
passed = true;
|
|
78
71
|
client.destroy();
|
|
79
72
|
resolveSocket();
|
|
80
73
|
}
|
|
81
74
|
});
|
|
82
|
-
client.on('error',
|
|
75
|
+
client.on('error', rejectSocket);
|
|
83
76
|
setTimeout(() => rejectSocket(new Error('Timeout ao receber +PONG')), 2000);
|
|
84
77
|
});
|
|
85
78
|
}
|
|
86
79
|
catch (e) {
|
|
87
|
-
console.error('
|
|
88
|
-
console.error('📝 O servidor não respondeu com +PONG\\r\\n
|
|
89
|
-
console.error('🎯
|
|
90
|
-
console.error('💥
|
|
80
|
+
console.error('\n' + chalk_1.default.bgRed.white.bold(' ❌ FALHA DE PROTOCOLO ') + '\n');
|
|
81
|
+
console.error(chalk_1.default.yellow('📝 Resumo: ') + 'O servidor não respondeu com +PONG\\r\\n ao comando PING.\n');
|
|
82
|
+
console.error(chalk_1.default.bgBlue.white.bold(' 🎯 ESPERADO ') + '\n' + chalk_1.default.blue('+PONG\\r\\n') + '\n');
|
|
83
|
+
console.error(chalk_1.default.bgMagenta.white.bold(' 💥 RECEBIDO ') + '\n' + chalk_1.default.magenta(e.message || 'Sem resposta') + '\n');
|
|
91
84
|
passed = false;
|
|
92
85
|
}
|
|
93
86
|
if (passed)
|
|
94
|
-
console.log(chalk_1.default.green('✅ Recebido +PONG
|
|
87
|
+
console.log(chalk_1.default.green('✅ Recebido +PONG do servidor!'));
|
|
95
88
|
child.kill();
|
|
96
89
|
resolve(passed);
|
|
97
90
|
}
|
|
@@ -107,7 +100,7 @@ async function runStage(stageOrder, cwd) {
|
|
|
107
100
|
return new Promise(async (resolve) => {
|
|
108
101
|
let child = null;
|
|
109
102
|
try {
|
|
110
|
-
child = (0, child_process_1.spawn)('npx', ['ts-node', '
|
|
103
|
+
child = (0, child_process_1.spawn)('npx', ['ts-node', 'src/index.ts'], { cwd });
|
|
111
104
|
await new Promise(r => setTimeout(r, 2000));
|
|
112
105
|
const net = require('net');
|
|
113
106
|
let connectedCount = 0;
|
|
@@ -120,18 +113,21 @@ async function runStage(stageOrder, cwd) {
|
|
|
120
113
|
res();
|
|
121
114
|
});
|
|
122
115
|
client.on('error', rej);
|
|
123
|
-
setTimeout(() => rej(new Error('Timeout
|
|
116
|
+
setTimeout(() => rej(new Error('Timeout de Conexão')), 2000);
|
|
124
117
|
});
|
|
125
118
|
}));
|
|
126
119
|
if (connectedCount === 3) {
|
|
127
|
-
console.log(chalk_1.default.green('✅ O servidor lidou com 3 conexões simultâneas
|
|
120
|
+
console.log(chalk_1.default.green('✅ O servidor lidou com 3 conexões simultâneas!'));
|
|
128
121
|
clients.forEach(c => c.destroy());
|
|
129
122
|
child.kill();
|
|
130
123
|
return resolve(true);
|
|
131
124
|
}
|
|
132
125
|
}
|
|
133
126
|
catch (e) {
|
|
134
|
-
console.error('
|
|
127
|
+
console.error('\n' + chalk_1.default.bgRed.white.bold(' ❌ FALHA DE CONCORRÊNCIA ') + '\n');
|
|
128
|
+
console.error(chalk_1.default.yellow('📝 Resumo: ') + 'O servidor bloqueou ou falhou ao aceitar múltiplas conexões paralelas.\n');
|
|
129
|
+
console.error(chalk_1.default.bgBlue.white.bold(' 🎯 ESPERADO ') + '\n' + chalk_1.default.blue('3 Conexões Ativas') + '\n');
|
|
130
|
+
console.error(chalk_1.default.bgMagenta.white.bold(' 💥 RECEBIDO ') + '\n' + chalk_1.default.magenta(`${connectedCount} conexões, Erro: ${e.message}`) + '\n');
|
|
135
131
|
clients.forEach(c => c.destroy());
|
|
136
132
|
child.kill();
|
|
137
133
|
return resolve(false);
|
|
@@ -10,33 +10,43 @@ const child_process_1 = require("child_process");
|
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
function runStage(stageOrder, cwd) {
|
|
12
12
|
if (stageOrder === 1) {
|
|
13
|
-
console.log(chalk_1.default.blue(`[Stage 1: Shell
|
|
14
|
-
// O Shell Stage 1 geralmente envolve criar um prompt e lidar com comandos triviais
|
|
13
|
+
console.log(chalk_1.default.blue(`[Stage 1: Shell REPL] Verificando loop REPL e mensagem de erro...`));
|
|
15
14
|
const testFilePath = path_1.default.join(cwd, '.eval-stage1.ts');
|
|
16
15
|
const code = `
|
|
17
16
|
const { execSync } = require('child_process');
|
|
18
17
|
const fs = require('fs');
|
|
19
|
-
|
|
20
|
-
function assert(condition
|
|
18
|
+
|
|
19
|
+
function assert(condition, failMsg, expected, got) {
|
|
21
20
|
if (!condition) {
|
|
22
|
-
console.error('
|
|
23
|
-
console.error('📝 ' + failMsg);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
console.error('');
|
|
21
|
+
console.error('\n[FALHA DE ASSERÇÃO]\n');
|
|
22
|
+
console.error('📝 Resumo: ' + failMsg + '\n');
|
|
23
|
+
console.error('🎯 ESPERADO\n' + expected + '\n');
|
|
24
|
+
console.error('💥 RECEBIDO\n' + got + '\n');
|
|
27
25
|
process.exit(1);
|
|
28
26
|
}
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
async function testSuite() {
|
|
32
30
|
try {
|
|
33
|
-
//
|
|
34
|
-
console.log('-> Injetando
|
|
35
|
-
const output = execSync('echo "
|
|
31
|
+
// O Estágio 1 do Shell pede para imprimir "$ ", ler o comando e imprimir "<cmd>: command not found"
|
|
32
|
+
console.log('-> Injetando "mycommand" via stdin no seu Shell (src/index.ts)...');
|
|
33
|
+
const output = execSync('echo "mycommand\\nexit 0" | npx ts-node src/index.ts', { cwd: '${cwd}', stdio: 'pipe' });
|
|
34
|
+
|
|
35
|
+
const content = output.toString();
|
|
36
|
+
assert(content.includes('mycommand: command not found'),
|
|
37
|
+
'O Shell deve imprimir ": command not found" para comandos desconhecidos no Estágio 1.',
|
|
38
|
+
'mycommand: command not found',
|
|
39
|
+
content.trim()
|
|
40
|
+
);
|
|
36
41
|
|
|
37
|
-
assert(
|
|
42
|
+
assert(content.includes('$ '),
|
|
43
|
+
'O Shell deve exibir o prompt "$ " antes de ler o comando.',
|
|
44
|
+
'Prompt "$ "',
|
|
45
|
+
content.trim()
|
|
46
|
+
);
|
|
47
|
+
|
|
38
48
|
console.log('PASS');
|
|
39
|
-
} catch(e
|
|
49
|
+
} catch(e) {
|
|
40
50
|
console.error(e.stderr?.toString() || e.message);
|
|
41
51
|
process.exit(1);
|
|
42
52
|
}
|
|
@@ -49,7 +59,7 @@ function runStage(stageOrder, cwd) {
|
|
|
49
59
|
return stdout.toString().includes('PASS');
|
|
50
60
|
}
|
|
51
61
|
catch (err) {
|
|
52
|
-
console.log(
|
|
62
|
+
console.log(err.stdout?.toString().trim() || err.stderr?.toString().trim() || err.message);
|
|
53
63
|
return false;
|
|
54
64
|
}
|
|
55
65
|
finally {
|
|
@@ -57,5 +67,6 @@ function runStage(stageOrder, cwd) {
|
|
|
57
67
|
fs_1.default.unlinkSync(testFilePath);
|
|
58
68
|
}
|
|
59
69
|
}
|
|
70
|
+
console.log(chalk_1.default.yellow(`⚠️ Nenhuma suite implementada ainda para Stage ${stageOrder} deste desafio. Bypass (Aprovado).`));
|
|
60
71
|
return true;
|
|
61
72
|
}
|
|
@@ -16,27 +16,26 @@ function runStage(stageOrder, cwd) {
|
|
|
16
16
|
const { execSync } = require('child_process');
|
|
17
17
|
const fs = require('fs');
|
|
18
18
|
|
|
19
|
-
function assert(condition
|
|
19
|
+
function assert(condition, failMsg, expected, got) {
|
|
20
20
|
if (!condition) {
|
|
21
|
-
console.error('
|
|
22
|
-
console.error('📝 ' + failMsg);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
console.error('');
|
|
21
|
+
console.error('\n[FALHA DE ASSERÇÃO]\n');
|
|
22
|
+
console.error('📝 Resumo: ' + failMsg + '\n');
|
|
23
|
+
console.error('🎯 ESPERADO\n' + expected + '\n');
|
|
24
|
+
console.error('💥 RECEBIDO\n' + got + '\n');
|
|
26
25
|
process.exit(1);
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
async function testSuite() {
|
|
31
30
|
try {
|
|
32
|
-
console.log('-> Executando seu comando: node src/index.
|
|
31
|
+
console.log('-> Executando seu comando: npx ts-node src/index.ts deploy');
|
|
33
32
|
const output = execSync('npx ts-node src/index.ts deploy', { cwd: '${cwd}', stdio: 'pipe' });
|
|
34
33
|
|
|
35
34
|
const content = output.toString().toLowerCase();
|
|
36
35
|
assert(content.includes('deploy') || content.includes('build') || content.includes('uploading'), 'O comando deploy não iniciou o fluxo esperado.', 'Deploying...', output.toString());
|
|
37
36
|
|
|
38
37
|
console.log('PASS');
|
|
39
|
-
} catch(e
|
|
38
|
+
} catch(e) {
|
|
40
39
|
console.error(e.stderr?.toString() || e.message);
|
|
41
40
|
process.exit(1);
|
|
42
41
|
}
|