OverviewFilesCommitsIssuesDocsReleasesPeers

pear-git / test / helpers / fixtures.js

250 lines · javascript ref:
/**
 * 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
}