Skip to content

Commit 0844183

Browse files
Add rollup module bundler and unitTestExpand bug fix
1 parent a0c4fae commit 0844183

13 files changed

+2309
-3906
lines changed

build/const/colors.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"use strict";
2+
3+
module.exports = {
4+
red: "\x1b[31m",
5+
yellow: "\x1b[33m",
6+
green: "\x1b[32m",
7+
blue: "\x1b[34m",
8+
reset: "\x1b[0m",
9+
bold: "\x1b[1m"
10+
};

build/const/common.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"use strict";
2+
3+
module.exports = {
4+
PYTHAGORA_TESTS_DIR: "pythagora_tests",
5+
PYTHAGORA_METADATA_DIR: ".pythagora",
6+
METADATA_FILENAME: "metadata.json",
7+
REVIEW_DATA_FILENAME: "review.json",
8+
EXPORT_METADATA_FILENAME: "export.json",
9+
CONFIG_FILENAME: "config.json",
10+
PYTHAGORA_ASYNC_STORE: 42069420,
11+
PYTHAGORA_DELIMITER: "-_-",
12+
EXPORTED_TESTS_DIR: "pythagora_tests/exported_tests",
13+
EXPORTED_TESTS_DATA_DIR: "pythagora_tests/exported_tests/data",
14+
SRC_TO_ROOT: "../../../",
15+
MIN_TOKENS_FOR_GPT_RESPONSE: 1640,
16+
MAX_GPT_MODEL_TOKENS: 8192,
17+
PYTHAGORA_UNIT_TESTS_VERSION: 1,
18+
PYTHAGORA_UNIT_DIR: "pythagora_tests/unit",
19+
PYTHAGORA_API_SERVER: "https://api.pythagora.io"
20+
};

build/helpers/apiClass.js

