mirror of
https://github.com/cheat/cheat.git
synced 2026-03-07 03:03:32 +01:00
test: improve mutation coverage across 4 modules
Mutation testing (56 mutations, 10 modules) identified 7 surviving mutations. Added 5 targeted tests to kill all actionable survivors. Remaining 2 are logically equivalent condition reorderings in filter.go. Overall mutation score: 96.4%. New tests: - TestHasMalformedYAML: YAML unmarshal error path - TestInvalidateInvalidCheatpath: cheatpath.Validate() delegation - TestIndentTrimsWhitespace: TrimSpace behavior - TestColorizeDefaultSyntax: default "bash" lexer - TestColorizeExplicitSyntax: lexer differentiation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
105
.test-mutations.json
Normal file
105
.test-mutations.json
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0",
|
||||||
|
"test_command": "go test ./...",
|
||||||
|
"last_updated": "2026-02-15T00:00:00Z",
|
||||||
|
"modules": {
|
||||||
|
"internal/sheet/parse.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/sheet/parse_test.go", "internal/sheet/parse_extended_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 8,
|
||||||
|
"mutations_killed": 8,
|
||||||
|
"mutation_score": 100.0,
|
||||||
|
"notes": "Originally 7/8 (87.5%). Added TestHasMalformedYAML to kill YAML unmarshal error survivor."
|
||||||
|
},
|
||||||
|
"internal/config/validate.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/config/validate_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 8,
|
||||||
|
"mutations_killed": 8,
|
||||||
|
"mutation_score": 100.0,
|
||||||
|
"notes": "Originally 7/8 (87.5%). Added TestInvalidateInvalidCheatpath to kill cheatpath.Validate() delegation survivor."
|
||||||
|
},
|
||||||
|
"internal/sheets/filter.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/sheets/filter_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 7,
|
||||||
|
"mutations_killed": 5,
|
||||||
|
"mutation_score": 71.4,
|
||||||
|
"notes": "Survivors relate to UTF-8 condition ordering and OR→AND on dead code path. Not actionable — logically equivalent mutations."
|
||||||
|
},
|
||||||
|
"internal/config/paths.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/config/paths_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 8,
|
||||||
|
"mutations_killed": 8,
|
||||||
|
"mutation_score": 100.0,
|
||||||
|
"notes": "Perfect score. Excellent existing coverage."
|
||||||
|
},
|
||||||
|
"internal/sheet/colorize.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/sheet/colorize_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 5,
|
||||||
|
"mutations_killed": 5,
|
||||||
|
"mutation_score": 100.0,
|
||||||
|
"notes": "Originally 2/5 (40%). Added TestColorizeDefaultSyntax and TestColorizeExplicitSyntax. All 5 mutations now killed."
|
||||||
|
},
|
||||||
|
"internal/sheets/consolidate.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/sheets/consolidate_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 2,
|
||||||
|
"mutations_killed": 2,
|
||||||
|
"mutation_score": 100.0,
|
||||||
|
"notes": "Override semantics well-tested."
|
||||||
|
},
|
||||||
|
"internal/display/indent.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/display/indent_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 3,
|
||||||
|
"mutations_killed": 3,
|
||||||
|
"mutation_score": 100.0,
|
||||||
|
"notes": "Originally 2/3 (66.7%). Added TestIndentTrimsWhitespace to kill TrimSpace survivor."
|
||||||
|
},
|
||||||
|
"internal/display/faint.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/display/faint_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 3,
|
||||||
|
"mutations_killed": 3,
|
||||||
|
"mutation_score": 100.0,
|
||||||
|
"notes": "Perfect score."
|
||||||
|
},
|
||||||
|
"internal/sheets/tags.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/sheets/tags_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 2,
|
||||||
|
"mutations_killed": 2,
|
||||||
|
"mutation_score": 100.0,
|
||||||
|
"notes": "UTF-8 validation and sort order both tested."
|
||||||
|
},
|
||||||
|
"internal/sheet/validate.go": {
|
||||||
|
"status": "completed",
|
||||||
|
"covering_tests": ["internal/sheet/validate_test.go"],
|
||||||
|
"last_tested": "2026-02-15T00:00:00Z",
|
||||||
|
"mutations_applied": 10,
|
||||||
|
"mutations_killed": 10,
|
||||||
|
"mutation_score": 100.0,
|
||||||
|
"notes": "Perfect score. All security checks well-tested."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"global_statistics": {
|
||||||
|
"total_modules": 10,
|
||||||
|
"completed_modules": 10,
|
||||||
|
"total_mutations": 56,
|
||||||
|
"total_killed": 54,
|
||||||
|
"total_survived": 2,
|
||||||
|
"overall_score": 96.4
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -157,3 +157,28 @@ func TestInvalidateDuplicateCheatpathPaths(t *testing.T) {
|
|||||||
t.Errorf("failed to invalidate config with cheatpaths with duplicate paths")
|
t.Errorf("failed to invalidate config with cheatpaths with duplicate paths")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestInvalidateInvalidCheatpath asserts that configs containing a cheatpath
|
||||||
|
// with an empty name are invalidated
|
||||||
|
func TestInvalidateInvalidCheatpath(t *testing.T) {
|
||||||
|
|
||||||
|
// mock a config with a cheatpath that has an empty name
|
||||||
|
conf := Config{
|
||||||
|
Colorize: true,
|
||||||
|
Editor: "vim",
|
||||||
|
Formatter: "terminal16m",
|
||||||
|
Cheatpaths: []cheatpath.Path{
|
||||||
|
cheatpath.Path{
|
||||||
|
Name: "",
|
||||||
|
Path: "/foo",
|
||||||
|
ReadOnly: false,
|
||||||
|
Tags: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// assert that an error is returned
|
||||||
|
if err := conf.Validate(); err == nil {
|
||||||
|
t.Errorf("failed to invalidate config with invalid cheatpath (empty name)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,3 +10,13 @@ func TestIndent(t *testing.T) {
|
|||||||
t.Errorf("failed to indent: want: %s, got: %s", want, got)
|
t.Errorf("failed to indent: want: %s, got: %s", want, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestIndentTrimsWhitespace asserts that Indent trims leading and trailing
|
||||||
|
// whitespace before indenting
|
||||||
|
func TestIndentTrimsWhitespace(t *testing.T) {
|
||||||
|
got := Indent(" foo\nbar\nbaz \n")
|
||||||
|
want := "\tfoo\n\tbar\n\tbaz\n"
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("failed to trim and indent: want: %q, got: %q", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,3 +40,55 @@ func TestColorize(t *testing.T) {
|
|||||||
t.Errorf("colorized text lost original content: %q", s.Text)
|
t.Errorf("colorized text lost original content: %q", s.Text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestColorizeDefaultSyntax asserts that when no syntax is specified, the
|
||||||
|
// default ("bash") is used and produces the same output as an explicit "bash"
|
||||||
|
func TestColorizeDefaultSyntax(t *testing.T) {
|
||||||
|
|
||||||
|
conf := config.Config{
|
||||||
|
Formatter: "terminal16m",
|
||||||
|
Style: "monokai",
|
||||||
|
}
|
||||||
|
|
||||||
|
// use bash-specific content that tokenizes differently across lexers
|
||||||
|
code := "if [[ -f /etc/passwd ]]; then\n echo \"found\" | grep -o found\nfi"
|
||||||
|
|
||||||
|
// colorize with empty syntax (should default to "bash")
|
||||||
|
noSyntax := Sheet{Text: code}
|
||||||
|
noSyntax.Colorize(conf)
|
||||||
|
|
||||||
|
// colorize with explicit "bash" syntax
|
||||||
|
bashSyntax := Sheet{Text: code, Syntax: "bash"}
|
||||||
|
bashSyntax.Colorize(conf)
|
||||||
|
|
||||||
|
// both should produce the same output
|
||||||
|
if noSyntax.Text != bashSyntax.Text {
|
||||||
|
t.Errorf(
|
||||||
|
"default syntax does not match explicit bash:\ndefault: %q\nexplicit: %q",
|
||||||
|
noSyntax.Text,
|
||||||
|
bashSyntax.Text,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestColorizeExplicitSyntax asserts that a specified syntax is used
|
||||||
|
func TestColorizeExplicitSyntax(t *testing.T) {
|
||||||
|
|
||||||
|
conf := config.Config{
|
||||||
|
Formatter: "terminal16m",
|
||||||
|
Style: "monokai",
|
||||||
|
}
|
||||||
|
|
||||||
|
// colorize as bash
|
||||||
|
bashSheet := Sheet{Text: "def hello():\n pass", Syntax: "bash"}
|
||||||
|
bashSheet.Colorize(conf)
|
||||||
|
|
||||||
|
// colorize as python
|
||||||
|
pySheet := Sheet{Text: "def hello():\n pass", Syntax: "python"}
|
||||||
|
pySheet.Colorize(conf)
|
||||||
|
|
||||||
|
// different lexers should produce different output for Python code
|
||||||
|
if bashSheet.Text == pySheet.Text {
|
||||||
|
t.Error("bash and python syntax produced identical output")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -93,3 +93,20 @@ To foo the bar: baz`
|
|||||||
t.Errorf("failed to parse text: want: %s, got: %s", markdown, text)
|
t.Errorf("failed to parse text: want: %s, got: %s", markdown, text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestHasMalformedYAML asserts that an error is returned when the frontmatter
|
||||||
|
// contains invalid YAML that cannot be unmarshalled
|
||||||
|
func TestHasMalformedYAML(t *testing.T) {
|
||||||
|
|
||||||
|
// stub cheatsheet content with syntactically invalid YAML between the
|
||||||
|
// delimiters (a bare tab character followed by unquoted colon)
|
||||||
|
markdown := "---\n\t:\t:\n---\nBody text here"
|
||||||
|
|
||||||
|
// parse the frontmatter
|
||||||
|
_, _, err := parse(markdown)
|
||||||
|
|
||||||
|
// assert that an error was returned due to YAML unmarshal failure
|
||||||
|
if err == nil {
|
||||||
|
t.Error("failed to error on malformed YAML frontmatter")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user