helpers_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. // These tests verify the inner workings of the helper methods associated
  2. // with check.T.
  3. package check_test
  4. import (
  5. "gopkg.in/check.v1"
  6. "os"
  7. "reflect"
  8. "runtime"
  9. "sync"
  10. )
  11. var helpersS = check.Suite(&HelpersS{})
  12. type HelpersS struct{}
  13. func (s *HelpersS) TestCountSuite(c *check.C) {
  14. suitesRun += 1
  15. }
  16. // -----------------------------------------------------------------------
  17. // Fake checker and bug info to verify the behavior of Assert() and Check().
  18. type MyChecker struct {
  19. info *check.CheckerInfo
  20. params []interface{}
  21. names []string
  22. result bool
  23. error string
  24. }
  25. func (checker *MyChecker) Info() *check.CheckerInfo {
  26. if checker.info == nil {
  27. return &check.CheckerInfo{Name: "MyChecker", Params: []string{"myobtained", "myexpected"}}
  28. }
  29. return checker.info
  30. }
  31. func (checker *MyChecker) Check(params []interface{}, names []string) (bool, string) {
  32. rparams := checker.params
  33. rnames := checker.names
  34. checker.params = append([]interface{}{}, params...)
  35. checker.names = append([]string{}, names...)
  36. if rparams != nil {
  37. copy(params, rparams)
  38. }
  39. if rnames != nil {
  40. copy(names, rnames)
  41. }
  42. return checker.result, checker.error
  43. }
  44. type myCommentType string
  45. func (c myCommentType) CheckCommentString() string {
  46. return string(c)
  47. }
  48. func myComment(s string) myCommentType {
  49. return myCommentType(s)
  50. }
  51. // -----------------------------------------------------------------------
  52. // Ensure a real checker actually works fine.
  53. func (s *HelpersS) TestCheckerInterface(c *check.C) {
  54. testHelperSuccess(c, "Check(1, Equals, 1)", true, func() interface{} {
  55. return c.Check(1, check.Equals, 1)
  56. })
  57. }
  58. // -----------------------------------------------------------------------
  59. // Tests for Check(), mostly the same as for Assert() following these.
  60. func (s *HelpersS) TestCheckSucceedWithExpected(c *check.C) {
  61. checker := &MyChecker{result: true}
  62. testHelperSuccess(c, "Check(1, checker, 2)", true, func() interface{} {
  63. return c.Check(1, checker, 2)
  64. })
  65. if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) {
  66. c.Fatalf("Bad params for check: %#v", checker.params)
  67. }
  68. }
  69. func (s *HelpersS) TestCheckSucceedWithoutExpected(c *check.C) {
  70. checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
  71. testHelperSuccess(c, "Check(1, checker)", true, func() interface{} {
  72. return c.Check(1, checker)
  73. })
  74. if !reflect.DeepEqual(checker.params, []interface{}{1}) {
  75. c.Fatalf("Bad params for check: %#v", checker.params)
  76. }
  77. }
  78. func (s *HelpersS) TestCheckFailWithExpected(c *check.C) {
  79. checker := &MyChecker{result: false}
  80. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  81. " return c\\.Check\\(1, checker, 2\\)\n" +
  82. "\\.+ myobtained int = 1\n" +
  83. "\\.+ myexpected int = 2\n\n"
  84. testHelperFailure(c, "Check(1, checker, 2)", false, false, log,
  85. func() interface{} {
  86. return c.Check(1, checker, 2)
  87. })
  88. }
  89. func (s *HelpersS) TestCheckFailWithExpectedAndComment(c *check.C) {
  90. checker := &MyChecker{result: false}
  91. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  92. " return c\\.Check\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" +
  93. "\\.+ myobtained int = 1\n" +
  94. "\\.+ myexpected int = 2\n" +
  95. "\\.+ Hello world!\n\n"
  96. testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
  97. func() interface{} {
  98. return c.Check(1, checker, 2, myComment("Hello world!"))
  99. })
  100. }
  101. func (s *HelpersS) TestCheckFailWithExpectedAndStaticComment(c *check.C) {
  102. checker := &MyChecker{result: false}
  103. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  104. " // Nice leading comment\\.\n" +
  105. " return c\\.Check\\(1, checker, 2\\) // Hello there\n" +
  106. "\\.+ myobtained int = 1\n" +
  107. "\\.+ myexpected int = 2\n\n"
  108. testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log,
  109. func() interface{} {
  110. // Nice leading comment.
  111. return c.Check(1, checker, 2) // Hello there
  112. })
  113. }
  114. func (s *HelpersS) TestCheckFailWithoutExpected(c *check.C) {
  115. checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
  116. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  117. " return c\\.Check\\(1, checker\\)\n" +
  118. "\\.+ myvalue int = 1\n\n"
  119. testHelperFailure(c, "Check(1, checker)", false, false, log,
  120. func() interface{} {
  121. return c.Check(1, checker)
  122. })
  123. }
  124. func (s *HelpersS) TestCheckFailWithoutExpectedAndMessage(c *check.C) {
  125. checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
  126. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  127. " return c\\.Check\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" +
  128. "\\.+ myvalue int = 1\n" +
  129. "\\.+ Hello world!\n\n"
  130. testHelperFailure(c, "Check(1, checker, msg)", false, false, log,
  131. func() interface{} {
  132. return c.Check(1, checker, myComment("Hello world!"))
  133. })
  134. }
  135. func (s *HelpersS) TestCheckWithMissingExpected(c *check.C) {
  136. checker := &MyChecker{result: true}
  137. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  138. " return c\\.Check\\(1, checker\\)\n" +
  139. "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" +
  140. "\\.+ Wrong number of parameters for MyChecker: " +
  141. "want 3, got 2\n\n"
  142. testHelperFailure(c, "Check(1, checker, !?)", false, false, log,
  143. func() interface{} {
  144. return c.Check(1, checker)
  145. })
  146. }
  147. func (s *HelpersS) TestCheckWithTooManyExpected(c *check.C) {
  148. checker := &MyChecker{result: true}
  149. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  150. " return c\\.Check\\(1, checker, 2, 3\\)\n" +
  151. "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" +
  152. "\\.+ Wrong number of parameters for MyChecker: " +
  153. "want 3, got 4\n\n"
  154. testHelperFailure(c, "Check(1, checker, 2, 3)", false, false, log,
  155. func() interface{} {
  156. return c.Check(1, checker, 2, 3)
  157. })
  158. }
  159. func (s *HelpersS) TestCheckWithError(c *check.C) {
  160. checker := &MyChecker{result: false, error: "Some not so cool data provided!"}
  161. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  162. " return c\\.Check\\(1, checker, 2\\)\n" +
  163. "\\.+ myobtained int = 1\n" +
  164. "\\.+ myexpected int = 2\n" +
  165. "\\.+ Some not so cool data provided!\n\n"
  166. testHelperFailure(c, "Check(1, checker, 2)", false, false, log,
  167. func() interface{} {
  168. return c.Check(1, checker, 2)
  169. })
  170. }
  171. func (s *HelpersS) TestCheckWithNilChecker(c *check.C) {
  172. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  173. " return c\\.Check\\(1, nil\\)\n" +
  174. "\\.+ Check\\(obtained, nil!\\?, \\.\\.\\.\\):\n" +
  175. "\\.+ Oops\\.\\. you've provided a nil checker!\n\n"
  176. testHelperFailure(c, "Check(obtained, nil)", false, false, log,
  177. func() interface{} {
  178. return c.Check(1, nil)
  179. })
  180. }
  181. func (s *HelpersS) TestCheckWithParamsAndNamesMutation(c *check.C) {
  182. checker := &MyChecker{result: false, params: []interface{}{3, 4}, names: []string{"newobtained", "newexpected"}}
  183. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  184. " return c\\.Check\\(1, checker, 2\\)\n" +
  185. "\\.+ newobtained int = 3\n" +
  186. "\\.+ newexpected int = 4\n\n"
  187. testHelperFailure(c, "Check(1, checker, 2) with mutation", false, false, log,
  188. func() interface{} {
  189. return c.Check(1, checker, 2)
  190. })
  191. }
  192. // -----------------------------------------------------------------------
  193. // Tests for Assert(), mostly the same as for Check() above.
  194. func (s *HelpersS) TestAssertSucceedWithExpected(c *check.C) {
  195. checker := &MyChecker{result: true}
  196. testHelperSuccess(c, "Assert(1, checker, 2)", nil, func() interface{} {
  197. c.Assert(1, checker, 2)
  198. return nil
  199. })
  200. if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) {
  201. c.Fatalf("Bad params for check: %#v", checker.params)
  202. }
  203. }
  204. func (s *HelpersS) TestAssertSucceedWithoutExpected(c *check.C) {
  205. checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
  206. testHelperSuccess(c, "Assert(1, checker)", nil, func() interface{} {
  207. c.Assert(1, checker)
  208. return nil
  209. })
  210. if !reflect.DeepEqual(checker.params, []interface{}{1}) {
  211. c.Fatalf("Bad params for check: %#v", checker.params)
  212. }
  213. }
  214. func (s *HelpersS) TestAssertFailWithExpected(c *check.C) {
  215. checker := &MyChecker{result: false}
  216. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  217. " c\\.Assert\\(1, checker, 2\\)\n" +
  218. "\\.+ myobtained int = 1\n" +
  219. "\\.+ myexpected int = 2\n\n"
  220. testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log,
  221. func() interface{} {
  222. c.Assert(1, checker, 2)
  223. return nil
  224. })
  225. }
  226. func (s *HelpersS) TestAssertFailWithExpectedAndMessage(c *check.C) {
  227. checker := &MyChecker{result: false}
  228. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  229. " c\\.Assert\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" +
  230. "\\.+ myobtained int = 1\n" +
  231. "\\.+ myexpected int = 2\n" +
  232. "\\.+ Hello world!\n\n"
  233. testHelperFailure(c, "Assert(1, checker, 2, msg)", nil, true, log,
  234. func() interface{} {
  235. c.Assert(1, checker, 2, myComment("Hello world!"))
  236. return nil
  237. })
  238. }
  239. func (s *HelpersS) TestAssertFailWithoutExpected(c *check.C) {
  240. checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
  241. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  242. " c\\.Assert\\(1, checker\\)\n" +
  243. "\\.+ myvalue int = 1\n\n"
  244. testHelperFailure(c, "Assert(1, checker)", nil, true, log,
  245. func() interface{} {
  246. c.Assert(1, checker)
  247. return nil
  248. })
  249. }
  250. func (s *HelpersS) TestAssertFailWithoutExpectedAndMessage(c *check.C) {
  251. checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}}
  252. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  253. " c\\.Assert\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" +
  254. "\\.+ myvalue int = 1\n" +
  255. "\\.+ Hello world!\n\n"
  256. testHelperFailure(c, "Assert(1, checker, msg)", nil, true, log,
  257. func() interface{} {
  258. c.Assert(1, checker, myComment("Hello world!"))
  259. return nil
  260. })
  261. }
  262. func (s *HelpersS) TestAssertWithMissingExpected(c *check.C) {
  263. checker := &MyChecker{result: true}
  264. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  265. " c\\.Assert\\(1, checker\\)\n" +
  266. "\\.+ Assert\\(myobtained, MyChecker, myexpected\\):\n" +
  267. "\\.+ Wrong number of parameters for MyChecker: " +
  268. "want 3, got 2\n\n"
  269. testHelperFailure(c, "Assert(1, checker, !?)", nil, true, log,
  270. func() interface{} {
  271. c.Assert(1, checker)
  272. return nil
  273. })
  274. }
  275. func (s *HelpersS) TestAssertWithError(c *check.C) {
  276. checker := &MyChecker{result: false, error: "Some not so cool data provided!"}
  277. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  278. " c\\.Assert\\(1, checker, 2\\)\n" +
  279. "\\.+ myobtained int = 1\n" +
  280. "\\.+ myexpected int = 2\n" +
  281. "\\.+ Some not so cool data provided!\n\n"
  282. testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log,
  283. func() interface{} {
  284. c.Assert(1, checker, 2)
  285. return nil
  286. })
  287. }
  288. func (s *HelpersS) TestAssertWithNilChecker(c *check.C) {
  289. log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" +
  290. " c\\.Assert\\(1, nil\\)\n" +
  291. "\\.+ Assert\\(obtained, nil!\\?, \\.\\.\\.\\):\n" +
  292. "\\.+ Oops\\.\\. you've provided a nil checker!\n\n"
  293. testHelperFailure(c, "Assert(obtained, nil)", nil, true, log,
  294. func() interface{} {
  295. c.Assert(1, nil)
  296. return nil
  297. })
  298. }
  299. // -----------------------------------------------------------------------
  300. // Ensure that values logged work properly in some interesting cases.
  301. func (s *HelpersS) TestValueLoggingWithArrays(c *check.C) {
  302. checker := &MyChecker{result: false}
  303. log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
  304. " return c\\.Check\\(\\[\\]byte{1, 2}, checker, \\[\\]byte{1, 3}\\)\n" +
  305. "\\.+ myobtained \\[\\]uint8 = \\[\\]byte{0x1, 0x2}\n" +
  306. "\\.+ myexpected \\[\\]uint8 = \\[\\]byte{0x1, 0x3}\n\n"
  307. testHelperFailure(c, "Check([]byte{1}, chk, []byte{3})", false, false, log,
  308. func() interface{} {
  309. return c.Check([]byte{1, 2}, checker, []byte{1, 3})
  310. })
  311. }
  312. func (s *HelpersS) TestValueLoggingWithMultiLine(c *check.C) {
  313. checker := &MyChecker{result: false}
  314. log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
  315. " return c\\.Check\\(\"a\\\\nb\\\\n\", checker, \"a\\\\nb\\\\nc\"\\)\n" +
  316. "\\.+ myobtained string = \"\" \\+\n" +
  317. "\\.+ \"a\\\\n\" \\+\n" +
  318. "\\.+ \"b\\\\n\"\n" +
  319. "\\.+ myexpected string = \"\" \\+\n" +
  320. "\\.+ \"a\\\\n\" \\+\n" +
  321. "\\.+ \"b\\\\n\" \\+\n" +
  322. "\\.+ \"c\"\n\n"
  323. testHelperFailure(c, `Check("a\nb\n", chk, "a\nb\nc")`, false, false, log,
  324. func() interface{} {
  325. return c.Check("a\nb\n", checker, "a\nb\nc")
  326. })
  327. }
  328. func (s *HelpersS) TestValueLoggingWithMultiLineException(c *check.C) {
  329. // If the newline is at the end of the string, don't log as multi-line.
  330. checker := &MyChecker{result: false}
  331. log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" +
  332. " return c\\.Check\\(\"a b\\\\n\", checker, \"a\\\\nb\"\\)\n" +
  333. "\\.+ myobtained string = \"a b\\\\n\"\n" +
  334. "\\.+ myexpected string = \"\" \\+\n" +
  335. "\\.+ \"a\\\\n\" \\+\n" +
  336. "\\.+ \"b\"\n\n"
  337. testHelperFailure(c, `Check("a b\n", chk, "a\nb")`, false, false, log,
  338. func() interface{} {
  339. return c.Check("a b\n", checker, "a\nb")
  340. })
  341. }
  342. // -----------------------------------------------------------------------
  343. // MakeDir() tests.
  344. type MkDirHelper struct {
  345. path1 string
  346. path2 string
  347. isDir1 bool
  348. isDir2 bool
  349. isDir3 bool
  350. isDir4 bool
  351. }
  352. func (s *MkDirHelper) SetUpSuite(c *check.C) {
  353. s.path1 = c.MkDir()
  354. s.isDir1 = isDir(s.path1)
  355. }
  356. func (s *MkDirHelper) Test(c *check.C) {
  357. s.path2 = c.MkDir()
  358. s.isDir2 = isDir(s.path2)
  359. }
  360. func (s *MkDirHelper) TearDownSuite(c *check.C) {
  361. s.isDir3 = isDir(s.path1)
  362. s.isDir4 = isDir(s.path2)
  363. }
  364. func (s *HelpersS) TestMkDir(c *check.C) {
  365. helper := MkDirHelper{}
  366. output := String{}
  367. check.Run(&helper, &check.RunConf{Output: &output})
  368. c.Assert(output.value, check.Equals, "")
  369. c.Check(helper.isDir1, check.Equals, true)
  370. c.Check(helper.isDir2, check.Equals, true)
  371. c.Check(helper.isDir3, check.Equals, true)
  372. c.Check(helper.isDir4, check.Equals, true)
  373. c.Check(helper.path1, check.Not(check.Equals),
  374. helper.path2)
  375. c.Check(isDir(helper.path1), check.Equals, false)
  376. c.Check(isDir(helper.path2), check.Equals, false)
  377. }
  378. func isDir(path string) bool {
  379. if stat, err := os.Stat(path); err == nil {
  380. return stat.IsDir()
  381. }
  382. return false
  383. }
  384. // Concurrent logging should not corrupt the underling buffer.
  385. // Use go test -race to detect the race in this test.
  386. func (s *HelpersS) TestConcurrentLogging(c *check.C) {
  387. defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(runtime.NumCPU()))
  388. var start, stop sync.WaitGroup
  389. start.Add(1)
  390. for i, n := 0, runtime.NumCPU()*2; i < n; i++ {
  391. stop.Add(1)
  392. go func(i int) {
  393. start.Wait()
  394. for j := 0; j < 30; j++ {
  395. c.Logf("Worker %d: line %d", i, j)
  396. }
  397. stop.Done()
  398. }(i)
  399. }
  400. start.Done()
  401. stop.Wait()
  402. }
  403. // -----------------------------------------------------------------------
  404. // Test the TestName function
  405. type TestNameHelper struct {
  406. name1 string
  407. name2 string
  408. name3 string
  409. name4 string
  410. name5 string
  411. }
  412. func (s *TestNameHelper) SetUpSuite(c *check.C) { s.name1 = c.TestName() }
  413. func (s *TestNameHelper) SetUpTest(c *check.C) { s.name2 = c.TestName() }
  414. func (s *TestNameHelper) Test(c *check.C) { s.name3 = c.TestName() }
  415. func (s *TestNameHelper) TearDownTest(c *check.C) { s.name4 = c.TestName() }
  416. func (s *TestNameHelper) TearDownSuite(c *check.C) { s.name5 = c.TestName() }
  417. func (s *HelpersS) TestTestName(c *check.C) {
  418. helper := TestNameHelper{}
  419. output := String{}
  420. check.Run(&helper, &check.RunConf{Output: &output})
  421. c.Check(helper.name1, check.Equals, "")
  422. c.Check(helper.name2, check.Equals, "TestNameHelper.Test")
  423. c.Check(helper.name3, check.Equals, "TestNameHelper.Test")
  424. c.Check(helper.name4, check.Equals, "TestNameHelper.Test")
  425. c.Check(helper.name5, check.Equals, "")
  426. }
  427. // -----------------------------------------------------------------------
  428. // A couple of helper functions to test helper functions. :-)
  429. func testHelperSuccess(c *check.C, name string, expectedResult interface{}, closure func() interface{}) {
  430. var result interface{}
  431. defer (func() {
  432. if err := recover(); err != nil {
  433. panic(err)
  434. }
  435. checkState(c, result,
  436. &expectedState{
  437. name: name,
  438. result: expectedResult,
  439. failed: false,
  440. log: "",
  441. })
  442. })()
  443. result = closure()
  444. }
  445. func testHelperFailure(c *check.C, name string, expectedResult interface{}, shouldStop bool, log string, closure func() interface{}) {
  446. var result interface{}
  447. defer (func() {
  448. if err := recover(); err != nil {
  449. panic(err)
  450. }
  451. checkState(c, result,
  452. &expectedState{
  453. name: name,
  454. result: expectedResult,
  455. failed: true,
  456. log: log,
  457. })
  458. })()
  459. result = closure()
  460. if shouldStop {
  461. c.Logf("%s didn't stop when it should", name)
  462. }
  463. }