Skip to content

Commit

Permalink
feat: add react example
Browse files Browse the repository at this point in the history
  • Loading branch information
jungs1 committed Jul 2, 2024
1 parent 7225002 commit 044951b
Show file tree
Hide file tree
Showing 50 changed files with 5,348 additions and 280 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ htmlcov/
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
Expand Down Expand Up @@ -158,4 +159,7 @@ cython_debug/
#.idea/
.DS_Store

/logs
logs
vendor
*.lcov
dist*
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Mutation testing is used by big tech companies like [Google](https://research.go

Examples:

- [React Example](/examples/vite-react-testing-ts/)
- [Go Example](/examples/go_webservice/)
- [Java Example](/examples/java_maven/)
- [JavaScript Example](/examples/js_vanilla/)
Expand Down
16 changes: 14 additions & 2 deletions examples/go_webservice/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
# Go Webservice Example

This example is from CodiumAI’s cover-agent [repository](https://github.com/Codium-ai/cover-agent/tree/main/templated_tests/go_webservice). The unit tests were generated using CodiumAI’s cover agent, and Mutahunter was used to verify the effectiveness of the test suite.

Coverage report was already generated. Now, we will run Mutahunter to analyze the tests.
## First generate test coverage report

```bash
go build
go install github.com/stretchr/testify/assert
go install github.com/axw/gocov/gocov
go install github.com/AlekSi/gocov-xml
go test -v -cover
go test -coverprofile=coverage.out
gocov convert coverage.out | gocov-xml > coverage.xml
```

### Running Mutahunter to analyze the tests
## Running Mutahunter to analyze the tests

```bash
mutahunter run --test-command "go test" --test-file-path "app_test.go" --code-coverage-report-path "coverage.xml" --only-mutate-file-paths "app.go"
Expand Down
174 changes: 87 additions & 87 deletions examples/go_webservice/coverage.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
<coverage line-rate="0.9655172" branch-rate="0" lines-covered="56" lines-valid="58" branches-covered="0" branches-valid="0" complexity="0" version="" timestamp="1718935027429">
<coverage line-rate="0.9655172" branch-rate="0" lines-covered="56" lines-valid="58" branches-covered="0" branches-valid="0" complexity="0" version="" timestamp="1719892806698">
<packages>
<package name="go_webservice" line-rate="0.9655172" branch-rate="0" complexity="0" line-count="58" line-hits="56">
<classes>
Expand All @@ -10,176 +10,176 @@
<lines>
<line number="13" hits="1"></line>
<line number="15" hits="1"></line>
<line number="19" hits="1"></line>
<line number="23" hits="1"></line>
<line number="30" hits="1"></line>
<line number="37" hits="1"></line>
<line number="44" hits="1"></line>
<line number="55" hits="1"></line>
<line number="61" hits="1"></line>
<line number="71" hits="1"></line>
<line number="77" hits="1"></line>
<line number="84" hits="1"></line>
<line number="89" hits="1"></line>
</lines>
</method>
<method name="@15:18" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="16" hits="1"></line>
</lines>
</method>
<method name="@19:30" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="17" hits="1"></line>
<line number="18" hits="1"></line>
<line number="19" hits="1"></line>
<line number="20" hits="1"></line>
</lines>
</method>
<method name="@23:33" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="21" hits="1"></line>
<line number="22" hits="1"></line>
<line number="23" hits="1"></line>
<line number="24" hits="1"></line>
<line number="25" hits="1"></line>
<line number="26" hits="1"></line>
<line number="27" hits="1"></line>
</lines>
</method>
<method name="@30:38" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="welcomeHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="31" hits="1"></line>
<line number="32" hits="1"></line>
<line number="33" hits="1"></line>
<line number="34" hits="1"></line>
</lines>
</method>
<method name="@37:38" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="currentDateHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="35" hits="1"></line>
</lines>
</method>
<method name="addHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="38" hits="1"></line>
<line number="39" hits="1"></line>
<line number="40" hits="1"></line>
<line number="41" hits="1"></line>
<line number="42" hits="1"></line>
</lines>
</method>
<method name="@44:36" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="subtractHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="45" hits="1"></line>
<line number="46" hits="1"></line>
<line number="47" hits="1"></line>
<line number="48" hits="1"></line>
<line number="49" hits="1"></line>
<line number="51" hits="1"></line>
<line number="52" hits="1"></line>
</lines>
</method>
<method name="@55:32" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="multiplyHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="53" hits="1"></line>
<line number="54" hits="1"></line>
<line number="55" hits="1"></line>
<line number="56" hits="1"></line>
<line number="57" hits="1"></line>
<line number="58" hits="1"></line>
</lines>
</method>
<method name="@61:30" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="divideHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="60" hits="1"></line>
<line number="61" hits="1"></line>
<line number="62" hits="1"></line>
<line number="63" hits="1"></line>
<line number="64" hits="1"></line>
<line number="65" hits="1"></line>
<line number="66" hits="1"></line>
<line number="67" hits="1"></line>
<line number="68" hits="1"></line>
</lines>
</method>
<method name="@71:37" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="squareHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="71" hits="1"></line>
<line number="72" hits="1"></line>
<line number="73" hits="1"></line>
<line number="74" hits="1"></line>
</lines>
</method>
<method name="@77:37" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="sqrtHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="77" hits="1"></line>
<line number="78" hits="1"></line>
<line number="79" hits="1"></line>
<line number="80" hits="1"></line>
<line number="81" hits="1"></line>
<line number="82" hits="1"></line>
<line number="83" hits="1"></line>
</lines>
</method>
<method name="@84:31" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="isPalindromeHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="85" hits="1"></line>
<line number="86" hits="1"></line>
<line number="87" hits="1"></line>
<line number="88" hits="1"></line>
<line number="89" hits="1"></line>
</lines>
</method>
<method name="main" signature="" line-rate="0" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="daysUntilNewYearHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="93" hits="0"></line>
<line number="94" hits="0"></line>
<line number="93" hits="1"></line>
<line number="94" hits="1"></line>
<line number="95" hits="1"></line>
<line number="96" hits="1"></line>
</lines>
</method>
<method name="reverse" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<method name="echoHandler" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="98" hits="1"></line>
<line number="99" hits="1"></line>
<line number="100" hits="1"></line>
<line number="102" hits="1"></line>
<line number="101" hits="1"></line>
</lines>
</method>
<method name="reverse" signature="" line-rate="1" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="105" hits="1"></line>
<line number="106" hits="1"></line>
<line number="107" hits="1"></line>
<line number="109" hits="1"></line>
</lines>
</method>
<method name="main" signature="" line-rate="0" branch-rate="0" complexity="0" line-count="0" line-hits="0">
<lines>
<line number="113" hits="0"></line>
<line number="114" hits="0"></line>
</lines>
</method>
</methods>
<lines>
<line number="13" hits="1"></line>
<line number="15" hits="1"></line>
<line number="19" hits="1"></line>
<line number="23" hits="1"></line>
<line number="30" hits="1"></line>
<line number="37" hits="1"></line>
<line number="44" hits="1"></line>
<line number="55" hits="1"></line>
<line number="61" hits="1"></line>
<line number="71" hits="1"></line>
<line number="77" hits="1"></line>
<line number="84" hits="1"></line>
<line number="89" hits="1"></line>
<line number="16" hits="1"></line>
<line number="17" hits="1"></line>
<line number="18" hits="1"></line>
<line number="19" hits="1"></line>
<line number="20" hits="1"></line>
<line number="21" hits="1"></line>
<line number="22" hits="1"></line>
<line number="23" hits="1"></line>
<line number="24" hits="1"></line>
<line number="25" hits="1"></line>
<line number="26" hits="1"></line>
<line number="27" hits="1"></line>
<line number="31" hits="1"></line>
<line number="32" hits="1"></line>
<line number="33" hits="1"></line>
<line number="34" hits="1"></line>
<line number="38" hits="1"></line>
<line number="35" hits="1"></line>
<line number="39" hits="1"></line>
<line number="40" hits="1"></line>
<line number="41" hits="1"></line>
<line number="45" hits="1"></line>
<line number="42" hits="1"></line>
<line number="46" hits="1"></line>
<line number="47" hits="1"></line>
<line number="48" hits="1"></line>
<line number="49" hits="1"></line>
<line number="51" hits="1"></line>
<line number="52" hits="1"></line>
<line number="53" hits="1"></line>
<line number="54" hits="1"></line>
<line number="55" hits="1"></line>
<line number="56" hits="1"></line>
<line number="57" hits="1"></line>
<line number="58" hits="1"></line>
<line number="60" hits="1"></line>
<line number="61" hits="1"></line>
<line number="62" hits="1"></line>
<line number="63" hits="1"></line>
<line number="64" hits="1"></line>
<line number="65" hits="1"></line>
<line number="66" hits="1"></line>
<line number="67" hits="1"></line>
<line number="68" hits="1"></line>
<line number="71" hits="1"></line>
<line number="72" hits="1"></line>
<line number="73" hits="1"></line>
<line number="74" hits="1"></line>
<line number="77" hits="1"></line>
<line number="78" hits="1"></line>
<line number="79" hits="1"></line>
<line number="80" hits="1"></line>
<line number="81" hits="1"></line>
<line number="85" hits="1"></line>
<line number="86" hits="1"></line>
<line number="93" hits="0"></line>
<line number="94" hits="0"></line>
<line number="98" hits="1"></line>
<line number="99" hits="1"></line>
<line number="82" hits="1"></line>
<line number="83" hits="1"></line>
<line number="87" hits="1"></line>
<line number="88" hits="1"></line>
<line number="89" hits="1"></line>
<line number="93" hits="1"></line>
<line number="94" hits="1"></line>
<line number="95" hits="1"></line>
<line number="96" hits="1"></line>
<line number="100" hits="1"></line>
<line number="102" hits="1"></line>
<line number="101" hits="1"></line>
<line number="105" hits="1"></line>
<line number="106" hits="1"></line>
<line number="107" hits="1"></line>
<line number="109" hits="1"></line>
<line number="113" hits="0"></line>
<line number="114" hits="0"></line>
</lines>
</class>
</classes>
Expand Down
33 changes: 19 additions & 14 deletions examples/go_webservice/logs/_latest/debug.log
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
2024-06-29 23:00:21,955 INFO: Command line input: /Users/taikorind/.pyenv/versions/mutahunter/bin/mutahunter run --test-command go test --test-file-path app_test.go --code-coverage-report-path coverage.xml --only-mutate-file-paths app.go
2024-06-29 23:00:21,956 INFO: Starting Coverage Analysis...
2024-06-29 23:00:22,480 INFO: 🦠 Generating Mutations... 🦠
2024-06-29 23:00:26,074 INFO: Mutant 1 killed by app_test.go
2024-06-29 23:00:28,496 INFO: Mutant 2 killed by app_test.go
2024-06-29 23:00:31,019 INFO: Mutant 3 killed by app_test.go
2024-06-29 23:00:40,677 INFO: Mutant 4 killed by app_test.go
2024-06-29 23:00:44,847 INFO: Mutant 5 survived by app_test.go
2024-06-29 23:00:48,751 INFO: 🎯 Generating Mutation Report... 🎯
2024-06-29 23:00:48,752 INFO: 🦠 Total Mutants: 5 🦠
2024-06-29 23:00:48,752 INFO: 🛡️ Survived Mutants: 1 🛡️
2024-06-29 23:00:48,752 INFO: 🗡️ Killed Mutants: 4 🗡️
2024-06-29 23:00:48,752 INFO: 🎯 Mutation Coverage: 80.0% 🎯
2024-06-29 23:00:52,555 INFO: Mutation Testing Ended. Took 31s
2024-07-02 00:00:10,208 INFO: Command line input: /Users/taikorind/.pyenv/versions/mutahunter/bin/mutahunter run --test-command go test --test-file-path app_test.go --code-coverage-report-path coverage.xml --only-mutate-file-paths app.go
2024-07-02 00:00:10,211 INFO: Starting Coverage Analysis...
2024-07-02 00:00:11,205 INFO: 🦠 Generating Mutations... 🦠
2024-07-02 00:00:16,135 INFO: Mutant 1 killed by app_test.go
2024-07-02 00:00:24,707 INFO: Mutant 2 killed by app_test.go
2024-07-02 00:00:27,406 INFO: Mutant 3 killed by app_test.go
2024-07-02 00:00:30,427 INFO: Mutant 4 killed by app_test.go
2024-07-02 00:00:32,674 INFO: Mutant 5 killed by app_test.go
2024-07-02 00:00:35,087 INFO: Mutant 6 survived by app_test.go
2024-07-02 00:00:37,514 INFO: Mutant 7 survived by app_test.go
2024-07-02 00:00:40,325 INFO: Mutant 8 survived by app_test.go
2024-07-02 00:00:42,976 INFO: Mutant 9 killed by app_test.go
2024-07-02 00:00:46,984 INFO: Mutant 10 survived by app_test.go
2024-07-02 00:00:46,985 INFO: 🎯 Generating Mutation Report... 🎯
2024-07-02 00:00:46,987 INFO: 🦠 Total Mutants: 10 🦠
2024-07-02 00:00:46,987 INFO: 🛡️ Survived Mutants: 4 🛡️
2024-07-02 00:00:46,987 INFO: 🗡️ Killed Mutants: 6 🗡️
2024-07-02 00:00:46,987 INFO: 🎯 Mutation Coverage: 60.0% 🎯
2024-07-02 00:00:46,987 INFO: Mutation Testing Ended. Took 37s
5 changes: 2 additions & 3 deletions examples/go_webservice/logs/_latest/mutants/10_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,12 @@ func daysUntilNewYearHandler(c *gin.Context) {

func echoHandler(c *gin.Context) {
message := c.Param("message")
// Mutation: Simulating a Cross-Site Scripting (XSS) vulnerability by not escaping the message parameter.
c.JSON(http.StatusOK, gin.H{"message": "<script>alert('" + message + "')</script>"})
c.JSON(http.StatusOK, gin.H{"message": message})
}

func reverse(s string) string {
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
for i, j := 0, len(runes)-1; i <= j; i, j = i+1, j-1 { // Mutation: Changed condition from i < j to i <= j to test boundary condition handling.
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
Expand Down
7 changes: 5 additions & 2 deletions examples/go_webservice/logs/_latest/mutants/1_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ func SetupRouter() *gin.Engine {
router.GET("/subtract/:num1/:num2", subtractHandler)
router.GET("/multiply/:num1/:num2", multiplyHandler)
router.GET("/divide/:num1/:num2", divideHandler)
router.GET("/square/:number", sqrtHandler) // Mutation: Changed handler for square endpoint to sqrtHandler
router.GET("/square/:number", squareHandler)
router.GET("/sqrt/:number", sqrtHandler)
router.GET("/is-palindrome/:text", isPalindromeHandler)
router.GET("/days-until-new-year", daysUntilNewYearHandler)
router.GET("/days-until-new-year", func(c *gin.Context) {
// Mutation: Simulating an error by returning a 500 status code instead of calling the actual handler.
c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal Server Error"})
})
router.GET("/echo/:message", echoHandler)

return router
Expand Down
Loading

0 comments on commit 044951b

Please sign in to comment.