github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/i18n/xgettext-go/main_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2014-2015 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
    21  
    22  import (
    23  	"bytes"
    24  	"fmt"
    25  	"io/ioutil"
    26  	"os"
    27  	"path/filepath"
    28  	"testing"
    29  
    30  	. "gopkg.in/check.v1"
    31  
    32  	"github.com/snapcore/snapd/testutil"
    33  )
    34  
    35  // Hook up check.v1 into the "go test" runner
    36  func TestT(t *testing.T) { TestingT(t) }
    37  
    38  type xgettextTestSuite struct {
    39  }
    40  
    41  var _ = Suite(&xgettextTestSuite{})
    42  
    43  // test helper
    44  func makeGoSourceFile(c *C, content []byte) string {
    45  	fname := filepath.Join(c.MkDir(), "foo.go")
    46  	err := ioutil.WriteFile(fname, []byte(content), 0644)
    47  	c.Assert(err, IsNil)
    48  
    49  	return fname
    50  }
    51  
    52  func (s *xgettextTestSuite) SetUpTest(c *C) {
    53  	// our test defaults
    54  	opts.NoLocation = false
    55  	opts.AddCommentsTag = "TRANSLATORS:"
    56  	opts.Keyword = "i18n.G"
    57  	opts.KeywordPlural = "i18n.NG"
    58  	opts.SortOutput = true
    59  	opts.PackageName = "snappy"
    60  	opts.MsgIDBugsAddress = "snappy-devel@lists.ubuntu.com"
    61  
    62  	// mock time
    63  	formatTime = func() string {
    64  		return "2015-06-30 14:48+0200"
    65  	}
    66  }
    67  
    68  func (s *xgettextTestSuite) TestFormatComment(c *C) {
    69  	var tests = []struct {
    70  		in  string
    71  		out string
    72  	}{
    73  		{in: "// foo ", out: "#. foo\n"},
    74  		{in: "/* foo */", out: "#. foo\n"},
    75  		{in: "/* foo\n */", out: "#. foo\n"},
    76  		{in: "/* foo\nbar   */", out: "#. foo\n#. bar\n"},
    77  	}
    78  
    79  	for _, test := range tests {
    80  		c.Assert(formatComment(test.in), Equals, test.out)
    81  	}
    82  }
    83  
    84  func (s *xgettextTestSuite) TestProcessFilesSimple(c *C) {
    85  	fname := makeGoSourceFile(c, []byte(`package main
    86  
    87  func main() {
    88      // TRANSLATORS: foo comment
    89      i18n.G("foo")
    90  }
    91  `))
    92  	err := processFiles([]string{fname})
    93  	c.Assert(err, IsNil)
    94  
    95  	c.Assert(msgIDs, DeepEquals, map[string][]msgID{
    96  		"foo": {
    97  			{
    98  				comment: "#. TRANSLATORS: foo comment\n",
    99  				fname:   fname,
   100  				line:    5,
   101  			},
   102  		},
   103  	})
   104  }
   105  
   106  func (s *xgettextTestSuite) TestProcessFilesMultiple(c *C) {
   107  	fname := makeGoSourceFile(c, []byte(`package main
   108  
   109  func main() {
   110      // TRANSLATORS: foo comment
   111      i18n.G("foo")
   112  
   113      // TRANSLATORS: bar comment
   114      i18n.G("foo")
   115  }
   116  `))
   117  	err := processFiles([]string{fname})
   118  	c.Assert(err, IsNil)
   119  
   120  	c.Assert(msgIDs, DeepEquals, map[string][]msgID{
   121  		"foo": {
   122  			{
   123  				comment: "#. TRANSLATORS: foo comment\n",
   124  				fname:   fname,
   125  				line:    5,
   126  			},
   127  			{
   128  				comment: "#. TRANSLATORS: bar comment\n",
   129  				fname:   fname,
   130  				line:    8,
   131  			},
   132  		},
   133  	})
   134  }
   135  
   136  const header = `# SOME DESCRIPTIVE TITLE.
   137  # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
   138  # This file is distributed under the same license as the PACKAGE package.
   139  # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
   140  #
   141  #, fuzzy
   142  msgid   ""
   143  msgstr  "Project-Id-Version: snappy\n"
   144          "Report-Msgid-Bugs-To: snappy-devel@lists.ubuntu.com\n"
   145          "POT-Creation-Date: 2015-06-30 14:48+0200\n"
   146          "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
   147          "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
   148          "Language-Team: LANGUAGE <LL@li.org>\n"
   149          "Language: \n"
   150          "MIME-Version: 1.0\n"
   151          "Content-Type: text/plain; charset=CHARSET\n"
   152          "Content-Transfer-Encoding: 8bit\n"
   153  `
   154  
   155  func (s *xgettextTestSuite) TestWriteOutputSimple(c *C) {
   156  	msgIDs = map[string][]msgID{
   157  		"foo": {
   158  			{
   159  				fname:   "fname",
   160  				line:    2,
   161  				comment: "#. foo\n",
   162  			},
   163  		},
   164  	}
   165  	out := bytes.NewBuffer([]byte(""))
   166  	writePotFile(out)
   167  
   168  	expected := fmt.Sprintf(`%s
   169  #. foo
   170  #: fname:2
   171  msgid   "foo"
   172  msgstr  ""
   173  
   174  `, header)
   175  	c.Assert(out.String(), Equals, expected)
   176  }
   177  
   178  func (s *xgettextTestSuite) TestWriteOutputMultiple(c *C) {
   179  	msgIDs = map[string][]msgID{
   180  		"foo": {
   181  			{
   182  				fname:   "fname",
   183  				line:    2,
   184  				comment: "#. comment1\n",
   185  			},
   186  			{
   187  				fname:   "fname",
   188  				line:    4,
   189  				comment: "#. comment2\n",
   190  			},
   191  		},
   192  	}
   193  	out := bytes.NewBuffer([]byte(""))
   194  	writePotFile(out)
   195  
   196  	expected := fmt.Sprintf(`%s
   197  #. comment1
   198  #. comment2
   199  #: fname:2 fname:4
   200  msgid   "foo"
   201  msgstr  ""
   202  
   203  `, header)
   204  	c.Assert(out.String(), Equals, expected)
   205  }
   206  
   207  func (s *xgettextTestSuite) TestWriteOutputNoComment(c *C) {
   208  	msgIDs = map[string][]msgID{
   209  		"foo": {
   210  			{
   211  				fname: "fname",
   212  				line:  2,
   213  			},
   214  		},
   215  	}
   216  	out := bytes.NewBuffer([]byte(""))
   217  	writePotFile(out)
   218  
   219  	expected := fmt.Sprintf(`%s
   220  #: fname:2
   221  msgid   "foo"
   222  msgstr  ""
   223  
   224  `, header)
   225  	c.Assert(out.String(), Equals, expected)
   226  }
   227  
   228  func (s *xgettextTestSuite) TestWriteOutputNoLocation(c *C) {
   229  	msgIDs = map[string][]msgID{
   230  		"foo": {
   231  			{
   232  				fname: "fname",
   233  				line:  2,
   234  			},
   235  		},
   236  	}
   237  
   238  	opts.NoLocation = true
   239  	out := bytes.NewBuffer([]byte(""))
   240  	writePotFile(out)
   241  
   242  	expected := fmt.Sprintf(`%s
   243  msgid   "foo"
   244  msgstr  ""
   245  
   246  `, header)
   247  	c.Assert(out.String(), Equals, expected)
   248  }
   249  
   250  func (s *xgettextTestSuite) TestWriteOutputFormatHint(c *C) {
   251  	msgIDs = map[string][]msgID{
   252  		"foo": {
   253  			{
   254  				fname:      "fname",
   255  				line:       2,
   256  				formatHint: "c-format",
   257  			},
   258  		},
   259  	}
   260  
   261  	out := bytes.NewBuffer([]byte(""))
   262  	writePotFile(out)
   263  
   264  	expected := fmt.Sprintf(`%s
   265  #: fname:2
   266  #, c-format
   267  msgid   "foo"
   268  msgstr  ""
   269  
   270  `, header)
   271  	c.Assert(out.String(), Equals, expected)
   272  }
   273  
   274  func (s *xgettextTestSuite) TestWriteOutputPlural(c *C) {
   275  	msgIDs = map[string][]msgID{
   276  		"foo": {
   277  			{
   278  				msgidPlural: "plural",
   279  				fname:       "fname",
   280  				line:        2,
   281  			},
   282  		},
   283  	}
   284  
   285  	out := bytes.NewBuffer([]byte(""))
   286  	writePotFile(out)
   287  
   288  	expected := fmt.Sprintf(`%s
   289  #: fname:2
   290  msgid   "foo"
   291  msgid_plural   "plural"
   292  msgstr[0]  ""
   293  msgstr[1]  ""
   294  
   295  `, header)
   296  	c.Assert(out.String(), Equals, expected)
   297  }
   298  
   299  func (s *xgettextTestSuite) TestWriteOutputSorted(c *C) {
   300  	msgIDs = map[string][]msgID{
   301  		"aaa": {
   302  			{
   303  				fname: "fname",
   304  				line:  2,
   305  			},
   306  		},
   307  		"zzz": {
   308  			{
   309  				fname: "fname",
   310  				line:  2,
   311  			},
   312  		},
   313  	}
   314  
   315  	opts.SortOutput = true
   316  	// we need to run this a bunch of times as the ordering might
   317  	// be right by pure chance
   318  	for i := 0; i < 10; i++ {
   319  		out := bytes.NewBuffer([]byte(""))
   320  		writePotFile(out)
   321  
   322  		expected := fmt.Sprintf(`%s
   323  #: fname:2
   324  msgid   "aaa"
   325  msgstr  ""
   326  
   327  #: fname:2
   328  msgid   "zzz"
   329  msgstr  ""
   330  
   331  `, header)
   332  		c.Assert(out.String(), Equals, expected)
   333  	}
   334  }
   335  
   336  func (s *xgettextTestSuite) TestIntegration(c *C) {
   337  	fname := makeGoSourceFile(c, []byte(`package main
   338  
   339  func main() {
   340      // TRANSLATORS: foo comment
   341      //              with multiple lines
   342      i18n.G("foo")
   343  
   344      // this comment has no translators tag
   345      i18n.G("abc")
   346  
   347      // TRANSLATORS: plural
   348      i18n.NG("singular", "plural", 99)
   349  
   350      i18n.G("zz %s")
   351  }
   352  `))
   353  
   354  	// a real integration test :)
   355  	outName := filepath.Join(c.MkDir(), "snappy.pot")
   356  	os.Args = []string{"test-binary",
   357  		"--output", outName,
   358  		"--keyword", "i18n.G",
   359  		"--keyword-plural", "i18n.NG",
   360  		"--msgid-bugs-address", "snappy-devel@lists.ubuntu.com",
   361  		"--package-name", "snappy",
   362  		fname,
   363  	}
   364  	main()
   365  
   366  	// verify its what we expect
   367  	c.Assert(outName, testutil.FileEquals, fmt.Sprintf(`%s
   368  #: %[2]s:9
   369  msgid   "abc"
   370  msgstr  ""
   371  
   372  #. TRANSLATORS: foo comment
   373  #. with multiple lines
   374  #: %[2]s:6
   375  msgid   "foo"
   376  msgstr  ""
   377  
   378  #. TRANSLATORS: plural
   379  #: %[2]s:12
   380  msgid   "singular"
   381  msgid_plural   "plural"
   382  msgstr[0]  ""
   383  msgstr[1]  ""
   384  
   385  #: %[2]s:14
   386  #, c-format
   387  msgid   "zz %%s"
   388  msgstr  ""
   389  
   390  `, header, fname))
   391  }
   392  
   393  func (s *xgettextTestSuite) TestProcessFilesConcat(c *C) {
   394  	fname := makeGoSourceFile(c, []byte(`package main
   395  
   396  func main() {
   397      // TRANSLATORS: foo comment
   398      i18n.G("foo\n" + "bar\n" + "baz")
   399  }
   400  `))
   401  	err := processFiles([]string{fname})
   402  	c.Assert(err, IsNil)
   403  
   404  	c.Assert(msgIDs, DeepEquals, map[string][]msgID{
   405  		"foo\\nbar\\nbaz": {
   406  			{
   407  				comment: "#. TRANSLATORS: foo comment\n",
   408  				fname:   fname,
   409  				line:    5,
   410  			},
   411  		},
   412  	})
   413  }
   414  
   415  func (s *xgettextTestSuite) TestProcessFilesWithQuote(c *C) {
   416  	fname := makeGoSourceFile(c, []byte(fmt.Sprintf(`package main
   417  
   418  func main() {
   419      i18n.G(%[1]s foo "bar"%[1]s)
   420  }
   421  `, "`")))
   422  	err := processFiles([]string{fname})
   423  	c.Assert(err, IsNil)
   424  
   425  	out := bytes.NewBuffer([]byte(""))
   426  	writePotFile(out)
   427  
   428  	expected := fmt.Sprintf(`%s
   429  #: %[2]s:4
   430  msgid   " foo \"bar\""
   431  msgstr  ""
   432  
   433  `, header, fname)
   434  	c.Check(out.String(), Equals, expected)
   435  
   436  }
   437  
   438  func (s *xgettextTestSuite) TestWriteOutputMultilines(c *C) {
   439  	msgIDs = map[string][]msgID{
   440  		"foo\\nbar\\nbaz": {
   441  			{
   442  				fname:   "fname",
   443  				line:    2,
   444  				comment: "#. foo\n",
   445  			},
   446  		},
   447  	}
   448  	out := bytes.NewBuffer([]byte(""))
   449  	writePotFile(out)
   450  	expected := fmt.Sprintf(`%s
   451  #. foo
   452  #: fname:2
   453  msgid   "foo\n"
   454          "bar\n"
   455          "baz"
   456  msgstr  ""
   457  
   458  `, header)
   459  	c.Assert(out.String(), Equals, expected)
   460  }
   461  
   462  func (s *xgettextTestSuite) TestWriteOutputTidy(c *C) {
   463  	msgIDs = map[string][]msgID{
   464  		"foo\\nbar\\nbaz": {
   465  			{
   466  				fname: "fname",
   467  				line:  2,
   468  			},
   469  		},
   470  		"zzz\\n": {
   471  			{
   472  				fname: "fname",
   473  				line:  4,
   474  			},
   475  		},
   476  	}
   477  	out := bytes.NewBuffer([]byte(""))
   478  	writePotFile(out)
   479  	expected := fmt.Sprintf(`%s
   480  #: fname:2
   481  msgid   "foo\n"
   482          "bar\n"
   483          "baz"
   484  msgstr  ""
   485  
   486  #: fname:4
   487  msgid   "zzz\n"
   488  msgstr  ""
   489  
   490  `, header)
   491  	c.Assert(out.String(), Equals, expected)
   492  }
   493  
   494  func (s *xgettextTestSuite) TestProcessFilesWithDoubleQuote(c *C) {
   495  	fname := makeGoSourceFile(c, []byte(`package main
   496  
   497  func main() {
   498      i18n.G("foo \"bar\"")
   499  }
   500  `))
   501  	err := processFiles([]string{fname})
   502  	c.Assert(err, IsNil)
   503  
   504  	out := bytes.NewBuffer([]byte(""))
   505  	writePotFile(out)
   506  
   507  	expected := fmt.Sprintf(`%s
   508  #: %[2]s:4
   509  msgid   "foo \"bar\""
   510  msgstr  ""
   511  
   512  `, header, fname)
   513  	c.Check(out.String(), Equals, expected)
   514  
   515  }
   516  
   517  func (s *xgettextTestSuite) TestDontEscapeAlreadyEscapedQuoteInBacktick(c *C) {
   518  	fname := makeGoSourceFile(c, []byte(`package main
   519  
   520  func main() {
   521      i18n.G(`+"`"+`Some text: "{\"key\":\"value\"}"`+"`"+`)
   522  }
   523  `))
   524  
   525  	err := processFiles([]string{fname})
   526  	c.Assert(err, IsNil)
   527  
   528  	out := bytes.NewBuffer([]byte(""))
   529  	writePotFile(out)
   530  
   531  	expected := fmt.Sprintf(`%s
   532  #: %[2]s:4
   533  msgid   "Some text: \"{\"key\":\"value\"}\""
   534  msgstr  ""
   535  
   536  `, header, fname)
   537  	c.Check(out.String(), Equals, expected)
   538  }