github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/cmd/snap/color_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2018 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package main_test 21 22 import ( 23 "os" 24 "runtime" 25 // "fmt" 26 // "net/http" 27 28 "gopkg.in/check.v1" 29 30 cmdsnap "github.com/snapcore/snapd/cmd/snap" 31 "github.com/snapcore/snapd/snap" 32 ) 33 34 func setEnviron(env map[string]string) func() { 35 old := make(map[string]string, len(env)) 36 ok := make(map[string]bool, len(env)) 37 38 for k, v := range env { 39 old[k], ok[k] = os.LookupEnv(k) 40 if v != "" { 41 os.Setenv(k, v) 42 } else { 43 os.Unsetenv(k) 44 } 45 } 46 47 return func() { 48 for k := range ok { 49 if ok[k] { 50 os.Setenv(k, old[k]) 51 } else { 52 os.Unsetenv(k) 53 } 54 } 55 } 56 } 57 58 func (s *SnapSuite) TestCanUnicode(c *check.C) { 59 // setenv is per thread 60 runtime.LockOSThread() 61 defer runtime.UnlockOSThread() 62 63 type T struct { 64 lang, lcAll, lcMsg string 65 expected bool 66 } 67 68 for _, t := range []T{ 69 {expected: false}, // all locale unset 70 {lang: "C", expected: false}, 71 {lang: "C", lcAll: "C", expected: false}, 72 {lang: "C", lcAll: "C", lcMsg: "C", expected: false}, 73 {lang: "C.UTF-8", lcAll: "C", lcMsg: "C", expected: false}, // LC_MESSAGES wins 74 {lang: "C.UTF-8", lcAll: "C.UTF-8", lcMsg: "C", expected: false}, 75 {lang: "C.UTF-8", lcAll: "C.UTF-8", lcMsg: "C.UTF-8", expected: true}, 76 {lang: "C.UTF-8", lcAll: "C", lcMsg: "C.UTF-8", expected: true}, 77 {lang: "C", lcAll: "C", lcMsg: "C.UTF-8", expected: true}, 78 {lang: "C", lcAll: "C.UTF-8", expected: true}, 79 {lang: "C.UTF-8", expected: true}, 80 {lang: "C.utf8", expected: true}, // deals with a bit of rando weirdness 81 } { 82 restore := setEnviron(map[string]string{"LANG": t.lang, "LC_ALL": t.lcAll, "LC_MESSAGES": t.lcMsg}) 83 c.Check(cmdsnap.CanUnicode("never"), check.Equals, false) 84 c.Check(cmdsnap.CanUnicode("always"), check.Equals, true) 85 restoreIsTTY := cmdsnap.MockIsStdoutTTY(true) 86 c.Check(cmdsnap.CanUnicode("auto"), check.Equals, t.expected) 87 cmdsnap.MockIsStdoutTTY(false) 88 c.Check(cmdsnap.CanUnicode("auto"), check.Equals, false) 89 restoreIsTTY() 90 restore() 91 } 92 } 93 94 func (s *SnapSuite) TestColorTable(c *check.C) { 95 // setenv is per thread 96 runtime.LockOSThread() 97 defer runtime.UnlockOSThread() 98 99 type T struct { 100 isTTY bool 101 noColor, term string 102 expected interface{} 103 desc string 104 } 105 106 for _, t := range []T{ 107 {isTTY: false, expected: cmdsnap.NoEscColorTable, desc: "not a tty"}, 108 {isTTY: false, noColor: "1", expected: cmdsnap.NoEscColorTable, desc: "no tty *and* NO_COLOR set"}, 109 {isTTY: false, term: "linux-m", expected: cmdsnap.NoEscColorTable, desc: "no tty *and* mono term set"}, 110 {isTTY: true, expected: cmdsnap.ColorColorTable, desc: "is a tty"}, 111 {isTTY: true, noColor: "1", expected: cmdsnap.MonoColorTable, desc: "is a tty, but NO_COLOR set"}, 112 {isTTY: true, term: "linux-m", expected: cmdsnap.MonoColorTable, desc: "is a tty, but TERM=linux-m"}, 113 {isTTY: true, term: "xterm-mono", expected: cmdsnap.MonoColorTable, desc: "is a tty, but TERM=xterm-mono"}, 114 } { 115 restoreIsTTY := cmdsnap.MockIsStdoutTTY(t.isTTY) 116 restoreEnv := setEnviron(map[string]string{"NO_COLOR": t.noColor, "TERM": t.term}) 117 c.Check(cmdsnap.ColorTable("never"), check.DeepEquals, cmdsnap.NoEscColorTable, check.Commentf(t.desc)) 118 c.Check(cmdsnap.ColorTable("always"), check.DeepEquals, cmdsnap.ColorColorTable, check.Commentf(t.desc)) 119 c.Check(cmdsnap.ColorTable("auto"), check.DeepEquals, t.expected, check.Commentf(t.desc)) 120 restoreEnv() 121 restoreIsTTY() 122 } 123 } 124 125 func (s *SnapSuite) TestPublisherEscapes(c *check.C) { 126 // just check never/always; for auto checks look above 127 type T struct { 128 color, unicode bool 129 username, display string 130 verified bool 131 short, long, fill string 132 } 133 for _, t := range []T{ 134 // non-verified equal under fold: 135 {color: false, unicode: false, username: "potato", display: "Potato", 136 short: "potato", long: "Potato", fill: ""}, 137 {color: false, unicode: true, username: "potato", display: "Potato", 138 short: "potato", long: "Potato", fill: ""}, 139 {color: true, unicode: false, username: "potato", display: "Potato", 140 short: "potato\x1b[32m\x1b[0m", long: "Potato\x1b[32m\x1b[0m", fill: "\x1b[32m\x1b[0m"}, 141 {color: true, unicode: true, username: "potato", display: "Potato", 142 short: "potato\x1b[32m\x1b[0m", long: "Potato\x1b[32m\x1b[0m", fill: "\x1b[32m\x1b[0m"}, 143 // verified equal under fold: 144 {color: false, unicode: false, username: "potato", display: "Potato", verified: true, 145 short: "potato*", long: "Potato*", fill: ""}, 146 {color: false, unicode: true, username: "potato", display: "Potato", verified: true, 147 short: "potato✓", long: "Potato✓", fill: ""}, 148 {color: true, unicode: false, username: "potato", display: "Potato", verified: true, 149 short: "potato\x1b[32m*\x1b[0m", long: "Potato\x1b[32m*\x1b[0m", fill: "\x1b[32m\x1b[0m"}, 150 {color: true, unicode: true, username: "potato", display: "Potato", verified: true, 151 short: "potato\x1b[32m✓\x1b[0m", long: "Potato\x1b[32m✓\x1b[0m", fill: "\x1b[32m\x1b[0m"}, 152 // non-verified, different 153 {color: false, unicode: false, username: "potato", display: "Carrot", 154 short: "potato", long: "Carrot (potato)", fill: ""}, 155 {color: false, unicode: true, username: "potato", display: "Carrot", 156 short: "potato", long: "Carrot (potato)", fill: ""}, 157 {color: true, unicode: false, username: "potato", display: "Carrot", 158 short: "potato\x1b[32m\x1b[0m", long: "Carrot (potato\x1b[32m\x1b[0m)", fill: "\x1b[32m\x1b[0m"}, 159 {color: true, unicode: true, username: "potato", display: "Carrot", 160 short: "potato\x1b[32m\x1b[0m", long: "Carrot (potato\x1b[32m\x1b[0m)", fill: "\x1b[32m\x1b[0m"}, 161 // verified, different 162 {color: false, unicode: false, username: "potato", display: "Carrot", verified: true, 163 short: "potato*", long: "Carrot (potato*)", fill: ""}, 164 {color: false, unicode: true, username: "potato", display: "Carrot", verified: true, 165 short: "potato✓", long: "Carrot (potato✓)", fill: ""}, 166 {color: true, unicode: false, username: "potato", display: "Carrot", verified: true, 167 short: "potato\x1b[32m*\x1b[0m", long: "Carrot (potato\x1b[32m*\x1b[0m)", fill: "\x1b[32m\x1b[0m"}, 168 {color: true, unicode: true, username: "potato", display: "Carrot", verified: true, 169 short: "potato\x1b[32m✓\x1b[0m", long: "Carrot (potato\x1b[32m✓\x1b[0m)", fill: "\x1b[32m\x1b[0m"}, 170 // some interesting equal-under-folds: 171 {color: false, unicode: false, username: "potato", display: "PoTaTo", 172 short: "potato", long: "PoTaTo", fill: ""}, 173 {color: false, unicode: false, username: "potato-team", display: "Potato Team", 174 short: "potato-team", long: "Potato Team", fill: ""}, 175 } { 176 pub := &snap.StoreAccount{Username: t.username, DisplayName: t.display} 177 if t.verified { 178 pub.Validation = "verified" 179 } 180 color := "never" 181 if t.color { 182 color = "always" 183 } 184 unicode := "never" 185 if t.unicode { 186 unicode = "always" 187 } 188 189 mx := cmdsnap.ColorMixin(color, unicode) 190 esc := cmdsnap.ColorMixinGetEscapes(mx) 191 192 c.Check(cmdsnap.ShortPublisher(esc, pub), check.Equals, t.short) 193 c.Check(cmdsnap.LongPublisher(esc, pub), check.Equals, t.long) 194 c.Check(cmdsnap.FillerPublisher(esc), check.Equals, t.fill) 195 } 196 }