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
29 changes: 28 additions & 1 deletion pull.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ class Pull {

const filesCreated = [];
const fileTree = {};
const usedFileNames = new Set(Object.keys(data.files).filter(Boolean));

// Process files from server - server now sends .feature files directly
for (const [fileName, content] of Object.entries(data.files)) {
const targetPath = path.join(this.targetDir, fileName);
const resolvedFileName = fileName || this.fallbackFileName(content, usedFileNames);
const targetPath = path.join(this.targetDir, resolvedFileName);
const targetDir = path.dirname(targetPath);

// Create directory structure
Expand Down Expand Up @@ -76,6 +78,31 @@ class Pull {
}


/**
* Generate a fallback filename when the server returns an empty path.
* @param {string} content - Feature file content
* @param {Set<string>} usedFileNames - File names already reserved for this pull
* @returns {string} Safe fallback file name
*/
fallbackFileName(content, usedFileNames) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DenysKuchma please check if we can come up wiht better implementaton
regexes look fragile, we need to think about it

const match = (content || '').match(/^\s*Feature:\s*(.+)$/m);
const baseName = (match ? match[1] : 'feature')
.toLowerCase()
.replace(/[^a-z0-9]+/g, '_')
.replace(/^_+|_+$/g, '')
.slice(0, 120) || 'feature';
let fileName = `${baseName}.feature`;
let counter = 2;

while (usedFileNames.has(fileName)) {
fileName = `${baseName}_${counter}.feature`;
counter += 1;
}

usedFileNames.add(fileName);
return fileName;
}

/**
* Add file to tree structure for display
* @param {Object} tree - File tree object
Expand Down
19 changes: 19 additions & 0 deletions tests/pull_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,25 @@ Feature: User Management
expect(content).to.include('Feature: Deep Test');
});

it('should generate a fallback file name for empty server file paths', async () => {
mockReporter.getFilesFromServer = () =>
Promise.resolve({
files: {
'': `Feature: Missing Source Path
Scenario: Pulled from Testomat
Given a feature has no source path`
}
});

await pull.execute();

const fallbackFile = path.join(testDir, 'missing_source_path.feature');
expect(fs.existsSync(fallbackFile)).to.be.true;

const content = fs.readFileSync(fallbackFile, 'utf8');
expect(content).to.include('Feature: Missing Source Path');
});

it('should handle empty server response', async () => {
mockReporter.getFilesFromServer = () => Promise.resolve({ files: {} });

Expand Down