diff --git a/README.md b/README.md index ed86817c..616eb541 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ Commonly used formats (see `--help` for a full list): * `dots` - print a character for each test. * `pkgname` (default) - print a line for each package. * `testname` - print a line for each test and package. + * `testdox` - print a sentence for each test using [gotestdox](https://github.com/bitfield/gotestdox). * `standard-quiet` - the standard `go test` format. * `standard-verbose` - the standard `go test -v` format. diff --git a/cmd/main.go b/cmd/main.go index 86df7675..cb522abb 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -140,6 +140,7 @@ Formats: pkgname print a line for each package pkgname-and-test-fails print a line for each package and failed test output testname print a line for each test and package + testdox print a sentence for each test using gotestdox github-actions testname format with github actions log grouping standard-quiet standard go test format standard-verbose standard go test -v format diff --git a/cmd/testdata/gotestsum-help-text b/cmd/testdata/gotestsum-help-text index 4ff8982f..5a2e2aa5 100644 --- a/cmd/testdata/gotestsum-help-text +++ b/cmd/testdata/gotestsum-help-text @@ -36,6 +36,7 @@ Formats: pkgname print a line for each package pkgname-and-test-fails print a line for each package and failed test output testname print a line for each test and package + testdox print a sentence for each test using gotestdox github-actions testname format with github actions log grouping standard-quiet standard go test format standard-verbose standard go test -v format diff --git a/go.mod b/go.mod index 86e78cdc..5e5ef66a 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,16 @@ module gotest.tools/gotestsum require ( + github.com/bitfield/gotestdox v0.2.1 github.com/dnephin/pflag v1.0.7 - github.com/fatih/color v1.13.0 + github.com/fatih/color v1.15.0 github.com/fsnotify/fsnotify v1.5.4 - github.com/google/go-cmp v0.5.8 + github.com/google/go-cmp v0.5.9 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/mattn/go-colorable v0.1.12 // indirect - golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 - golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 - golang.org/x/tools v0.1.11 + golang.org/x/sync v0.3.0 + golang.org/x/sys v0.10.0 + golang.org/x/term v0.10.0 + golang.org/x/tools v0.11.0 gotest.tools/v3 v3.3.0 ) diff --git a/go.sum b/go.sum index 8f8ed3ba..cbd23a8b 100644 --- a/go.sum +++ b/go.sum @@ -1,67 +1,87 @@ +github.com/bitfield/gotestdox v0.2.1 h1:Zj8IMLAO5/oiAKoMmtN96eyFiPZraJRTH2p0zDgtxc0= +github.com/bitfield/gotestdox v0.2.1/go.mod h1:D+gwtS0urjBrzguAkTM2wodsTQYFHdpx8eqRJ3N+9pY= github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM= -golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY= -golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/testjson/format.go b/testjson/format.go index f298eb01..8efc2958 100644 --- a/testjson/format.go +++ b/testjson/format.go @@ -5,8 +5,10 @@ import ( "fmt" "io" "os" + "sort" "strings" + "github.com/bitfield/gotestdox" "github.com/fatih/color" ) @@ -77,11 +79,65 @@ func standardJSONFormat(out io.Writer) EventFormatter { func testNameFormatTestEvent(out io.Writer, event TestEvent) { pkgPath := RelativePackagePath(event.Package) - fmt.Fprintf(out, "%s %s%s %s\n", + fmt.Fprintf(out, "%s %s%s (%.2fs)\n", colorEvent(event)(strings.ToUpper(string(event.Action))), joinPkgToTestName(pkgPath, event.Test), formatRunID(event.RunID), - fmt.Sprintf("(%.2fs)", event.Elapsed)) + event.Elapsed) +} + +func testDoxFormat(out io.Writer, opts FormatOptions) EventFormatter { + buf := bufio.NewWriter(out) + type Result struct { + Event TestEvent + Sentence string + } + getIcon := icon + if opts.UseHiVisibilityIcons { + getIcon = iconHiVis + } + results := map[string][]Result{} + return eventFormatterFunc(func(event TestEvent, exec *Execution) error { + switch { + case event.PackageEvent(): + if !event.Action.IsTerminal() { + return nil + } + if opts.HideEmptyPackages && len(results[event.Package]) == 0 { + return nil + } + fmt.Fprintf(buf, "%s:\n", event.Package) + tests := results[event.Package] + sort.Slice(tests, func(i, j int) bool { + return tests[i].Sentence < tests[j].Sentence + }) + for _, r := range tests { + fmt.Fprintf(buf, " %s %s (%.2fs)\n", + getIcon(r.Event.Action), + r.Sentence, + r.Event.Elapsed) + } + fmt.Fprintln(buf) + return buf.Flush() + case event.Action.IsTerminal(): + // Fuzz test cases tend not to have interesting names, + // so only report these if they're failures + if isFuzzCase(event) { + return nil + } + results[event.Package] = append(results[event.Package], Result{ + Event: event, + Sentence: gotestdox.Prettify(event.Test), + }) + } + return nil + }) +} + +func isFuzzCase(event TestEvent) bool { + return strings.HasPrefix(event.Test, "Fuzz") && + event.Action == ActionPass && + TestName(event.Test).IsSubTest() } func testNameFormat(out io.Writer) EventFormatter { @@ -188,40 +244,59 @@ func pkgNameFormat(out io.Writer, opts FormatOptions) eventFormatterFunc { } } +func icon(action Action) string { + switch action { + case ActionPass: + return color.GreenString("✓") + case ActionSkip: + return color.YellowString("∅") + case ActionFail: + return color.RedString("✖") + default: + return "" + } +} + +func iconHiVis(action Action) string { + switch action { + case ActionPass: + return "✅" + case ActionSkip: + return "➖" + case ActionFail: + return "❌" + default: + return "" + } +} + func shortFormatPackageEvent(opts FormatOptions, event TestEvent, exec *Execution) string { pkg := exec.Package(event.Package) - var iconSkipped, iconSuccess, iconFailure string + getIcon := icon if opts.UseHiVisibilityIcons { - iconSkipped = "➖" - iconSuccess = "✅" - iconFailure = "❌" - } else { - iconSkipped = "∅" - iconSuccess = "✓" - iconFailure = "✖" + getIcon = iconHiVis } fmtEvent := func(action string) string { return action + " " + packageLine(event, exec.Package(event.Package)) } - withColor := colorEvent(event) switch event.Action { case ActionSkip: if opts.HideEmptyPackages { return "" } - return fmtEvent(withColor(iconSkipped)) + return fmtEvent(getIcon(event.Action)) case ActionPass: if pkg.Total == 0 { if opts.HideEmptyPackages { return "" } - return fmtEvent(withColor(iconSkipped)) + return fmtEvent(getIcon(ActionSkip)) } - return fmtEvent(withColor(iconSuccess)) + return fmtEvent(getIcon(event.Action)) case ActionFail: - return fmtEvent(withColor(iconFailure)) + return fmtEvent(getIcon(event.Action)) } return "" } @@ -312,6 +387,8 @@ func NewEventFormatter(out io.Writer, format string, formatOpts FormatOptions) E return dotsFormatV1(out) case "dots-v2": return newDotFormatter(out, formatOpts) + case "gotestdox", "testdox": + return testDoxFormat(out, formatOpts) case "testname", "short-verbose": if os.Getenv("GITHUB_ACTIONS") == "true" { return githubActionsFormat(out) diff --git a/testjson/format_test.go b/testjson/format_test.go index b2b4605c..fed4862b 100644 --- a/testjson/format_test.go +++ b/testjson/format_test.go @@ -86,6 +86,13 @@ func TestFormats_DefaultGoTestJson(t *testing.T) { } testCases := []testCase{ + { + name: "testdox", + format: func(out io.Writer) EventFormatter { + return testDoxFormat(out, FormatOptions{}) + }, + expectedOut: "format/testdox.out", + }, { name: "testname", format: testNameFormat, @@ -176,6 +183,13 @@ func TestFormats_Coverage(t *testing.T) { } testCases := []testCase{ + { + name: "testdox", + format: func(out io.Writer) EventFormatter { + return testDoxFormat(out, FormatOptions{}) + }, + expectedOut: "format/testdox-coverage.out", + }, { name: "testname", format: testNameFormat, @@ -244,6 +258,13 @@ func TestFormats_Shuffle(t *testing.T) { } testCases := []testCase{ + { + name: "testdox", + format: func(out io.Writer) EventFormatter { + return testDoxFormat(out, FormatOptions{}) + }, + expectedOut: "format/testdox-shuffle.out", + }, { name: "testname", format: testNameFormat, diff --git a/testjson/testdata/format/testdox-coverage.out b/testjson/testdata/format/testdox-coverage.out new file mode 100644 index 00000000..fe2d7c31 --- /dev/null +++ b/testjson/testdata/format/testdox-coverage.out @@ -0,0 +1,52 @@ +gotest.tools/gotestsum/testjson/internal/badmain: + +gotest.tools/gotestsum/testjson/internal/good: + ✓ Nested success (0.00s) + ✓ Nested success a (0.00s) + ✓ Nested success a sub (0.00s) + ✓ Nested success b (0.00s) + ✓ Nested success b sub (0.00s) + ✓ Nested success c (0.00s) + ✓ Nested success c sub (0.00s) + ✓ Nested success d (0.00s) + ✓ Nested success d sub (0.00s) + ✓ Parallel the first (0.01s) + ✓ Parallel the second (0.01s) + ✓ Parallel the third (0.00s) + ✓ Passed (0.00s) + ✓ Passed with log (0.00s) + ✓ Passed with stdout (0.00s) + ∅ Skipped (0.00s) + ∅ Skipped wit log (0.00s) + ✓ With stderr (0.00s) + +gotest.tools/gotestsum/testjson/internal/stub: + ✖ Failed (0.00s) + ✖ Failed with stderr (0.00s) + ✓ Nested success (0.00s) + ✓ Nested success a (0.00s) + ✓ Nested success a sub (0.00s) + ✓ Nested success b (0.00s) + ✓ Nested success b sub (0.00s) + ✓ Nested success c (0.00s) + ✓ Nested success c sub (0.00s) + ✓ Nested success d (0.00s) + ✓ Nested success d sub (0.00s) + ✖ Nested with failure (0.00s) + ✓ Nested with failure a (0.00s) + ✓ Nested with failure a sub (0.00s) + ✓ Nested with failure b (0.00s) + ✓ Nested with failure b sub (0.00s) + ✖ Nested with failure c (0.00s) + ✓ Nested with failure d (0.00s) + ✓ Nested with failure d sub (0.00s) + ✓ Parallel the first (0.01s) + ✓ Parallel the second (0.01s) + ✓ Parallel the third (0.00s) + ✓ Passed (0.00s) + ✓ Passed with log (0.00s) + ✓ Passed with stdout (0.00s) + ∅ Skipped (0.00s) + ∅ Skipped wit log (0.00s) + ✓ With stderr (0.00s) + diff --git a/testjson/testdata/format/testdox-shuffle.out b/testjson/testdata/format/testdox-shuffle.out new file mode 100644 index 00000000..825669b2 --- /dev/null +++ b/testjson/testdata/format/testdox-shuffle.out @@ -0,0 +1,67 @@ +gotest.tools/gotestsum/testjson/internal/badmain: + +gotest.tools/gotestsum/testjson/internal/good: + ✓ Nested success (0.00s) + ✓ Nested success a (0.00s) + ✓ Nested success a sub (0.00s) + ✓ Nested success b (0.00s) + ✓ Nested success b sub (0.00s) + ✓ Nested success c (0.00s) + ✓ Nested success c sub (0.00s) + ✓ Nested success d (0.00s) + ✓ Nested success d sub (0.00s) + ✓ Parallel the first (0.01s) + ✓ Parallel the second (0.01s) + ✓ Parallel the third (0.00s) + ✓ Passed (0.00s) + ✓ Passed with log (0.00s) + ✓ Passed with stdout (0.00s) + ∅ Skipped (0.00s) + ∅ Skipped wit log (0.00s) + ✓ With stderr (0.00s) + +gotest.tools/gotestsum/testjson/internal/parallelfails: + ✖ Nested parallel failures (0.00s) + ✖ Nested parallel failures a (0.00s) + ✖ Nested parallel failures b (0.00s) + ✖ Nested parallel failures c (0.00s) + ✖ Nested parallel failures d (0.00s) + ✖ Parallel the first (0.01s) + ✖ Parallel the second (0.01s) + ✖ Parallel the third (0.00s) + ✓ Passed (0.00s) + ✓ Passed with log (0.00s) + ✓ Passed with stdout (0.00s) + ✓ With stderr (0.00s) + +gotest.tools/gotestsum/testjson/internal/withfails: + ✖ Failed (0.00s) + ✖ Failed with stderr (0.00s) + ✓ Nested success (0.00s) + ✓ Nested success a (0.00s) + ✓ Nested success a sub (0.00s) + ✓ Nested success b (0.00s) + ✓ Nested success b sub (0.00s) + ✓ Nested success c (0.00s) + ✓ Nested success c sub (0.00s) + ✓ Nested success d (0.00s) + ✓ Nested success d sub (0.00s) + ✖ Nested with failure (0.00s) + ✓ Nested with failure a (0.00s) + ✓ Nested with failure a sub (0.00s) + ✓ Nested with failure b (0.00s) + ✓ Nested with failure b sub (0.00s) + ✖ Nested with failure c (0.00s) + ✓ Nested with failure d (0.00s) + ✓ Nested with failure d sub (0.00s) + ✓ Parallel the first (0.01s) + ✓ Parallel the second (0.01s) + ✓ Parallel the third (0.00s) + ✓ Passed (0.00s) + ✓ Passed with log (0.00s) + ✓ Passed with stdout (0.00s) + ∅ Skipped (0.00s) + ∅ Skipped wit log (0.00s) + ∅ Timeout (0.00s) + ✓ With stderr (0.00s) + diff --git a/testjson/testdata/format/testdox.out b/testjson/testdata/format/testdox.out new file mode 100644 index 00000000..028e8262 --- /dev/null +++ b/testjson/testdata/format/testdox.out @@ -0,0 +1,69 @@ +gotest.tools/gotestsum/testjson/internal/badmain: + +gotest.tools/gotestsum/testjson/internal/empty: + +gotest.tools/gotestsum/testjson/internal/good: + ✓ Nested success (0.00s) + ✓ Nested success a (0.00s) + ✓ Nested success a sub (0.00s) + ✓ Nested success b (0.00s) + ✓ Nested success b sub (0.00s) + ✓ Nested success c (0.00s) + ✓ Nested success c sub (0.00s) + ✓ Nested success d (0.00s) + ✓ Nested success d sub (0.00s) + ✓ Parallel the first (0.01s) + ✓ Parallel the second (0.01s) + ✓ Parallel the third (0.00s) + ✓ Passed (0.00s) + ✓ Passed with log (0.00s) + ✓ Passed with stdout (0.00s) + ∅ Skipped (0.00s) + ∅ Skipped wit log (0.00s) + ✓ With stderr (0.00s) + +gotest.tools/gotestsum/testjson/internal/parallelfails: + ✖ Nested parallel failures (0.00s) + ✖ Nested parallel failures a (0.00s) + ✖ Nested parallel failures b (0.00s) + ✖ Nested parallel failures c (0.00s) + ✖ Nested parallel failures d (0.00s) + ✖ Parallel the first (0.01s) + ✖ Parallel the second (0.01s) + ✖ Parallel the third (0.00s) + ✓ Passed (0.00s) + ✓ Passed with log (0.00s) + ✓ Passed with stdout (0.00s) + ✓ With stderr (0.00s) + +gotest.tools/gotestsum/testjson/internal/withfails: + ✖ Failed (0.00s) + ✖ Failed with stderr (0.00s) + ✓ Nested success (0.00s) + ✓ Nested success a (0.00s) + ✓ Nested success a sub (0.00s) + ✓ Nested success b (0.00s) + ✓ Nested success b sub (0.00s) + ✓ Nested success c (0.00s) + ✓ Nested success c sub (0.00s) + ✓ Nested success d (0.00s) + ✓ Nested success d sub (0.00s) + ✖ Nested with failure (0.00s) + ✓ Nested with failure a (0.00s) + ✓ Nested with failure a sub (0.00s) + ✓ Nested with failure b (0.00s) + ✓ Nested with failure b sub (0.00s) + ✖ Nested with failure c (0.00s) + ✓ Nested with failure d (0.00s) + ✓ Nested with failure d sub (0.00s) + ✓ Parallel the first (0.01s) + ✓ Parallel the second (0.01s) + ✓ Parallel the third (0.00s) + ✓ Passed (0.00s) + ✓ Passed with log (0.00s) + ✓ Passed with stdout (0.00s) + ∅ Skipped (0.00s) + ∅ Skipped wit log (0.00s) + ∅ Timeout (0.00s) + ✓ With stderr (0.00s) +