Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions __tests__/triggers/two-four-six-game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
const {
startGameTrigger,
handleTripleGuessTrigger,
handleRuleGuessTrigger,
checkRule,
} = require('../../triggers/two-four-six-game');
const { enqueueMessage } = require('../../outgoing-messages');
jest.mock('../../outgoing-messages');

describe('2-4-6 game triggers', () => {
beforeEach(() => {
enqueueMessage.mockClear();
});

describe('startGameTrigger', () => {
test.each([
['играть 246'],
['играть'],
['игра 2 4 6'],
['давай игра'],
['play 246'],
["let's play"],
['сыграем'],
])('"%s" message starts the game', (incomingMessage) => {
const context = {
request: { peerType: 'user', text: incomingMessage },
state: {}
};
expect(startGameTrigger.condition(context)).toBe(true);
startGameTrigger.action(context);
expect(enqueueMessage).toHaveBeenCalled();
expect(context.state.games.twoFourSixGame.active).toBe(true);
});

test.each([
['привет'],
['2 4 6'],
['как дела?'],
])('"%s" message does not start the game', (incomingMessage) => {
const context = {
request: { peerType: 'user', text: incomingMessage },
state: {}
};
expect(startGameTrigger.condition(context)).toBe(false);
});

test('does not trigger for outgoing messages', () => {
const context = {
request: { peerType: 'user', text: 'играть', isOutbox: true },
state: {}
};
expect(startGameTrigger.condition(context)).toBe(false);
});
});

describe('handleTripleGuessTrigger', () => {
test.each([
['2 4 6', [2, 4, 6], true],
['8, 10, 12', [8, 10, 12], true],
['-1, 121, 130.5', [-1, 121, 130.5], true],
['100 200 300', [100, 200, 300], true],
['2 2 3', [2, 2, 3], false],
['3 2 1', [3, 2, 1], false],
])('"%s" triple is processed correctly', (incomingMessage, triple, shouldMatch) => {
const context = {
request: { peerType: 'user', text: incomingMessage },
state: {
games: {
twoFourSixGame: {
active: true,
guesses: []
}
}
}
};
expect(handleTripleGuessTrigger.condition(context)).toBe(true);
handleTripleGuessTrigger.action(context);
expect(enqueueMessage).toHaveBeenCalled();
const callArg = enqueueMessage.mock.calls[0][0];
expect(callArg.response.message).toContain(shouldMatch ? '✅' : '❌');
expect(context.state.games.twoFourSixGame.guesses.length).toBe(1);
expect(context.state.games.twoFourSixGame.guesses[0].triple).toEqual(triple);
});

test('does not trigger when game is not active', () => {
const context = {
request: { peerType: 'user', text: '2 4 6' },
state: {
games: {
twoFourSixGame: {
active: false
}
}
}
};
expect(handleTripleGuessTrigger.condition(context)).toBe(false);
});
});

describe('handleRuleGuessTrigger', () => {
test('accepts correct rule guess with ascending keywords', () => {
const context = {
request: { peerType: 'user', text: 'правило: числа в порядке возрастания' },
state: {
games: {
twoFourSixGame: {
active: true,
guesses: [],
ruleGuessesCount: 0
}
}
}
};
expect(handleRuleGuessTrigger.condition(context)).toBe(true);
handleRuleGuessTrigger.action(context);
expect(enqueueMessage).toHaveBeenCalled();
const callArg = enqueueMessage.mock.calls[0][0];
expect(callArg.response.message).toContain('🎉');
expect(context.state.games.twoFourSixGame.active).toBe(false);
});

test('rejects incorrect rule guess', () => {
const context = {
request: { peerType: 'user', text: 'правило: четные числа' },
state: {
games: {
twoFourSixGame: {
active: true,
guesses: [],
ruleGuessesCount: 0
}
}
}
};
expect(handleRuleGuessTrigger.condition(context)).toBe(true);
handleRuleGuessTrigger.action(context);
expect(enqueueMessage).toHaveBeenCalled();
const callArg = enqueueMessage.mock.calls[0][0];
expect(callArg.response.message).toContain('❌');
expect(context.state.games.twoFourSixGame.active).toBe(true);
});

test('prevents multiple rule guesses per day', () => {
const yesterday = new Date();
yesterday.setHours(yesterday.getHours() - 12);

const context = {
request: { peerType: 'user', text: 'правило: числа больше' },
state: {
games: {
twoFourSixGame: {
active: true,
guesses: [],
ruleGuessesCount: 1,
lastRuleGuessDate: yesterday
}
}
}
};
expect(handleRuleGuessTrigger.condition(context)).toBe(true);
handleRuleGuessTrigger.action(context);
expect(enqueueMessage).toHaveBeenCalled();
const callArg = enqueueMessage.mock.calls[0][0];
expect(callArg.response.message).toContain('⏰');
});

test('does not trigger for triple guesses', () => {
const context = {
request: { peerType: 'user', text: '2 4 6' },
state: {
games: {
twoFourSixGame: {
active: true,
guesses: []
}
}
}
};
expect(handleRuleGuessTrigger.condition(context)).toBe(false);
});
});

describe('checkRule', () => {
test.each([
[2, 4, 6, true],
[8, 10, 12, true],
[-1, 121, 130.5, true],
[1, 2, 3, true],
[0, 0.5, 1, true],
[2, 2, 3, false],
[3, 2, 1, false],
[6, 4, 2, false],
[1, 1, 1, false],
[5, 3, 7, false],
])('checkRule(%d, %d, %d) returns %s', (a, b, c, expected) => {
expect(checkRule(a, b, c)).toBe(expected);
});
});
});
96 changes: 96 additions & 0 deletions experiments/test-two-four-six-game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Test script for the 2-4-6 game triggers
const {
startGameRegex,
tripleRegex,
ruleGuessRegex,
checkRule,
} = require('../triggers/two-four-six-game');

