/**
* Test Fixtures and Helpers
*
* Common utilities for testing pear-git components
*/
// Sample git diff output for testing diff parser
export const sampleDiffs = {
// Single file addition
singleFileAdd: `diff --git a/newfile.js b/newfile.js
new file mode 100644
index 0000000..abc1234
--- /dev/null
+++ b/newfile.js
@@ -0,0 +1,3 @@
+console.log('hello')
+console.log('world')
+module.exports = {}`,
// Single file modification
singleFileModify: `diff --git a/file.js b/file.js
index abc1234..def5678 100644
--- a/file.js
+++ b/file.js
@@ -1,5 +1,6 @@
const x = 1
-const y = 2
+const y = 3
+const z = 4
function test() {
return x + y`,
// File deletion
fileDelete: `diff --git a/oldfile.js b/oldfile.js
deleted file mode 100644
index abc1234..0000000
--- a/oldfile.js
+++ /dev/null
@@ -1,2 +0,0 @@
-console.log('goodbye')
-module.exports = {}`,
// File rename
fileRename: `diff --git a/old-name.js b/new-name.js
similarity index 95%
rename from old-name.js
rename to new-name.js
index abc1234..def5678 100644
--- a/old-name.js
+++ b/new-name.js
@@ -1,3 +1,3 @@
const x = 1
-const y = 2
+const y = 3
module.exports = {}`,
// Multiple files
multipleFiles: `diff --git a/file1.js b/file1.js
index abc1234..def5678 100644
--- a/file1.js
+++ b/file1.js
@@ -1,2 +1,3 @@
const a = 1
+const b = 2
module.exports = {}
diff --git a/file2.js b/file2.js
index 111222..333444 100644
--- a/file2.js
+++ b/file2.js
@@ -5,3 +5,4 @@
function test() {
return true
}
+test()`,
// Binary file
binaryFile: `diff --git a/image.png b/image.png
new file mode 100644
index 0000000..abc1234
Binary files /dev/null and b/image.png differ`,
// Empty diff
empty: ``
}
// Sample issue data
export const sampleIssues = {
basic: {
title: 'Bug: Something is broken',
description: 'This feature does not work as expected.\n\nSteps to reproduce:\n1. Do this\n2. Do that',
labels: ['bug'],
createdBy: 'user123'
},
withImages: {
title: 'Screenshot of error',
description: 'See attached screenshot',
images: ['data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='],
labels: ['bug', 'help-wanted'],
createdBy: 'user456'
},
featureRequest: {
title: 'Feature: Add dark mode',
description: 'It would be nice to have a dark mode option',
labels: ['enhancement'],
createdBy: 'user789'
}
}
// Sample labels
export const sampleLabels = [
{ name: 'bug', color: '#d73a4a', description: 'Something isn\'t working' },
{ name: 'enhancement', color: '#a2eeef', description: 'New feature or request' },
{ name: 'documentation', color: '#0075ca', description: 'Documentation improvements' },
{ name: 'help-wanted', color: '#008672', description: 'Extra attention is needed' },
{ name: 'question', color: '#d876e3', description: 'Further information is requested' }
]
// Sample file extensions for syntax detection
export const sampleFiles = {
javascript: ['app.js', 'index.mjs', 'utils.cjs'],
typescript: ['app.ts', 'index.tsx', 'types.d.ts'],
python: ['main.py', 'utils.pyw'],
rust: ['main.rs', 'lib.rs'],
go: ['main.go', 'server.go'],
markdown: ['README.md', 'docs.markdown'],
json: ['package.json', 'config.json'],
yaml: ['config.yml', 'docker-compose.yaml'],
html: ['index.html', 'template.htm'],
css: ['styles.css', 'app.scss', 'theme.less'],
shell: ['script.sh', 'deploy.bash', 'setup.zsh'],
binary: ['image.png', 'photo.jpg', 'archive.zip', 'program.exe']
}
// Mock registry for testing
export class MockRegistry {
constructor() {
this.data = new Map()
}
async get(key) {
const value = this.data.get(key)
return value ? { value } : null
}
async put(key, value) {
this.data.set(key, value)
}
async del(key) {
this.data.delete(key)
}
async * createReadStream(options = {}) {
const { gt, gte, lt } = options
const sorted = [...this.data.entries()].sort((a, b) => a[0].localeCompare(b[0]))
for (const [key, value] of sorted) {
if (gt && key <= gt) continue
if (gte && key < gte) continue
if (lt && key >= lt) continue
yield { key, value }
}
}
clear() {
this.data.clear()
}
}
// Mock corestore for testing
export class MockCorestore {
constructor() {
this.cores = new Map()
}
get(options = {}) {
const name = options.name || 'default'
if (!this.cores.has(name)) {
this.cores.set(name, new MockCore())
}
return this.cores.get(name)
}
}
// Mock hypercore for testing
export class MockCore {
constructor() {
this.data = []
this.isReady = false
}
async ready() {
this.isReady = true
}
async append(block) {
this.data.push(block)
return this.data.length - 1
}
async get(index) {
return this.data[index]
}
get length() {
return this.data.length
}
}
// Utility: wait for a condition
export async function waitFor(condition, timeout = 5000, interval = 100) {
const start = Date.now()
while (Date.now() - start < timeout) {
if (await condition()) return true
await sleep(interval)
}
throw new Error('Timeout waiting for condition')
}
// Utility: sleep
export function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
// Utility: create a test context
export function createTestContext() {
return {
registry: new MockRegistry(),
corestore: new MockCorestore(),
cleanup: async function() {
this.registry.clear()
}
}
}
export default {
sampleDiffs,
sampleIssues,
sampleLabels,
sampleFiles,
MockRegistry,
MockCorestore,
MockCore,
waitFor,
sleep,
createTestContext
}