gitee.com/mysnapcore/mysnapd@v0.1.0/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  
    26  	"gopkg.in/check.v1"
    27  
    28  	cmdsnap "gitee.com/mysnapcore/mysnapd/cmd/snap"
    29  	"gitee.com/mysnapcore/mysnapd/snap"
    30  )
    31  
    32  func setEnviron(env map[string]string) func() {
    33  	old := make(map[string]string, len(env))
    34  	ok := make(map[string]bool, len(env))
    35  
    36  	for k, v := range env {
    37  		old[k], ok[k] = os.LookupEnv(k)
    38  		if v != "" {
    39  			os.Setenv(k, v)
    40  		} else {
    41  			os.Unsetenv(k)
    42  		}
    43  	}
    44  
    45  	return func() {
    46  		for k := range ok {
    47  			if ok[k] {
    48  				os.Setenv(k, old[k])
    49  			} else {
    50  				os.Unsetenv(k)
    51  			}
    52  		}
    53  	}
    54  }
    55  
    56  func (s *SnapSuite) TestCanUnicode(c *check.C) {
    57  	// setenv is per thread
    58  	runtime.LockOSThread()
    59  	defer runtime.UnlockOSThread()
    60  
    61  	type T struct {
    62  		lang, lcAll, lcMsg string
    63  		expected           bool
    64  	}
    65  
    66  	for _, t := range []T{
    67  		{expected: false}, // all locale unset
    68  		{lang: "C", expected: false},
    69  		{lang: "C", lcAll: "C", expected: false},
    70  		{lang: "C", lcAll: "C", lcMsg: "C", expected: false},
    71  		{lang: "C.UTF-8", lcAll: "C", lcMsg: "C", expected: false}, // LC_MESSAGES wins
    72  		{lang: "C.UTF-8", lcAll: "C.UTF-8", lcMsg: "C", expected: false},
    73  		{lang: "C.UTF-8", lcAll: "C.UTF-8", lcMsg: "C.UTF-8", expected: true},
    74  		{lang: "C.UTF-8", lcAll: "C", lcMsg: "C.UTF-8", expected: true},
    75  		{lang: "C", lcAll: "C", lcMsg: "C.UTF-8", expected: true},
    76  		{lang: "C", lcAll: "C.UTF-8", expected: true},
    77  		{lang: "C.UTF-8", expected: true},
    78  		{lang: "C.utf8", expected: true}, // deals with a bit of rando weirdness
    79  	} {
    80  		restore := setEnviron(map[string]string{"LANG": t.lang, "LC_ALL": t.lcAll, "LC_MESSAGES": t.lcMsg})
    81  		c.Check(cmdsnap.CanUnicode("never"), check.Equals, false)
    82  		c.Check(cmdsnap.CanUnicode("always"), check.Equals, true)
    83  		restoreIsTTY := cmdsnap.MockIsStdoutTTY(true)
    84  		c.Check(cmdsnap.CanUnicode("auto"), check.Equals, t.expected)
    85  		cmdsnap.MockIsStdoutTTY(false)
    86  		c.Check(cmdsnap.CanUnicode("auto"), check.Equals, false)
    87  		restoreIsTTY()
    88  		restore()
    89  	}
    90  }
    91  
    92  func (s *SnapSuite) TestColorTable(c *check.C) {
    93  	// setenv is per thread
    94  	runtime.LockOSThread()
    95  	defer runtime.UnlockOSThread()
    96  
    97  	type T struct {
    98  		isTTY         bool
    99  		noColor, term string
   100  		expected      interface{}
   101  		desc          string
   102  	}
   103  
   104  	for _, t := range []T{
   105  		{isTTY: false, expected: cmdsnap.NoEscColorTable, desc: "not a tty"},
   106  		{isTTY: false, noColor: "1", expected: cmdsnap.NoEscColorTable, desc: "no tty *and* NO_COLOR set"},
   107  		{isTTY: false, term: "linux-m", expected: cmdsnap.NoEscColorTable, desc: "no tty *and* mono term set"},
   108  		{isTTY: true, expected: cmdsnap.ColorColorTable, desc: "is a tty"},
   109  		{isTTY: true, noColor: "1", expected: cmdsnap.MonoColorTable, desc: "is a tty, but NO_COLOR set"},
   110  		{isTTY: true, term: "linux-m", expected: cmdsnap.MonoColorTable, desc: "is a tty, but TERM=linux-m"},
   111  		{isTTY: true, term: "xterm-mono", expected: cmdsnap.MonoColorTable, desc: "is a tty, but TERM=xterm-mono"},
   112  	} {
   113  		restoreIsTTY := cmdsnap.MockIsStdoutTTY(t.isTTY)
   114  		restoreEnv := setEnviron(map[string]string{"NO_COLOR": t.noColor, "TERM": t.term})
   115  		c.Check(cmdsnap.ColorTable("never"), check.DeepEquals, cmdsnap.NoEscColorTable, check.Commentf(t.desc))
   116  		c.Check(cmdsnap.ColorTable("always"), check.DeepEquals, cmdsnap.ColorColorTable, check.Commentf(t.desc))
   117  		c.Check(cmdsnap.ColorTable("auto"), check.DeepEquals, t.expected, check.Commentf(t.desc))
   118  		restoreEnv()
   119  		restoreIsTTY()
   120  	}
   121  }
   122  
   123  func (s *SnapSuite) TestPublisherEscapes(c *check.C) {
   124  	// just check never/always; for auto checks look above
   125  	type T struct {
   126  		color, unicode    bool
   127  		username, display string
   128  		verified          bool
   129  		starred           bool
   130  		short, long, fill string
   131  	}
   132  	for _, t := range []T{
   133  		// non-verified equal under fold:
   134  		{color: false, unicode: false, username: "potato", display: "Potato",
   135  			short: "potato", long: "Potato", fill: ""},
   136  		{color: false, unicode: true, username: "potato", display: "Potato",
   137  			short: "potato", long: "Potato", fill: ""},
   138  		{color: true, unicode: false, username: "potato", display: "Potato",
   139  			short: "potato\x1b[32m\x1b[0m", long: "Potato\x1b[32m\x1b[0m", fill: "\x1b[32m\x1b[0m"},
   140  		{color: true, unicode: true, username: "potato", display: "Potato",
   141  			short: "potato\x1b[32m\x1b[0m", long: "Potato\x1b[32m\x1b[0m", fill: "\x1b[32m\x1b[0m"},
   142  		// verified equal under fold:
   143  		{color: false, unicode: false, username: "potato", display: "Potato", verified: true,
   144  			short: "potato**", long: "Potato**", fill: ""},
   145  		{color: false, unicode: true, username: "potato", display: "Potato", verified: true,
   146  			short: "potato✓", long: "Potato✓", fill: ""},
   147  		{color: true, unicode: false, username: "potato", display: "Potato", verified: true,
   148  			short: "potato\x1b[32m**\x1b[0m", long: "Potato\x1b[32m**\x1b[0m", fill: "\x1b[32m\x1b[0m"},
   149  		{color: true, unicode: true, username: "potato", display: "Potato", verified: true,
   150  			short: "potato\x1b[32m✓\x1b[0m", long: "Potato\x1b[32m✓\x1b[0m", fill: "\x1b[32m\x1b[0m"},
   151  		// starred equal under fold:
   152  		{color: false, unicode: false, username: "potato", display: "Potato", starred: true,
   153  			short: "potato*", long: "Potato*", fill: ""},
   154  		{color: false, unicode: true, username: "potato", display: "Potato", starred: true,
   155  			short: "potato✪", long: "Potato✪", fill: ""},
   156  		{color: true, unicode: false, username: "potato", display: "Potato", starred: true,
   157  			short: "potato\x1b[93m*\x1b[0m", long: "Potato\x1b[93m*\x1b[0m", fill: "\x1b[32m\x1b[0m"},
   158  		{color: true, unicode: true, username: "potato", display: "Potato", starred: true,
   159  			short: "potato\x1b[93m✪\x1b[0m", long: "Potato\x1b[93m✪\x1b[0m", fill: "\x1b[32m\x1b[0m"},
   160  		// non-verified, different
   161  		{color: false, unicode: false, username: "potato", display: "Carrot",
   162  			short: "potato", long: "Carrot (potato)", fill: ""},
   163  		{color: false, unicode: true, username: "potato", display: "Carrot",
   164  			short: "potato", long: "Carrot (potato)", fill: ""},
   165  		{color: true, unicode: false, username: "potato", display: "Carrot",
   166  			short: "potato\x1b[32m\x1b[0m", long: "Carrot (potato\x1b[32m\x1b[0m)", fill: "\x1b[32m\x1b[0m"},
   167  		{color: true, unicode: true, username: "potato", display: "Carrot",
   168  			short: "potato\x1b[32m\x1b[0m", long: "Carrot (potato\x1b[32m\x1b[0m)", fill: "\x1b[32m\x1b[0m"},
   169  		// verified, different
   170  		{color: false, unicode: false, username: "potato", display: "Carrot", verified: true,
   171  			short: "potato**", long: "Carrot (potato**)", fill: ""},
   172  		{color: false, unicode: true, username: "potato", display: "Carrot", verified: true,
   173  			short: "potato✓", long: "Carrot (potato✓)", fill: ""},
   174  		{color: true, unicode: false, username: "potato", display: "Carrot", verified: true,
   175  			short: "potato\x1b[32m**\x1b[0m", long: "Carrot (potato\x1b[32m**\x1b[0m)", fill: "\x1b[32m\x1b[0m"},
   176  		{color: true, unicode: true, username: "potato", display: "Carrot", verified: true,
   177  			short: "potato\x1b[32m✓\x1b[0m", long: "Carrot (potato\x1b[32m✓\x1b[0m)", fill: "\x1b[32m\x1b[0m"},
   178  		// starred, different
   179  		{color: false, unicode: false, username: "potato", display: "Carrot", starred: true,
   180  			short: "potato*", long: "Carrot (potato*)", fill: ""},
   181  		{color: false, unicode: true, username: "potato", display: "Carrot", starred: true,
   182  			short: "potato✪", long: "Carrot (potato✪)", fill: ""},
   183  		{color: true, unicode: false, username: "potato", display: "Carrot", starred: true,
   184  			short: "potato\x1b[93m*\x1b[0m", long: "Carrot (potato\x1b[93m*\x1b[0m)", fill: "\x1b[32m\x1b[0m"},
   185  		{color: true, unicode: true, username: "potato", display: "Carrot", starred: true,
   186  			short: "potato\x1b[93m✪\x1b[0m", long: "Carrot (potato\x1b[93m✪\x1b[0m)", fill: "\x1b[32m\x1b[0m"},
   187  		// some interesting equal-under-folds:
   188  		{color: false, unicode: false, username: "potato", display: "PoTaTo",
   189  			short: "potato", long: "PoTaTo", fill: ""},
   190  		{color: false, unicode: false, username: "potato-team", display: "Potato Team",
   191  			short: "potato-team", long: "Potato Team", fill: ""},
   192  	} {
   193  		pub := &snap.StoreAccount{Username: t.username, DisplayName: t.display}
   194  		switch {
   195  		case t.verified && t.starred:
   196  			panic("invalid test setup: cannot be starred and validated at the same time")
   197  		case t.verified:
   198  			pub.Validation = "verified"
   199  		case t.starred:
   200  			pub.Validation = "starred"
   201  		}
   202  		color := "never"
   203  		if t.color {
   204  			color = "always"
   205  		}
   206  		unicode := "never"
   207  		if t.unicode {
   208  			unicode = "always"
   209  		}
   210  
   211  		mx := cmdsnap.ColorMixin(color, unicode)
   212  		esc := cmdsnap.ColorMixinGetEscapes(mx)
   213  
   214  		c.Check(cmdsnap.ShortPublisher(esc, pub), check.Equals, t.short)
   215  		c.Check(cmdsnap.LongPublisher(esc, pub), check.Equals, t.long)
   216  		c.Check(cmdsnap.FillerPublisher(esc), check.Equals, t.fill)
   217  	}
   218  }