Skip to content

Commit c7a7022

Browse files
committed
test: add validation tests for shipped agent files in agents/ directory
Signed-off-by: leocavalcante <[email protected]>
1 parent d6e2517 commit c7a7022

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

tests/install.test.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,6 +2029,141 @@ The agent handles various tasks and operations in the system.
20292029
})
20302030
})
20312031

2032+
describe("shipped agent files validation", () => {
2033+
it("should validate all shipped agent files pass content validation", async () => {
2034+
const { AGENT_NAMES, validateAgentContent } = await import("../src/paths.mjs")
2035+
2036+
const agentsDir = join(process.cwd(), "agents")
2037+
2038+
for (const agentName of AGENT_NAMES) {
2039+
const filePath = join(agentsDir, `${agentName}.md`)
2040+
2041+
// Verify file exists
2042+
expect(existsSync(filePath)).toBe(true)
2043+
2044+
// Read and validate content
2045+
const content = readFileSync(filePath, "utf-8")
2046+
const result = validateAgentContent(content)
2047+
2048+
// Should pass validation
2049+
expect(result.valid).toBe(true)
2050+
if (!result.valid) {
2051+
// Provide helpful error message if validation fails
2052+
throw new Error(`Agent ${agentName}.md failed validation: ${result.error}`)
2053+
}
2054+
}
2055+
})
2056+
2057+
it("should validate all shipped agent files have valid frontmatter", async () => {
2058+
const { AGENT_NAMES, parseFrontmatter, REQUIRED_FRONTMATTER_FIELDS } = await import(
2059+
"../src/paths.mjs"
2060+
)
2061+
2062+
const agentsDir = join(process.cwd(), "agents")
2063+
2064+
for (const agentName of AGENT_NAMES) {
2065+
const filePath = join(agentsDir, `${agentName}.md`)
2066+
const content = readFileSync(filePath, "utf-8")
2067+
2068+
// Parse frontmatter
2069+
const frontmatter = parseFrontmatter(content)
2070+
2071+
// Should have frontmatter
2072+
expect(frontmatter.found).toBe(true)
2073+
2074+
// Should have all required fields
2075+
for (const field of REQUIRED_FRONTMATTER_FIELDS) {
2076+
expect(frontmatter.fields[field]).toBeDefined()
2077+
expect(frontmatter.fields[field]).not.toBe("")
2078+
}
2079+
2080+
// Verify version field is valid semver format
2081+
const versionField = frontmatter.fields.version
2082+
expect(versionField).toMatch(/^\d+\.\d+\.\d+$/)
2083+
2084+
// Verify requires field is a valid version constraint
2085+
const requiresField = frontmatter.fields.requires
2086+
expect(requiresField).toMatch(/^[>=<^~]*\d+\.\d+\.\d+$/)
2087+
}
2088+
})
2089+
2090+
it("should validate all shipped agent files have markdown headers after frontmatter", async () => {
2091+
const { AGENT_NAMES, parseFrontmatter } = await import("../src/paths.mjs")
2092+
2093+
const agentsDir = join(process.cwd(), "agents")
2094+
2095+
for (const agentName of AGENT_NAMES) {
2096+
const filePath = join(agentsDir, `${agentName}.md`)
2097+
const content = readFileSync(filePath, "utf-8")
2098+
2099+
// Parse frontmatter to get endIndex
2100+
const frontmatter = parseFrontmatter(content)
2101+
expect(frontmatter.found).toBe(true)
2102+
2103+
// Get content after frontmatter
2104+
const contentAfterFrontmatter = content.slice(frontmatter.endIndex).trimStart()
2105+
2106+
// Should start with a markdown header
2107+
expect(contentAfterFrontmatter.startsWith("# ")).toBe(true)
2108+
2109+
// Extract and verify the header title is meaningful
2110+
const firstLineEnd = contentAfterFrontmatter.indexOf("\n")
2111+
const headerLine =
2112+
firstLineEnd !== -1
2113+
? contentAfterFrontmatter.slice(0, firstLineEnd)
2114+
: contentAfterFrontmatter
2115+
expect(headerLine.length).toBeGreaterThan(2) // More than just "# "
2116+
}
2117+
})
2118+
2119+
it("should validate all shipped agent files contain required keywords", async () => {
2120+
const { AGENT_NAMES, REQUIRED_KEYWORDS } = await import("../src/paths.mjs")
2121+
2122+
const agentsDir = join(process.cwd(), "agents")
2123+
2124+
for (const agentName of AGENT_NAMES) {
2125+
const filePath = join(agentsDir, `${agentName}.md`)
2126+
const content = readFileSync(filePath, "utf-8")
2127+
const lowerContent = content.toLowerCase()
2128+
2129+
// Should contain at least one required keyword
2130+
const hasKeyword = REQUIRED_KEYWORDS.some((keyword: string) =>
2131+
lowerContent.includes(keyword),
2132+
)
2133+
expect(hasKeyword).toBe(true)
2134+
}
2135+
})
2136+
2137+
it("should validate all shipped agent files meet minimum content length", async () => {
2138+
const { AGENT_NAMES, MIN_CONTENT_LENGTH } = await import("../src/paths.mjs")
2139+
2140+
const agentsDir = join(process.cwd(), "agents")
2141+
2142+
for (const agentName of AGENT_NAMES) {
2143+
const filePath = join(agentsDir, `${agentName}.md`)
2144+
const content = readFileSync(filePath, "utf-8")
2145+
2146+
// Should be above minimum length
2147+
expect(content.length).toBeGreaterThanOrEqual(MIN_CONTENT_LENGTH)
2148+
}
2149+
})
2150+
2151+
it("should validate shipped agent count matches AGENT_NAMES", async () => {
2152+
const { AGENT_NAMES } = await import("../src/paths.mjs")
2153+
2154+
const agentsDir = join(process.cwd(), "agents")
2155+
const files = readdirSync(agentsDir).filter((f) => f.endsWith(".md"))
2156+
2157+
// Number of .md files should match expected agent names
2158+
expect(files.length).toBe(AGENT_NAMES.length)
2159+
2160+
// All expected agents should exist as files
2161+
for (const agentName of AGENT_NAMES) {
2162+
expect(files).toContain(`${agentName}.md`)
2163+
}
2164+
})
2165+
})
2166+
20322167
describe("full install/uninstall cycle", () => {
20332168
it("should install and then cleanly uninstall", async () => {
20342169
// Create scripts

0 commit comments

Comments
 (0)