tests/CodeCompass.Repo.Tests.ps1

BeforeAll {
    $modulePath = Split-Path $PSScriptRoot -Parent
    Import-Module $modulePath -Force
}

Describe 'Module loads correctly' {
    It 'Exports expected functions' {
        $expected = @(
            'Test-CCRepoHealth'
            'Test-CCFilePresence'
            'Test-CCFolderStructure'
            'Test-CCDocumentation'
            'Test-CCDependencies'
            'Test-CCCIConfiguration'
            'Get-CCStandard'
            'Repair-CCRepo'
        )
        $exported = (Get-Module CodeCompass.Repo).ExportedFunctions.Keys
        foreach ($fn in $expected) {
            $exported | Should -Contain $fn
        }
    }
}

Describe 'Get-CCStandard' {
    It 'Returns core standard with all required files' {
        $std = Get-CCStandard -Name core
        $std.Name | Should -Be 'core'
        $std.FilesRequired | Should -Contain 'README.md'
        $std.FilesRequired | Should -Contain 'LICENSE'
        $std.FilesRequired | Should -Contain 'CHANGELOG.md'
        $std.RequireCI | Should -BeTrue
    }

    It 'Returns active standard with relaxed settings' {
        $std = Get-CCStandard -Name active
        $std.FilesRequired | Should -Not -Contain 'CHANGELOG.md'
        $std.RequireTestStep | Should -BeFalse
    }

    It 'Returns minimal standard with fewest requirements' {
        $std = Get-CCStandard -Name minimal
        $std.FilesRequired.Count | Should -Be 2
        $std.RequireCI | Should -BeFalse
    }
}

Describe 'Test-CCFilePresence' {
    BeforeAll {
        $testDir = Join-Path $TestDrive 'repo-file-test'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        Set-Content -Path (Join-Path $testDir 'README.md') -Value '# Test'
        Set-Content -Path (Join-Path $testDir '.gitignore') -Value '*.log'
    }

    It 'Detects present files as Pass' {
        $results = Test-CCFilePresence -Path $testDir -Standard minimal
        $readme = $results | Where-Object CheckId -eq 'FILE-001'
        $readme.Status | Should -Be 'Pass'
    }

    It 'Detects missing files as Fail' {
        $results = Test-CCFilePresence -Path $testDir -Standard core
        $license = $results | Where-Object CheckId -eq 'FILE-003'
        $license.Status | Should -Be 'Fail'
    }

    It 'Respects standard tier — minimal only requires README and .gitignore' {
        $results = Test-CCFilePresence -Path $testDir -Standard minimal
        $results.Count | Should -Be 2
        ($results | Where-Object Status -eq 'Pass').Count | Should -Be 2
    }
}

Describe 'Test-CCFolderStructure' {
    BeforeAll {
        $testDir = Join-Path $TestDrive 'repo-struct-test'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        New-Item -ItemType Directory -Path (Join-Path $testDir 'src') -Force | Out-Null
        New-Item -ItemType Directory -Path (Join-Path $testDir 'tests') -Force | Out-Null
        New-Item -ItemType Directory -Path (Join-Path $testDir '.github/workflows') -Force | Out-Null
    }

    It 'Detects existing folders as Pass' {
        $results = Test-CCFolderStructure -Path $testDir -Standard core
        $src = $results | Where-Object CheckId -eq 'STRUCT-001'
        $src.Status | Should -Be 'Pass'
    }

    It 'Detects missing docs folder' {
        $results = Test-CCFolderStructure -Path $testDir -Standard core
        $docs = $results | Where-Object CheckId -eq 'STRUCT-003'
        $docs.Status | Should -Be 'Warning'
    }

    It 'Skips structure checks for minimal standard' {
        $results = Test-CCFolderStructure -Path $testDir -Standard minimal
        $results.Count | Should -Be 0
    }
}

Describe 'Test-CCDocumentation' {
    BeforeAll {
        $testDir = Join-Path $TestDrive 'repo-doc-test'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        $readmeContent = @"
# My Project

## Overview

A test project.

## Installation

``pip install myproject``

## Usage

``import myproject``
"@

        Set-Content -Path (Join-Path $testDir 'README.md') -Value $readmeContent
        $changelogContent = @"
# Changelog

## [1.0.0] - 2026-01-01

### Added

- Initial release
"@

        Set-Content -Path (Join-Path $testDir 'CHANGELOG.md') -Value $changelogContent
    }

    It 'Passes when README has all required sections' {
        $results = Test-CCDocumentation -Path $testDir -Standard core
        $doc = $results | Where-Object CheckId -eq 'DOC-001'
        $doc.Status | Should -Be 'Pass'
    }

    It 'Passes CHANGELOG format check' {
        $results = Test-CCDocumentation -Path $testDir -Standard core
        $cl = $results | Where-Object CheckId -eq 'DOC-002'
        $cl.Status | Should -Be 'Pass'
    }

    It 'Fails when README missing sections' {
        $badDir = Join-Path $TestDrive 'repo-doc-bad'
        New-Item -ItemType Directory -Path $badDir -Force | Out-Null
        Set-Content -Path (Join-Path $badDir 'README.md') -Value '# Hello World'
        $results = Test-CCDocumentation -Path $badDir -Standard core
        $doc = $results | Where-Object CheckId -eq 'DOC-001'
        $doc.Status | Should -Be 'Fail'
        $doc.Message | Should -Match 'missing sections'
    }
}

