├── .github └── workflows │ └── ci.yaml ├── LICENSE.txt ├── README.md ├── gotest └── test └── smoke ├── fail_test.go ├── pass_test.go └── run.rb /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | tests: 6 | name: Tests 7 | strategy: 8 | matrix: 9 | os: [ubuntu-latest, macos-latest] 10 | fail-fast: false 11 | runs-on: ${{ matrix.os }} 12 | steps: 13 | - uses: ruby/setup-ruby@v1 14 | with: 15 | ruby-version: '3' 16 | - uses: actions/setup-go@v3 17 | - uses: actions/checkout@v3 18 | - run: ruby ./test/smoke/run.rb 19 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | the MIT License 2 | 3 | Copyright (c) 2018 rhysd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 17 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 20 | THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Colorize `go test` 2 | ================== 3 | [![CI][ci-badge]][ci] 4 | 5 | This repository provides a tiny script to colorize `go test`. 6 | 7 | ![sreenshot](https://github.com/rhysd/ss/blob/master/gotest/main.png?raw=true) 8 | 9 | ## Prerequisites 10 | 11 | - `/bin/bash` 12 | - `sed` 13 | 14 | ## Installation 15 | 16 | 1. Copy [`gotest`](gotest) script to your `$PATH` directory 17 | 2. Give it executable permission with `chmod +x` 18 | 19 | On CI, directly downloading `gotest` with `curl` would be sufficient in most cases as follows. 20 | 21 | ```sh 22 | $ curl -L https://raw.githubusercontent.com/rhysd/gotest/master/gotest > gotest 23 | $ bash ./gotest 24 | ``` 25 | 26 | ## Usage 27 | 28 | ``` 29 | $ gotest [args...] 30 | ``` 31 | 32 | Arguments are the same as `go test` but `-v` is always implied. 33 | 34 | The reason I created this in spite of [rakyll/gotest](https://github.com/rakyll/gotest) is that 35 | my requirements can be met with only ~20 lines of shell script. Smaller script is better because 36 | it can be modified/fixed easily and easy to understand and easy to test. 37 | 38 | ## Change colors 39 | 40 | If you want to change colors, please modify [the script](gotest) directly. The color definitions at 41 | top of the script (e.g. `92` for green, `91` for red) are [ANSI escape sequences for colors][ansi-colors]. 42 | Please modify them to use your favorite colors. 43 | 44 | ## License 45 | 46 | [MIT License](LICENSE.txt) 47 | 48 | [ci-badge]: https://github.com/rhysd/gotest/actions/workflows/ci.yaml/badge.svg 49 | [ci]: https://github.com/rhysd/gotest/actions/workflows/ci.yaml 50 | [ansi-colors]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors 51 | -------------------------------------------------------------------------------- /gotest: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # gotest 4 | # 5 | # the MIT License 6 | # 7 | # Copyright (c) 2018 rhysd 8 | 9 | # Usage: 10 | # Put this file in $PATH directory and give it executable permission by `chmod +x` 11 | # Arguments are the same as `go test` but -v is implied. 12 | 13 | GREEN='' 14 | RED='' 15 | YELLOW='' 16 | GRAY='' 17 | BOLD='' 18 | RESET='' 19 | 20 | pass="s/^[[:space:]]*--- PASS: .+$/${GREEN}&${RESET}/;" 21 | fail="s/^[[:space:]]*--- FAIL: .+$/${RED}&${RESET}/;" 22 | skip="s/^[[:space:]]*--- SKIP: .+$/${YELLOW}&${RESET}/;" 23 | result_pass="s/^PASS$/${BOLD}${GREEN}&${RESET}/;" 24 | result_fail="s/^FAIL$/${BOLD}${RED}&${RESET}/;" 25 | run="s/^=== RUN /${BOLD}&${RESET}/;" 26 | elapsed="s/\\([[:digit:]]+\\.[[:digit:]]+s\\)/${GRAY}&${RESET}/;" 27 | 28 | go test -v ${1+"$@"} | sed -E "$pass $fail $skip $result_pass $result_fail $run $elapsed" 29 | exit "${PIPESTATUS[0]}" 30 | -------------------------------------------------------------------------------- /test/smoke/fail_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestFailSkip(t *testing.T) { 8 | t.Skip("for testing gotest") 9 | } 10 | 11 | func TestFailPass(t *testing.T) { 12 | // Do nothing 13 | } 14 | 15 | func TestFailFail(t *testing.T) { 16 | t.Fatal() 17 | } 18 | -------------------------------------------------------------------------------- /test/smoke/pass_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestPassSkip(t *testing.T) { 8 | t.Skip("for testing gotest") 9 | } 10 | 11 | func TestPassPass(t *testing.T) { 12 | // Do nothing 13 | } 14 | -------------------------------------------------------------------------------- /test/smoke/run.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | GREEN='' 4 | RED='' 5 | YELLOW='' 6 | GRAY='' 7 | BOLD='' 8 | RESET='' 9 | 10 | abort 'This script must be run from root of repository' unless Dir.exist? '.git' 11 | 12 | def check_run(out, f) 13 | abort "#{f}: fail because bold text is not rendered:\n#{out}" unless out.include? "#{BOLD}=== RUN " 14 | end 15 | def check_skip(out, f) 16 | abort "#{f}: fail because yellow text is not rendered:\n#{out}" unless out.include? "#{YELLOW}--- SKIP: " 17 | end 18 | def check_pass(out, f) 19 | abort "#{f}: fail because green text is not rendered:\n#{out}" unless out.include? "#{GREEN}--- PASS: " 20 | end 21 | def check_fail(out, f) 22 | abort "#{f}: fail because red text is not rendered:\n#{out}" unless out.include? "#{RED}--- FAIL: " 23 | end 24 | def check_result(out, f, text) 25 | abort "#{f}: fail because result is not rendered:\n#{out}" unless out.include? "#{BOLD}#{text}#{RESET}" 26 | end 27 | 28 | f = 'pass_test.go' 29 | out = `./gotest ./test/smoke/#{f}` 30 | abort "#{f}: fail due to non-zero exit status: #{$?}" unless $?.success? 31 | 32 | check_run(out, f) 33 | check_skip(out, f) 34 | check_pass(out, f) 35 | check_result(out, f, "#{GREEN}PASS") 36 | 37 | f = 'fail_test.go' 38 | out = `./gotest ./test/smoke/#{f}` 39 | abort "#{f}: fail due to non-zero exit status: #{$?}" if $?.success? 40 | check_run(out, f) 41 | check_skip(out, f) 42 | check_pass(out, f) 43 | check_fail(out, f) 44 | 45 | check_result(out, f, "#{RED}FAIL") 46 | 47 | puts 'OK' 48 | --------------------------------------------------------------------------------