console.log('Testing 2-4-6 game implementation...\n');

// Test 1: Start game regex
console.log('=== Test 1: Start Game Regex ===');
const startGameTests = [
{ text: 'играть 246', expected: true },
{ text: 'играть', expected: true },
{ text: 'игра 2 4 6', expected: true },
{ text: 'давай игра', expected: true },
{ text: 'play 246', expected: true },
{ text: 'play game', expected: true },
{ text: "let's play", expected: true },
{ text: 'сыграем', expected: true },
{ text: 'привет', expected: false },
{ text: '2 4 6', expected: false },
];

startGameTests.forEach(test => {
const result = startGameRegex.test(test.text);
const status = result === test.expected ? '✅' : '❌';
console.log(`${status} "${test.text}" -> ${result} (expected: ${test.expected})`);
});

// Test 2: Triple regex
console.log('\n=== Test 2: Triple Regex ===');
const tripleTests = [
{ text: '2 4 6', expected: true },
{ text: '8, 10, 12', expected: true },
{ text: '-1, 121, 130.5', expected: true },
{ text: '100 200 300', expected: true },
{ text: '2.5, 3.7, 4.9', expected: true },
{ text: '2 4', expected: false },
{ text: '1 2 3 4', expected: false },
{ text: 'привет', expected: false },
];

tripleTests.forEach(test => {
const result = tripleRegex.test(test.text);
const status = result === test.expected ? '✅' : '❌';
console.log(`${status} "${test.text}" -> ${result} (expected: ${test.expected})`);
if (result) {
const match = test.text.match(tripleRegex);
console.log(` Extracted: [${match[1]}, ${match[2]}, ${match[3]}]`);
}
});

// Test 3: Rule guess regex
console.log('\n=== Test 3: Rule Guess Regex ===');
const ruleGuessTests = [
{ text: 'правило: числа возрастают', expected: true },
{ text: 'я знаю правило', expected: true },
{ text: 'понял! числа должны расти', expected: true },
{ text: 'rule: ascending order', expected: true },
{ text: 'i know the rule', expected: true },
{ text: 'got it: numbers increase', expected: true },
{ text: 'числа должны идти в порядке возрастания, каждое следующее больше предыдущего', expected: true },
{ text: '2 4 6', expected: false },
];

ruleGuessTests.forEach(test => {
const result = ruleGuessRegex.test(test.text) || test.text.length > 30;
const status = result === test.expected ? '✅' : '❌';
console.log(`${status} "${test.text}" -> ${result} (expected: ${test.expected})`);
});

// Test 4: Check rule function
console.log('\n=== Test 4: Check Rule Function ===');
const ruleTests = [
{ triple: [2, 4, 6], expected: true },
{ triple: [8, 10, 12], expected: true },
{ triple: [-1, 121, 130.5], expected: true },
{ triple: [1, 2, 3], expected: true },
{ triple: [0, 0.5, 1], expected: true },
{ triple: [2, 2, 3], expected: false },
{ triple: [3, 2, 1], expected: false },
{ triple: [6, 4, 2], expected: false },
{ triple: [1, 1, 1], expected: false },
{ triple: [5, 3, 7], expected: false },
];

ruleTests.forEach(test => {
const [a, b, c] = test.triple;
const result = checkRule(a, b, c);
const status = result === test.expected ? '✅' : '❌';
console.log(`${status} checkRule(${a}, ${b}, ${c}) -> ${result} (expected: ${test.expected})`);
});

console.log('\n=== All Tests Complete ===');
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const triggers = [
// require('./triggers/who-singular').trigger,
// require('./triggers/have-we-talked-before').trigger,
// require('./triggers/engage-with-acquaintance').trigger
require('./triggers/two-four-six-game').startGameTrigger,
require('./triggers/two-four-six-game').handleTripleGuessTrigger,
require('./triggers/two-four-six-game').handleRuleGuessTrigger,
];

const token = getToken();
Expand Down
Loading