Describe 'Test-CCDependencies' {
    It 'Skips lockfile check when no package manager detected' {
        $testDir = Join-Path $TestDrive 'repo-dep-empty'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        Set-Content -Path (Join-Path $testDir 'README.md') -Value '# test'
        $results = Test-CCDependencies -Path $testDir -Standard core
        $lock = $results | Where-Object CheckId -eq 'DEP-001'
        $lock.Status | Should -Be 'Skipped'
    }

    It 'Fails when package.json exists but no lockfile' {
        $testDir = Join-Path $TestDrive 'repo-dep-nolock'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        Set-Content -Path (Join-Path $testDir 'package.json') -Value '{}'
        $results = Test-CCDependencies -Path $testDir -Standard core
        $lock = $results | Where-Object CheckId -eq 'DEP-001'
        $lock.Status | Should -Be 'Fail'
    }

    It 'Passes when lockfile exists' {
        $testDir = Join-Path $TestDrive 'repo-dep-lock'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        Set-Content -Path (Join-Path $testDir 'package.json') -Value '{}'
        Set-Content -Path (Join-Path $testDir 'package-lock.json') -Value '{}'
        $results = Test-CCDependencies -Path $testDir -Standard core
        $lock = $results | Where-Object CheckId -eq 'DEP-001'
        $lock.Status | Should -Be 'Pass'
    }
}

Describe 'Test-CCCIConfiguration' {
    It 'Passes when workflows exist with test step' {
        $testDir = Join-Path $TestDrive 'repo-ci-good'
        New-Item -ItemType Directory -Path "$testDir/.github/workflows" -Force | Out-Null
        Set-Content -Path "$testDir/.github/workflows/ci.yml" -Value 'jobs: test: run: npm test'
        $results = Test-CCCIConfiguration -Path $testDir -Standard core
        $ci = $results | Where-Object CheckId -eq 'CI-001'
        $ci.Status | Should -Be 'Pass'
    }

    It 'Fails when no workflows exist' {
        $testDir = Join-Path $TestDrive 'repo-ci-none'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        $results = Test-CCCIConfiguration -Path $testDir -Standard core
        $ci = $results | Where-Object CheckId -eq 'CI-001'
        $ci.Status | Should -Be 'Fail'
    }

    It 'Returns nothing for minimal standard' {
        $testDir = Join-Path $TestDrive 'repo-ci-minimal'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        $results = Test-CCCIConfiguration -Path $testDir -Standard minimal
        $results.Count | Should -Be 0
    }
}

Describe 'Repair-CCRepo' {
    It 'Creates missing files with -WhatIf' {
        $testDir = Join-Path $TestDrive 'repo-repair-whatif'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        Repair-CCRepo -Path $testDir -Standard minimal -WhatIf
        # Should NOT have created files
        Test-Path (Join-Path $testDir 'README.md') | Should -BeFalse
    }

    It 'Creates missing files when run without -WhatIf' {
        $testDir = Join-Path $TestDrive 'repo-repair-real'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        Repair-CCRepo -Path $testDir -Standard minimal -Confirm:$false
        Test-Path (Join-Path $testDir 'README.md') | Should -BeTrue
        Test-Path (Join-Path $testDir '.gitignore') | Should -BeTrue
    }
}

Describe 'Technology detection' {
    It 'Detects PowerShell projects' {
        $testDir = Join-Path $TestDrive 'repo-tech-ps'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        Set-Content -Path (Join-Path $testDir 'MyModule.psd1') -Value '@{}'
        InModuleScope CodeCompass.Repo -Parameters @{ dir = $testDir } {
            param($dir)
            $result = Get-CCTechStack -Path $dir
            $result | Should -Contain 'powershell'
        }
    }

    It 'Detects JavaScript projects' {
        $testDir = Join-Path $TestDrive 'repo-tech-js'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        Set-Content -Path (Join-Path $testDir 'package.json') -Value '{}'
        InModuleScope CodeCompass.Repo -Parameters @{ dir = $testDir } {
            param($dir)
            $result = Get-CCTechStack -Path $dir
            $result | Should -Contain 'javascript'
        }
    }

    It 'Detects Python projects' {
        $testDir = Join-Path $TestDrive 'repo-tech-py'
        New-Item -ItemType Directory -Path $testDir -Force | Out-Null
        Set-Content -Path (Join-Path $testDir 'pyproject.toml') -Value '[project]'
        InModuleScope CodeCompass.Repo -Parameters @{ dir = $testDir } {
            param($dir)
            $result = Get-CCTechStack -Path $dir
            $result | Should -Contain 'python'
        }
    }
}

Describe 'Per-repo config override' {
    It 'Overrides structure source mapping' {
        $testDir = Join-Path $TestDrive 'repo-config-override'
        New-Item -ItemType Directory -Path "$testDir/.codecompass" -Force | Out-Null
        New-Item -ItemType Directory -Path "$testDir/Modules" -Force | Out-Null
        $configContent = @"
structure:
  source: Modules
"@

        Set-Content -Path "$testDir/.codecompass/config.yml" -Value $configContent
        $results = Test-CCFolderStructure -Path $testDir -Standard core
        $src = $results | Where-Object CheckId -eq 'STRUCT-001'
        $src.Status | Should -Be 'Pass'
        $src.Item | Should -Be 'Modules'
    }
}