+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
"use strict";
2+
3+
/* eslint-disable no-unsafe-finally */
4+
const _ = require("lodash");
5+
const axios = require("axios");
6+
const {
7+
blue,
8+
red,
9+
reset,
10+
bold
11+
} = require("../const/colors");
12+
13+
/**
14+
* @class Api
15+
* @description A class to interact with the remote API.
16+
* @throws Will throw an error if the class is instantiated directly.
17+
*/
18+
class Api {
19+
#apiUrl;
20+
#apiKey;
21+
#apiKeyType;
22+
23+
/**
24+
* @param {string} apiUrl - The API base url.
25+
* @param {string} apiKey - The API key.
26+
* @param {string} apiKeyType - The type of the API key. It should be 'openai' or 'pythagora'.
27+
* @throws Will throw an error if called directly.
28+
*/
29+
constructor(apiUrl, apiKey, apiKeyType) {
30+
if (!apiKey) {
31+
console.log(`${bold + red}No API key found!${reset}`);
32+
console.log("Please run:");
33+
console.log(`${bold + blue}npx pythagora --config --pythagora-api-key <YOUR_PYTHAGORA_API_KEY>${reset}`);
34+
console.log("or");
35+
console.log(`${bold + blue}npx pythagora --config --openai-api-key <YOUR_OPENAI_API_KEY>${reset}`);
36+
console.log("You can get Pythagora API key here: https://mailchi.mp/f4f4d7270a7a/api-waitlist");
37+
process.exit(0);
38+
}
39+
if (!apiUrl || !apiKey) {
40+
throw new Error("Please, pass API url!");
41+
}
42+
if (apiKeyType !== "openai" && apiKeyType !== "pythagora") {
43+
throw new Error("API key type value must be openai or pythagora!");
44+
}
45+
this.#apiUrl = apiUrl;
46+
this.#apiKey = apiKey;
47+
this.#apiKeyType = apiKeyType;
48+
}
49+
50+
/**
51+
* Prepare and set the options for the API request
52+
*/
53+
setOptions({
54+
path,
55+
method,
56+
headers
57+
}) {
58+
const parsedUrl = new URL(this.#apiUrl);
59+
const options = {
60+
protocol: parsedUrl.protocol.replace(":", ""),
61+
hostname: parsedUrl.hostname,
62+
port: parsedUrl.port,
63+
path: path || "/",
64+
method: method || "POST",
65+
headers: headers || {
66+
"Content-Type": "application/json",
67+
apikey: this.#apiKey,
68+
apikeytype: this.#apiKeyType
69+
}
70+
};
71+
if (!options.port) delete options.port;
72+
return options;
73+
}
74+
75+
/**
76+
* Make API request
77+
*/
78+
async makeRequest(data, options, customLogFunction) {
79+
let gptResponse = "";
80+
const httpModule = options.protocol === "http" ? require("http") : require("https");
81+
return new Promise((resolve, reject) => {
82+
const req = httpModule.request(_.omit(options, ["protocol"]), function (res) {
83+
res.on("data", chunk => {
84+
try {
85+
const stringified = chunk.toString();
86+
try {
87+
const json = JSON.parse(stringified);
88+
if (json.error || json.message) {
89+
gptResponse = json;
90+
return;
91+
}
92+
} catch (e) {}
93+
gptResponse += stringified;
94+
if (customLogFunction) customLogFunction(gptResponse);else process.stdout.write(stringified);
95+
} catch (e) {}
96+
});
97+
res.on("end", async function () {
98+
process.stdout.write("\n");
99+
if (res.statusCode >= 400) return reject(new Error(`Response status code: ${res.statusCode}. Error message: ${gptResponse}`));
100+
if (gptResponse.error) return reject(new Error(`Error: ${gptResponse.error.message}. Code: ${gptResponse.error.code}`));
101+
if (gptResponse.message) return reject(new Error(`Error: ${gptResponse.message}. Code: ${gptResponse.code}`));
102+
gptResponse = gptResponse.split("pythagora_end:").pop();
103+
return resolve(gptResponse);
104+
});
105+
});
106+
req.on("error", e => {
107+
console.error("problem with request:" + e.message);
108+
reject(e);
109+
});
110+
req.write(data);
111+
req.end();
112+
});
113+
}
114+
async getUnitTests(data, customLogFunction) {
115+
const options = this.setOptions({
116+
path: "/api/generate-unit-tests"
117+
});
118+
let tests, error;
119+
try {
120+
tests = await this.makeRequest(JSON.stringify(data), options, customLogFunction);
121+
} catch (e) {
122+
error = e;
123+
} finally {
124+
return {
125+
tests,
126+
error
127+
};
128+
}
129+
}
130+
async expandUnitTests(data, customLogFunction) {
131+
const options = this.setOptions({
132+
path: "/api/expand-unit-tests"
133+
});
134+
let tests, error;
135+
try {
136+
tests = await this.makeRequest(JSON.stringify(data), options, customLogFunction);
137+
} catch (e) {
138+
error = e;
139+
} finally {
140+
return {
141+
tests,
142+
error
143+
};
144+
}
145+
}
146+
async getJestAuthFunction(loginMongoQueriesArray, loginRequestBody, loginEndpointPath) {
147+
const options = this.setOptions({
148+
path: "/api/generate-jest-auth"
149+
});
150+
return this.makeRequest(JSON.stringify({
151+
loginMongoQueriesArray,
152+
loginRequestBody,
153+
loginEndpointPath
154+
}), options);
155+
}
156+
157+
/**
158+
* Generate jest test
159+
*/
160+
async getJestTest(test) {
161+
const options = this.setOptions({
162+
path: "/api/generate-jest-test"
163+
});
164+
return this.makeRequest(JSON.stringify(test), options);
165+
}
166+
167+
/**
168+
* Generate jest test name
169+
*/
170+
async getJestTestName(test, usedNames) {
171+
const options = this.setOptions({
172+
path: "/api/generate-jest-test-name"
173+
});
174+
return this.makeRequest(JSON.stringify({
175+
test
176+
}), options);
177+
}
178+
179+
/**
180+
* Check if the test is eligible for export
181+
*/
182+
async isEligibleForExport(test) {
183+
try {
184+
const options = this.setOptions({
185+
path: "/api/check-if-eligible"
186+
});
187+
const response = await axios.post(`${options.protocol}://${options.hostname}${options.port ? ":" + options.port : ""}${options.path}`, JSON.stringify({
188+
test
189+
}), {
190+
headers: options.headers
191+
});
192+
return response.data;
193+
} catch (error) {
194+
console.log(error);
195+
return false;
196+
}
197+
}
198+
}
199+
module.exports = Api;

0 commit comments

Comments
 (0)