diff --git a/color.go b/color.go index d3906bf..6f70d4f 100644 --- a/color.go +++ b/color.go @@ -113,6 +113,40 @@ var mapResetAttributes map[Attribute]Attribute = map[Attribute]Attribute{ ReverseVideo: ResetReversed, Concealed: ResetConcealed, CrossedOut: ResetCrossedOut, + FgBlack: Attribute(39), + FgRed: Attribute(39), + FgGreen: Attribute(39), + FgYellow: Attribute(39), + FgBlue: Attribute(39), + FgMagenta: Attribute(39), + FgCyan: Attribute(39), + FgWhite: Attribute(39), + FgHiBlack: Attribute(39), + FgHiRed: Attribute(39), + FgHiGreen: Attribute(39), + FgHiYellow: Attribute(39), + FgHiBlue: Attribute(39), + FgHiMagenta: Attribute(39), + FgHiCyan: Attribute(39), + FgHiWhite: Attribute(39), + BgBlack: Attribute(49), + BgRed: Attribute(49), + BgGreen: Attribute(49), + BgYellow: Attribute(49), + BgBlue: Attribute(49), + BgMagenta: Attribute(49), + BgCyan: Attribute(49), + BgWhite: Attribute(49), + BgHiBlack: Attribute(49), + BgHiRed: Attribute(49), + BgHiGreen: Attribute(49), + BgHiYellow: Attribute(49), + BgHiBlue: Attribute(49), + BgHiMagenta: Attribute(49), + BgHiCyan: Attribute(49), + BgHiWhite: Attribute(49), + foreground: Attribute(39), + background: Attribute(49), } // Foreground text colors @@ -481,14 +515,12 @@ func (c *Color) format() string { } func (c *Color) unformat() string { - //return fmt.Sprintf("%s[%dm", escape, Reset) - //for each element in sequence let's use the specific reset escape, or the generic one if not found - format := make([]string, len(c.params)) - for i, v := range c.params { - format[i] = strconv.Itoa(int(Reset)) + //for each element in sequence let's use the specific reset escape, or skip if not found + format := make([]string, 0, len(c.params)) + for _, v := range c.params { ra, ok := mapResetAttributes[v] if ok { - format[i] = strconv.Itoa(int(ra)) + format = append(format, strconv.Itoa(int(ra))) } } diff --git a/color_test.go b/color_test.go index e22af6b..80bd67a 100644 --- a/color_test.go +++ b/color_test.go @@ -60,7 +60,7 @@ func TestColor(t *testing.T) { for _, c := range testColors { line := New(c.code).Sprintf("%s", c.text) scannedLine := fmt.Sprintf("%q", line) - colored := fmt.Sprintf("\x1b[%dm%s\x1b[0m", c.code, c.text) + colored := fmt.Sprintf("\x1b[%dm%s\x1b[39m", c.code, c.text) escapedForm := fmt.Sprintf("%q", colored) fmt.Printf("%s\t: %s\n", c.text, line) @@ -444,22 +444,22 @@ func TestNoFormatString(t *testing.T) { args []interface{} want string }{ - {BlackString, "%s", nil, "\x1b[30m%s\x1b[0m"}, - {RedString, "%s", nil, "\x1b[31m%s\x1b[0m"}, - {GreenString, "%s", nil, "\x1b[32m%s\x1b[0m"}, - {YellowString, "%s", nil, "\x1b[33m%s\x1b[0m"}, - {BlueString, "%s", nil, "\x1b[34m%s\x1b[0m"}, - {MagentaString, "%s", nil, "\x1b[35m%s\x1b[0m"}, - {CyanString, "%s", nil, "\x1b[36m%s\x1b[0m"}, - {WhiteString, "%s", nil, "\x1b[37m%s\x1b[0m"}, - {HiBlackString, "%s", nil, "\x1b[90m%s\x1b[0m"}, - {HiRedString, "%s", nil, "\x1b[91m%s\x1b[0m"}, - {HiGreenString, "%s", nil, "\x1b[92m%s\x1b[0m"}, - {HiYellowString, "%s", nil, "\x1b[93m%s\x1b[0m"}, - {HiBlueString, "%s", nil, "\x1b[94m%s\x1b[0m"}, - {HiMagentaString, "%s", nil, "\x1b[95m%s\x1b[0m"}, - {HiCyanString, "%s", nil, "\x1b[96m%s\x1b[0m"}, - {HiWhiteString, "%s", nil, "\x1b[97m%s\x1b[0m"}, + {BlackString, "%s", nil, "\x1b[30m%s\x1b[39m"}, + {RedString, "%s", nil, "\x1b[31m%s\x1b[39m"}, + {GreenString, "%s", nil, "\x1b[32m%s\x1b[39m"}, + {YellowString, "%s", nil, "\x1b[33m%s\x1b[39m"}, + {BlueString, "%s", nil, "\x1b[34m%s\x1b[39m"}, + {MagentaString, "%s", nil, "\x1b[35m%s\x1b[39m"}, + {CyanString, "%s", nil, "\x1b[36m%s\x1b[39m"}, + {WhiteString, "%s", nil, "\x1b[37m%s\x1b[39m"}, + {HiBlackString, "%s", nil, "\x1b[90m%s\x1b[39m"}, + {HiRedString, "%s", nil, "\x1b[91m%s\x1b[39m"}, + {HiGreenString, "%s", nil, "\x1b[92m%s\x1b[39m"}, + {HiYellowString, "%s", nil, "\x1b[93m%s\x1b[39m"}, + {HiBlueString, "%s", nil, "\x1b[94m%s\x1b[39m"}, + {HiMagentaString, "%s", nil, "\x1b[95m%s\x1b[39m"}, + {HiCyanString, "%s", nil, "\x1b[96m%s\x1b[39m"}, + {HiWhiteString, "%s", nil, "\x1b[97m%s\x1b[39m"}, } for i, test := range tests { @@ -479,7 +479,7 @@ func TestColor_Println_Newline(t *testing.T) { c.Println("foo") got := readRaw(t, rb) - want := "\x1b[31mfoo\x1b[0m\n" + want := "\x1b[31mfoo\x1b[39m\n" if want != got { t.Errorf("Println newline error\n\nwant: %q\n got: %q", want, got) @@ -490,7 +490,7 @@ func TestColor_Sprintln_Newline(t *testing.T) { c := New(FgRed) got := c.Sprintln("foo") - want := "\x1b[31mfoo\x1b[0m\n" + want := "\x1b[31mfoo\x1b[39m\n" if want != got { t.Errorf("Println newline error\n\nwant: %q\n got: %q", want, got) @@ -525,7 +525,7 @@ func TestColor_Fprintln(t *testing.T) { t.Errorf("Fprint error: %v", err) } got := rb.String() - want := "\x1b[31mfoo bar\x1b[0m\n" + want := "\x1b[31mfoo bar\x1b[39m\n" if want != got { t.Errorf("Fprintln error\n\nwant: %q\n got: %q", want, got) @@ -561,7 +561,7 @@ func TestColor_Fprintln_Newline(t *testing.T) { c.Fprintln(rb, "foo") got := readRaw(t, rb) - want := "\x1b[31mfoo\x1b[0m\n" + want := "\x1b[31mfoo\x1b[39m\n" if want != got { t.Errorf("Println newline error\n\nwant: %q\n got: %q", want, got) @@ -591,7 +591,7 @@ func TestIssue206_1(t *testing.T) { fmt.Println(line) result := fmt.Sprintf("%v", line) - const expectedResult = "\x1b[36mword1 \x1b[4mword2\x1b[24m word3 \x1b[4mword4\x1b[24m\x1b[0m" + const expectedResult = "\x1b[36mword1 \x1b[4mword2\x1b[24m word3 \x1b[4mword4\x1b[24m\x1b[39m" if !bytes.Equal([]byte(result), []byte(expectedResult)) { t.Errorf("Expecting %v, got '%v'\n", expectedResult, result) @@ -607,7 +607,7 @@ func TestIssue206_2(t *testing.T) { fmt.Println(line) result := fmt.Sprintf("%v", line) - const expectedResult = "\x1b[32m\x1b[4munderlined regular green\x1b[24m\x1b[0m \x1b[31m\x1b[1mbold red\x1b[22m\x1b[0m" + const expectedResult = "\x1b[32m\x1b[4munderlined regular green\x1b[24m\x1b[39m \x1b[31m\x1b[1mbold red\x1b[22m\x1b[39m" if !bytes.Equal([]byte(result), []byte(expectedResult)) { t.Errorf("Expecting %v, got '%v'\n", expectedResult, result) @@ -625,7 +625,7 @@ func TestIssue218(t *testing.T) { fmt.Println(params...) fmt.Print(result) - const expectedResult = "\x1b[36mword1 word2 word3 word4\n\x1b[0m\n" + const expectedResult = "\x1b[36mword1 word2 word3 word4\n\x1b[39m\n" if !bytes.Equal([]byte(result), []byte(expectedResult)) { t.Errorf("Sprintln: Expecting %v (%v), got '%v (%v)'\n", expectedResult, []byte(expectedResult), result, []byte(result)) @@ -662,3 +662,26 @@ func TestRGB(t *testing.T) { }) } } + +func TestIssue233(t *testing.T) { + NoColor = false + t.Cleanup(func() { NoColor = true }) + + a := New(FgRed).SprintFunc()("aaa") + b := New(FgBlue).SprintFunc()("bbb") + c := New(Underline).SprintFunc()(a + b) + + const expectedA = "\x1b[31maaa\x1b[39m" + const expectedB = "\x1b[34mbbb\x1b[39m" + const expectedC = "\x1b[4m\x1b[31maaa\x1b[39m\x1b[34mbbb\x1b[39m\x1b[24m" + + if a != expectedA { + t.Errorf("a:\n want: %q\n got: %q", expectedA, a) + } + if b != expectedB { + t.Errorf("b:\n want: %q\n got: %q", expectedB, b) + } + if c != expectedC { + t.Errorf("c:\n want: %q\n got: %q", expectedC, c) + } +}