jettypod 4.4.21 → 4.4.22
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/jettypod.js +11 -11
- package/lib/decisions/index.js +490 -0
- package/lib/git-hooks/git-hooks.feature +30 -0
- package/lib/git-hooks/index.js +94 -0
- package/lib/git-hooks/post-commit +59 -0
- package/lib/git-hooks/post-merge +71 -0
- package/lib/git-hooks/pre-commit +28 -0
- package/lib/git-hooks/simple-steps.js +53 -0
- package/lib/git-hooks/simple-test.feature +10 -0
- package/lib/git-hooks/steps.js +196 -0
- package/lib/mode-prompts/index.js +95 -0
- package/lib/mode-prompts/simple-steps.js +44 -0
- package/lib/mode-prompts/simple-test.feature +9 -0
- package/lib/update-command/index.js +181 -0
- package/lib/work-commands/bug-workflow-display.feature +22 -0
- package/lib/work-commands/index.js +1603 -0
- package/lib/work-commands/simple-steps.js +69 -0
- package/lib/work-commands/stable-tests.feature +57 -0
- package/lib/work-commands/steps.js +1233 -0
- package/lib/work-commands/work-commands.feature +13 -0
- package/lib/work-commands/worktree-management.feature +63 -0
- package/lib/work-tracking/index.js +2396 -0
- package/lib/work-tracking/mode-required.feature +111 -0
- package/lib/work-tracking/work-set-mode.feature +70 -0
- package/lib/work-tracking/work-start-mode.feature +83 -0
- package/package.json +1 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const { Given, When, Then } = require('@cucumber/cucumber');
|
|
2
|
+
const assert = require('assert');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
const { resetDb } = require('../../lib/database');
|
|
7
|
+
|
|
8
|
+
const testDir = path.join('/tmp', 'jettypod-test-' + Date.now());
|
|
9
|
+
let originalDir;
|
|
10
|
+
|
|
11
|
+
Given('I have initialized jettypod', function () {
|
|
12
|
+
resetDb(); // Clear singleton db to avoid stale connections
|
|
13
|
+
|
|
14
|
+
originalDir = process.cwd();
|
|
15
|
+
// SAFETY: Only delete if testDir is in /tmp
|
|
16
|
+
if (fs.existsSync(testDir) && testDir.startsWith('/tmp/')) {
|
|
17
|
+
fs.rmSync(testDir, { recursive: true, force: true });
|
|
18
|
+
}
|
|
19
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
20
|
+
process.chdir(testDir);
|
|
21
|
+
|
|
22
|
+
execSync('git init', { stdio: 'pipe' });
|
|
23
|
+
execSync('git config user.email "test@test.com"', { stdio: 'pipe' });
|
|
24
|
+
execSync('git config user.name "Test"', { stdio: 'pipe' });
|
|
25
|
+
execSync(`node ${path.join(originalDir, 'jettypod.js')} init`, { stdio: 'pipe', env: { ...process.env, NODE_ENV: 'test' } });
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
Given('I create an epic with id {int}', function (id) {
|
|
29
|
+
execSync(`node ${path.join(originalDir, 'jettypod.js')} work create epic "Test Epic"`, { stdio: 'pipe', env: { ...process.env, NODE_ENV: 'test' } });
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
Given('I create a feature with id {int} under epic {int}', function (featureId, epicId) {
|
|
33
|
+
execSync(`node ${path.join(originalDir, 'jettypod.js')} work create feature "Test Feature" "" --parent=${epicId}`, { stdio: 'pipe', env: { ...process.env, NODE_ENV: 'test' } });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
When('I start work on item {int}', function (id) {
|
|
37
|
+
execSync(`node ${path.join(originalDir, 'jettypod.js')} work start ${id}`, { stdio: 'pipe', env: { ...process.env, NODE_ENV: 'test' } });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
Then('the current work file exists', function () {
|
|
41
|
+
const currentWorkPath = path.join(testDir, '.jettypod', 'current-work.json');
|
|
42
|
+
assert(fs.existsSync(currentWorkPath), 'Current work file does not exist');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
Then('the current work contains item {int}', function (id) {
|
|
46
|
+
const currentWorkPath = path.join(testDir, '.jettypod', 'current-work.json');
|
|
47
|
+
const currentWork = JSON.parse(fs.readFileSync(currentWorkPath, 'utf-8'));
|
|
48
|
+
assert.strictEqual(currentWork.id, id);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
Then('item {int} status is in_progress or backlog', function (id) {
|
|
52
|
+
// Use CLI to check status to avoid database connection issues
|
|
53
|
+
try {
|
|
54
|
+
const output = execSync(`node ${path.join(originalDir, 'jettypod.js')} work show ${id}`, { encoding: 'utf-8', env: { ...process.env, NODE_ENV: 'test' } });
|
|
55
|
+
const statusMatch = output.match(/Status:\s+(\w+)/);
|
|
56
|
+
if (!statusMatch) {
|
|
57
|
+
throw new Error('Could not find status in output');
|
|
58
|
+
}
|
|
59
|
+
const status = statusMatch[1];
|
|
60
|
+
assert(status === 'in_progress' || status === 'backlog', `Status is ${status}`);
|
|
61
|
+
} finally {
|
|
62
|
+
// SAFETY: Only delete if testDir is in /tmp
|
|
63
|
+
if (fs.existsSync(testDir) && testDir.startsWith('/tmp/')) {
|
|
64
|
+
process.chdir(originalDir);
|
|
65
|
+
fs.rmSync(testDir, { recursive: true, force: true });
|
|
66
|
+
}
|
|
67
|
+
resetDb(); // Clear singleton after cleanup
|
|
68
|
+
}
|
|
69
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
Feature: Work Commands - Stable Mode
|
|
2
|
+
Edge cases and error handling for work commands
|
|
3
|
+
|
|
4
|
+
Scenario: Start work with invalid ID
|
|
5
|
+
Given jettypod is initialized
|
|
6
|
+
When I try to start work with ID "invalid"
|
|
7
|
+
Then I get an error "Invalid work item ID"
|
|
8
|
+
|
|
9
|
+
Scenario: Start work with negative ID
|
|
10
|
+
Given jettypod is initialized
|
|
11
|
+
When I try to start work with ID "-1"
|
|
12
|
+
Then I get an error "Invalid work item ID"
|
|
13
|
+
|
|
14
|
+
Scenario: Start work when not initialized
|
|
15
|
+
Given jettypod is not initialized
|
|
16
|
+
When I try to start work with ID "1"
|
|
17
|
+
Then I get an error "JettyPod not initialized"
|
|
18
|
+
|
|
19
|
+
Scenario: Start work on non-existent item
|
|
20
|
+
Given jettypod is initialized
|
|
21
|
+
When I try to start work with ID "999"
|
|
22
|
+
Then I get an error "Work item #999 not found"
|
|
23
|
+
|
|
24
|
+
Scenario: Stop work with invalid status
|
|
25
|
+
Given I have current work
|
|
26
|
+
When I try to stop work with status "invalid"
|
|
27
|
+
Then I get an error "Invalid status"
|
|
28
|
+
|
|
29
|
+
Scenario: Stop work when no current work
|
|
30
|
+
Given jettypod is initialized
|
|
31
|
+
And no work is active
|
|
32
|
+
When I try to stop work
|
|
33
|
+
Then operation succeeds with no changes
|
|
34
|
+
|
|
35
|
+
Scenario: Get current work with corrupted file
|
|
36
|
+
Given jettypod is initialized
|
|
37
|
+
And current work file is corrupted
|
|
38
|
+
When I get current work
|
|
39
|
+
Then it returns null
|
|
40
|
+
|
|
41
|
+
Scenario: Start work without git repo
|
|
42
|
+
Given jettypod is initialized without git
|
|
43
|
+
And I have a work item
|
|
44
|
+
When I start work on the item
|
|
45
|
+
Then it succeeds without creating branch
|
|
46
|
+
|
|
47
|
+
Scenario: Multiple start work calls
|
|
48
|
+
Given I have a work item
|
|
49
|
+
And I start work on it
|
|
50
|
+
When I start work on a different item
|
|
51
|
+
Then the first item stops being current
|
|
52
|
+
And the second item becomes current
|
|
53
|
+
|
|
54
|
+
Scenario: Start work preserves existing status
|
|
55
|
+
Given I have a work item with status "in_progress"
|
|
56
|
+
When I start work on it
|
|
57
|
+
Then the status remains "in_progress"
|