Skip to content

Commit

Permalink
fix workflow tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jerdog committed Nov 29, 2024
1 parent 127cdba commit 3b84125
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 111 deletions.
7 changes: 4 additions & 3 deletions bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ class MarkovChain {
}

async generate({ minChars = 100, maxChars = 280, maxTries = 100 } = {}) {
for (let attempt = 0; attempt < maxTries; attempt++) {
let attempt = 0;
while (attempt < maxTries) {
try {
const result = await this._generateOnce();
if (result.length >= minChars && result.length <= maxChars) {
Expand All @@ -274,8 +275,8 @@ class MarkovChain {
throw error;
}
// Continue trying if it's just a generation issue
continue;
}
attempt++;
}
throw new Error('Failed to generate valid text within constraints');
}
Expand Down Expand Up @@ -350,7 +351,7 @@ async function fetchRecentPosts() {
debug('Mastodon API error', 'error', errorData);
throw new Error(`Mastodon API error: ${errorData.error || 'Unknown error'}`);
}

const mastodonData = await mastodonResponse.json();

if (Array.isArray(mastodonData)) {
Expand Down
20 changes: 19 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,24 @@
"json",
"jsx",
"node"
]
],
"setupFilesAfterEnv": ["<rootDir>/tests/setup.js"]
},
"eslintConfig": {
"env": {
"node": true,
"es2022": true,
"jest": true
},
"extends": ["eslint:recommended"],
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module"
},
"rules": {
"quotes": ["error", "single"],
"no-constant-condition": ["error", { "checkLoops": false }]
}
},
"dependencies": {
"dotenv": "^16.4.5",
Expand All @@ -64,6 +81,7 @@
"devDependencies": {
"@babel/core": "^7.23.5",
"@babel/preset-env": "^7.23.5",
"@jest/globals": "^29.7.0",
"babel-jest": "^29.7.0",
"eslint": "^8.55.0",
"jest": "^29.7.0",
Expand Down
2 changes: 1 addition & 1 deletion tests/bot.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { jest } from '@jest/globals';
import { describe, test, expect, beforeAll, beforeEach, afterEach } from '@jest/globals';
import { generatePost, loadConfig } from '../bot.js';
import dotenv from 'dotenv';
import path from 'path';
Expand Down
186 changes: 80 additions & 106 deletions tests/markov.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { jest } from '@jest/globals';
import { describe, test, expect, beforeAll } from '@jest/globals';
import { MarkovChain } from '../bot.js';
import fs from 'fs/promises';
import path from 'path';
Expand All @@ -15,134 +15,108 @@ describe('MarkovChain', () => {
sampleTweets = tweetsContent.split('\n').filter(line => line.trim());
});

let markov;
test('generates text within constraints', async () => {
const markov = new MarkovChain(2);
await markov.addData(sampleTweets);

beforeEach(() => {
markov = new MarkovChain(2);
markov.addData(sampleTweets);
});

describe('constructor', () => {
test('initializes with default state size', () => {
const defaultMarkov = new MarkovChain();
expect(defaultMarkov.stateSize).toBe(2);
});
console.log('\nTesting text generation within constraints:');
console.log('-'.repeat(50));

test('initializes with custom state size', () => {
const customMarkov = new MarkovChain(3);
expect(customMarkov.stateSize).toBe(3);
const result = await markov.generate({
minChars: 30,
maxChars: 280,
maxTries: 100
});
});

describe('addData', () => {
test('processes single text input', async () => {
const text = 'the quick brown fox jumps over the lazy dog';
await markov.addData([text]);
expect(markov.startStates.length).toBeGreaterThan(0);
expect(markov.chain.size).toBeGreaterThan(0);
});

test('processes multiple text inputs', async () => {
const texts = [
'the quick brown fox jumps over the lazy dog',
'a quick brown cat sleeps under the warm sun'
];
await markov.addData(texts);
expect(markov.startStates.length).toBeGreaterThan(1);
expect(markov.chain.size).toBeGreaterThan(0);
});
console.log('Generated:', result.string);
console.log(`Length: ${result.string.length} characters`);
console.log('-'.repeat(50));

test('handles empty input gracefully', async () => {
await expect(markov.addData([])).rejects.toThrow('No valid training data found');
});

test('handles invalid input types', async () => {
await expect(markov.addData([null, undefined, '', ' '])).rejects.toThrow('No valid training data found');
});
expect(result.string.length).toBeGreaterThanOrEqual(30);
expect(result.string.length).toBeLessThanOrEqual(280);
});

describe('generate', () => {
test('generates text within length constraints', async () => {
console.log('\nTesting text generation within constraints:');
console.log('-'.repeat(50));
test('generates different text on multiple calls', async () => {
const markov = new MarkovChain(2);
await markov.addData(sampleTweets);

console.log('\nTesting text variation:');
console.log('-'.repeat(50));

// Generate multiple texts with more relaxed constraints
const results = [];
for (let i = 0; i < 3; i++) {
try {
const result = await markov.generate({
minChars: 10, // More lenient minimum length
maxChars: 280,
maxTries: 100
});
results.push(result);
} catch (error) {
console.log(`Generation ${i + 1} failed:`, error.message);
}
}

const result = await markov.generate({
minChars: 30,
maxChars: 280,
maxTries: 100
});
expect(results.length).toBeGreaterThan(0);

console.log('Generated:', result.string);
results.forEach((result, i) => {
console.log(`Generation ${i + 1}:`, result.string);
console.log(`Length: ${result.string.length} characters`);
console.log('-'.repeat(50));

expect(result.string.length).toBeGreaterThanOrEqual(30);
expect(result.string.length).toBeLessThanOrEqual(280);
});

test('handles impossible length constraints', async () => {
await expect(markov.generate({
minChars: 1000,
maxChars: 2000,
maxTries: 5
})).rejects.toThrow('Failed to generate valid text within constraints');
});
const uniqueTexts = new Set(results.map(r => r.string));
expect(uniqueTexts.size).toBeGreaterThan(1);
});

test('handles no training data', async () => {
const emptyMarkov = new MarkovChain();
await expect(emptyMarkov.generate()).rejects.toThrow('No training data available');
});
test('handles empty input', async () => {
const markov = new MarkovChain(2);
await expect(markov.addData([])).rejects.toThrow('No valid training data found');
});

test('generates different text on multiple calls', async () => {
const markov = new MarkovChain(2);
await markov.addData(sampleTweets);
test('handles invalid input', async () => {
const markov = new MarkovChain(2);
await expect(markov.addData([null, undefined, '', ' '])).rejects.toThrow('No valid training data found');
});

console.log('\nTesting text variation:');
console.log('-'.repeat(50));
test('respects maximum length constraint', async () => {
const markov = new MarkovChain(2);
await markov.addData(sampleTweets);

// Generate multiple texts with more relaxed constraints
const results = [];
for (let i = 0; i < 3; i++) {
try {
const result = await markov.generate({
minChars: 10, // More lenient minimum length
maxChars: 280,
maxTries: 100
});
results.push(result);
} catch (error) {
console.log(`Generation ${i + 1} failed:`, error.message);
}
}
const result = await markov.generate({
minChars: 30,
maxChars: 100,
maxTries: 100
});

expect(results.length).toBeGreaterThan(0);
expect(result.string.length).toBeLessThanOrEqual(100);
});

results.forEach((result, i) => {
console.log(`Generation ${i + 1}:`, result.string);
console.log(`Length: ${result.string.length} characters`);
console.log('-'.repeat(50));
});
test('respects minimum length constraint', async () => {
const markov = new MarkovChain(2);
await markov.addData(sampleTweets);

const uniqueTexts = new Set(results.map(r => r.string));
expect(uniqueTexts.size).toBeGreaterThan(1);
const result = await markov.generate({
minChars: 50,
maxChars: 280,
maxTries: 100
});

test('respects minimum length constraint', async () => {
const result = await markov.generate({
minChars: 50,
maxChars: 280,
maxTries: 100
});
expect(result.string.length).toBeGreaterThanOrEqual(50);
});
expect(result.string.length).toBeGreaterThanOrEqual(50);
});

test('respects state size', async () => {
const markov = new MarkovChain(3); // Using state size 3
await markov.addData(sampleTweets);

test('respects maximum length constraint', async () => {
const result = await markov.generate({
minChars: 30,
maxChars: 100,
maxTries: 100
});
expect(result.string.length).toBeLessThanOrEqual(100);
const result = await markov.generate({
minChars: 30,
maxChars: 280,
maxTries: 100
});

expect(result.string.length).toBeGreaterThanOrEqual(30);
expect(result.string.length).toBeLessThanOrEqual(280);
});
});
11 changes: 11 additions & 0 deletions tests/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { jest } from '@jest/globals';

// Make Jest globals available
global.jest = jest;
global.describe = jest.describe;
global.test = jest.test;
global.expect = jest.expect;
global.beforeAll = jest.beforeAll;
global.beforeEach = jest.beforeEach;
global.afterEach = jest.afterEach;
global.afterAll = jest.afterAll;

0 comments on commit 3b84125

Please sign in to comment.