testeranto
Version:
the AI powered BDD test framework for typescript projects
164 lines (163 loc) • 7.28 kB
JavaScript
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */
import Tiposkripto from "../Tiposkripto";
/**
* Concrete implementation of Tiposkripto for testing purposes
*/
export class MockTiposkripto extends Tiposkripto {
constructor(input, testSpecification, testImplementation, testResourceRequirement = { ports: 0 }, testAdapter, uberCatcher = (cb) => cb()) {
super(input, testSpecification, testImplementation, testResourceRequirement, testAdapter, uberCatcher);
this.specs = [];
this.testJobs = [];
this.artifacts = [];
this.features = [];
this.testImplementation = testImplementation;
this.testAdapter = testAdapter;
// Store implementation methods as overrides
this.suitesOverrides = testImplementation.suites;
this.givenOverides = testImplementation.givens;
this.whenOverides = testImplementation.whens;
this.thenOverides = testImplementation.thens;
// Calculate total number of tests (sum of all Givens across all Suites)
// For testing purposes, we'll use the number of Givens in the implementation
// Each Given corresponds to one test
let totalTests = Object.keys(testImplementation.givens).length;
// Override with specific values for test cases
if (input && typeof input === "object") {
const inputObj = input;
if ("testCount" in inputObj) {
totalTests = Number(inputObj.testCount);
}
}
// Extract features from the test specification
try {
this.features = this.extractFeaturesFromSpecification(testSpecification);
}
catch (error) {
console.error("Failed to extract features, using fallback:", error);
// Fallback to basic features
this.features = [
"Tiposkripto should initialize with default values",
"Custom input test",
"Resource requirements test",
"Should generate specs from test specification",
"Should create test jobs from specs",
"Should track artifacts",
"Should properly configure all overrides",
"Interface configuration test",
"Custom implementation test",
"Custom specification test",
"Should allow modifying specs",
"Should allow modifying jobs",
"Should properly handle errors",
"Should complete a full test run successfully",
"Should correctly count the number of tests",
"Should set runTimeTests to -1 on hard errors",
"Given a config that has 1 suite containing 5 GivenWhenThens",
"Given a config that has 1 suite containing 3 GivenWhenThens and 1 suite containing 3 GivenWhenThens",
];
}
}
extractFeaturesFromSpecification(specification) {
try {
// Create proper mock functions that match the expected signatures
// The Suite function should take name, tests, and features
const mockSuite = (name, tests, features) => ({
name,
tests,
features,
});
// The Given function should take features, whens, thens
const mockGiven = (features, whens, thens) => {
return {
features: Array.isArray(features)
? features.filter((f) => typeof f === "string")
: [],
whens,
thens,
};
};
// Create mock When and Then objects that have all the methods from the implementation
// We need to dynamically create objects with all the method names from this.testImplementation.whens and this.testImplementation.thens
const mockWhen = {};
const mockThen = {};
// Add all when methods
if (this.testImplementation.whens) {
Object.keys(this.testImplementation.whens).forEach((key) => {
mockWhen[key] = (...args) => ({ name: key, args });
});
}
// Add all then methods
if (this.testImplementation.thens) {
Object.keys(this.testImplementation.thens).forEach((key) => {
mockThen[key] = (...args) => ({ name: key, args });
});
}
// Execute the specification to get the test suites
const suites = specification(mockSuite, mockGiven, mockWhen, mockThen);
// Extract all features from all tests in all suites
const features = [];
for (const suite of suites) {
if (suite && suite.tests && typeof suite.tests === "object") {
for (const testKey of Object.keys(suite.tests)) {
const test = suite.tests[testKey];
if (test && test.features && Array.isArray(test.features)) {
// Ensure all features are strings
for (const feature of test.features) {
if (typeof feature === "string") {
features.push(feature);
}
}
}
}
}
}
// Remove duplicates
const uniqueFeatures = [...new Set(features)];
return uniqueFeatures;
}
catch (error) {
console.error("Error extracting features from specification:", error);
return [];
}
}
async receiveTestResourceConfig(partialTestResource) {
try {
// Ensure test adapter is properly configured
if (!this.testAdapter) {
throw new Error("Test adapter not configured");
}
// Ensure features are always strings
const stringFeatures = this.features.filter((f) => typeof f === "string");
// Calculate totalTests based on input
let totalTests = Object.keys(this.givenOverides).length;
const input = this.input;
// Override with specific values for test cases
if (input && typeof input === "object") {
if ("testCount" in input) {
totalTests = input.testCount;
}
}
// Simulate running tests
return {
failed: false,
fails: 0,
artifacts: [],
features: stringFeatures,
tests: 0,
runTimeTests: totalTests,
};
}
catch (error) {
// On hard error, set runTimeTests to -1
return {
failed: true,
fails: 1,
artifacts: [],
features: [], // Ensure this is always an array of strings
tests: 0,
runTimeTests: -1,
};
}
}
}