cell_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. package xlsx
  2. import (
  3. "math"
  4. "time"
  5. . "gopkg.in/check.v1"
  6. )
  7. type CellSuite struct{}
  8. var _ = Suite(&CellSuite{})
  9. // Test that we can set and get a Value from a Cell
  10. func (s *CellSuite) TestValueSet(c *C) {
  11. // Note, this test is fairly pointless, it serves mostly to
  12. // reinforce that this functionality is important, and should
  13. // the mechanics of this all change at some point, to remind
  14. // us not to lose this.
  15. cell := Cell{}
  16. cell.Value = "A string"
  17. c.Assert(cell.Value, Equals, "A string")
  18. }
  19. // Test that GetStyle correctly converts the xlsxStyle.Fonts.
  20. func (s *CellSuite) TestGetStyleWithFonts(c *C) {
  21. font := NewFont(10, "Calibra")
  22. style := NewStyle()
  23. style.Font = *font
  24. cell := &Cell{Value: "123", style: style}
  25. style = cell.GetStyle()
  26. c.Assert(style, NotNil)
  27. c.Assert(style.Font.Size, Equals, 10)
  28. c.Assert(style.Font.Name, Equals, "Calibra")
  29. }
  30. // Test that SetStyle correctly translates into a xlsxFont element
  31. func (s *CellSuite) TestSetStyleWithFonts(c *C) {
  32. file := NewFile()
  33. sheet, _ := file.AddSheet("Test")
  34. row := sheet.AddRow()
  35. cell := row.AddCell()
  36. font := NewFont(12, "Calibra")
  37. style := NewStyle()
  38. style.Font = *font
  39. cell.SetStyle(style)
  40. style = cell.GetStyle()
  41. xFont, _, _, _ := style.makeXLSXStyleElements()
  42. c.Assert(xFont.Sz.Val, Equals, "12")
  43. c.Assert(xFont.Name.Val, Equals, "Calibra")
  44. }
  45. // Test that GetStyle correctly converts the xlsxStyle.Fills.
  46. func (s *CellSuite) TestGetStyleWithFills(c *C) {
  47. fill := *NewFill("solid", "FF000000", "00FF0000")
  48. style := NewStyle()
  49. style.Fill = fill
  50. cell := &Cell{Value: "123", style: style}
  51. style = cell.GetStyle()
  52. _, xFill, _, _ := style.makeXLSXStyleElements()
  53. c.Assert(xFill.PatternFill.PatternType, Equals, "solid")
  54. c.Assert(xFill.PatternFill.BgColor.RGB, Equals, "00FF0000")
  55. c.Assert(xFill.PatternFill.FgColor.RGB, Equals, "FF000000")
  56. }
  57. // Test that SetStyle correctly updates xlsxStyle.Fills.
  58. func (s *CellSuite) TestSetStyleWithFills(c *C) {
  59. file := NewFile()
  60. sheet, _ := file.AddSheet("Test")
  61. row := sheet.AddRow()
  62. cell := row.AddCell()
  63. fill := NewFill("solid", "00FF0000", "FF000000")
  64. style := NewStyle()
  65. style.Fill = *fill
  66. cell.SetStyle(style)
  67. style = cell.GetStyle()
  68. _, xFill, _, _ := style.makeXLSXStyleElements()
  69. xPatternFill := xFill.PatternFill
  70. c.Assert(xPatternFill.PatternType, Equals, "solid")
  71. c.Assert(xPatternFill.FgColor.RGB, Equals, "00FF0000")
  72. c.Assert(xPatternFill.BgColor.RGB, Equals, "FF000000")
  73. }
  74. // Test that GetStyle correctly converts the xlsxStyle.Borders.
  75. func (s *CellSuite) TestGetStyleWithBorders(c *C) {
  76. border := *NewBorder("thin", "thin", "thin", "thin")
  77. style := NewStyle()
  78. style.Border = border
  79. cell := Cell{Value: "123", style: style}
  80. style = cell.GetStyle()
  81. _, _, xBorder, _ := style.makeXLSXStyleElements()
  82. c.Assert(xBorder.Left.Style, Equals, "thin")
  83. c.Assert(xBorder.Right.Style, Equals, "thin")
  84. c.Assert(xBorder.Top.Style, Equals, "thin")
  85. c.Assert(xBorder.Bottom.Style, Equals, "thin")
  86. }
  87. // We can return a string representation of the formatted data
  88. func (l *CellSuite) TestSetFloatWithFormat(c *C) {
  89. cell := Cell{}
  90. cell.SetFloatWithFormat(37947.75334343, "yyyy/mm/dd")
  91. c.Assert(cell.Value, Equals, "37947.75334343")
  92. c.Assert(cell.NumFmt, Equals, "yyyy/mm/dd")
  93. c.Assert(cell.Type(), Equals, CellTypeNumeric)
  94. }
  95. func (l *CellSuite) TestSetFloat(c *C) {
  96. cell := Cell{}
  97. cell.SetFloat(0)
  98. c.Assert(cell.Value, Equals, "0")
  99. cell.SetFloat(0.000005)
  100. c.Assert(cell.Value, Equals, "5e-06")
  101. cell.SetFloat(100.0)
  102. c.Assert(cell.Value, Equals, "100")
  103. cell.SetFloat(37947.75334343)
  104. c.Assert(cell.Value, Equals, "37947.75334343")
  105. }
  106. func (l *CellSuite) TestGeneralNumberHandling(c *C) {
  107. // If you go to Excel, make a new file, type 18.99 in a cell, and save, what you will get is a
  108. // cell where the format is General and the storage type is Number, that contains the value 18.989999999999998.
  109. // The correct way to format this should be 18.99.
  110. // 1.1 will get you the same, with a stored value of 1.1000000000000001.
  111. // Also, numbers greater than 1e11 and less than 1e-9 wil be shown as scientific notation.
  112. testCases := []struct {
  113. value string
  114. formattedValueOutput string
  115. noExpValueOutput string
  116. }{
  117. {
  118. value: "18.989999999999998",
  119. formattedValueOutput: "18.99",
  120. noExpValueOutput: "18.99",
  121. },
  122. {
  123. value: "1.1000000000000001",
  124. formattedValueOutput: "1.1",
  125. noExpValueOutput: "1.1",
  126. },
  127. {
  128. value: "0.0000000000000001",
  129. formattedValueOutput: "1E-16",
  130. noExpValueOutput: "0.0000000000000001",
  131. },
  132. {
  133. value: "0.000000000000008",
  134. formattedValueOutput: "8E-15",
  135. noExpValueOutput: "0.000000000000008",
  136. },
  137. {
  138. value: "1000000000000000000",
  139. formattedValueOutput: "1E+18",
  140. noExpValueOutput: "1000000000000000000",
  141. },
  142. {
  143. value: "1230000000000000000",
  144. formattedValueOutput: "1.23E+18",
  145. noExpValueOutput: "1230000000000000000",
  146. },
  147. {
  148. value: "12345678",
  149. formattedValueOutput: "12345678",
  150. noExpValueOutput: "12345678",
  151. },
  152. {
  153. value: "0",
  154. formattedValueOutput: "0",
  155. noExpValueOutput: "0",
  156. },
  157. {
  158. value: "-18.989999999999998",
  159. formattedValueOutput: "-18.99",
  160. noExpValueOutput: "-18.99",
  161. },
  162. {
  163. value: "-1.1000000000000001",
  164. formattedValueOutput: "-1.1",
  165. noExpValueOutput: "-1.1",
  166. },
  167. {
  168. value: "-0.0000000000000001",
  169. formattedValueOutput: "-1E-16",
  170. noExpValueOutput: "-0.0000000000000001",
  171. },
  172. {
  173. value: "-0.000000000000008",
  174. formattedValueOutput: "-8E-15",
  175. noExpValueOutput: "-0.000000000000008",
  176. },
  177. {
  178. value: "-1000000000000000000",
  179. formattedValueOutput: "-1E+18",
  180. noExpValueOutput: "-1000000000000000000",
  181. },
  182. {
  183. value: "-1230000000000000000",
  184. formattedValueOutput: "-1.23E+18",
  185. noExpValueOutput: "-1230000000000000000",
  186. },
  187. {
  188. value: "-12345678",
  189. formattedValueOutput: "-12345678",
  190. noExpValueOutput: "-12345678",
  191. },
  192. {
  193. value: "",
  194. formattedValueOutput: "",
  195. noExpValueOutput: "",
  196. },
  197. }
  198. for _, testCase := range testCases {
  199. cell := Cell{
  200. cellType: CellTypeNumeric,
  201. NumFmt: builtInNumFmt[builtInNumFmtIndex_GENERAL],
  202. Value: testCase.value,
  203. }
  204. val, err := cell.FormattedValue()
  205. if err != nil {
  206. c.Fatal(err)
  207. }
  208. c.Assert(val, Equals, testCase.formattedValueOutput)
  209. val, err = cell.GeneralNumericWithoutScientific()
  210. if err != nil {
  211. c.Fatal(err)
  212. }
  213. c.Assert(val, Equals, testCase.noExpValueOutput)
  214. }
  215. }
  216. func (s *CellSuite) TestGetTime(c *C) {
  217. cell := Cell{}
  218. cell.SetFloat(0)
  219. date, err := cell.GetTime(false)
  220. c.Assert(err, Equals, nil)
  221. c.Assert(date, Equals, time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC))
  222. cell.SetFloat(39813.0)
  223. date, err = cell.GetTime(true)
  224. c.Assert(err, Equals, nil)
  225. c.Assert(date, Equals, time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC))
  226. cell.Value = "d"
  227. _, err = cell.GetTime(false)
  228. c.Assert(err, NotNil)
  229. }
  230. // FormattedValue returns an error for formatting errors
  231. func (l *CellSuite) TestFormattedValueErrorsOnBadFormat(c *C) {
  232. cell := Cell{Value: "Fudge Cake"}
  233. cell.NumFmt = "#,##0 ;(#,##0)"
  234. value, err := cell.FormattedValue()
  235. c.Assert(value, Equals, "Fudge Cake")
  236. c.Assert(err, NotNil)
  237. c.Assert(err.Error(), Equals, "strconv.ParseFloat: parsing \"Fudge Cake\": invalid syntax")
  238. }
  239. // FormattedValue returns a string containing error text for formatting errors
  240. func (l *CellSuite) TestFormattedValueReturnsErrorAsValueForBadFormat(c *C) {
  241. cell := Cell{Value: "Fudge Cake"}
  242. cell.NumFmt = "#,##0 ;(#,##0)"
  243. _, err := cell.FormattedValue()
  244. c.Assert(err.Error(), Equals, "strconv.ParseFloat: parsing \"Fudge Cake\": invalid syntax")
  245. }
  246. // formattedValueChecker removes all the boilerplate for testing Cell.FormattedValue
  247. // after its change from returning one value (a string) to two values (string, error)
  248. // This allows all the old one-line asserts in the test to continue to be one
  249. // line, instead of multi-line with error checking.
  250. type formattedValueChecker struct {
  251. c *C
  252. }
  253. func (fvc *formattedValueChecker) Equals(cell Cell, expected string) {
  254. val, err := cell.FormattedValue()
  255. if err != nil {
  256. fvc.c.Error(err)
  257. }
  258. fvc.c.Assert(val, Equals, expected)
  259. }
  260. // We can return a string representation of the formatted data
  261. func (l *CellSuite) TestFormattedValue(c *C) {
  262. // XXX TODO, this test should probably be split down, and made
  263. // in terms of SafeFormattedValue, as FormattedValue wraps
  264. // that function now.
  265. cell := Cell{Value: "37947.7500001"}
  266. negativeCell := Cell{Value: "-37947.7500001"}
  267. smallCell := Cell{Value: "0.007"}
  268. earlyCell := Cell{Value: "2.1"}
  269. fvc := formattedValueChecker{c: c}
  270. cell.NumFmt = "general"
  271. fvc.Equals(cell, "37947.7500001")
  272. negativeCell.NumFmt = "general"
  273. fvc.Equals(negativeCell, "-37947.7500001")
  274. // TODO: This test is currently broken. For a string type cell, I
  275. // don't think FormattedValue() should be doing a numeric conversion on the value
  276. // before returning the string.
  277. cell.NumFmt = "0"
  278. fvc.Equals(cell, "37947")
  279. cell.NumFmt = "#,##0" // For the time being we're not doing
  280. // this comma formatting, so it'll fall back to the related
  281. // non-comma form.
  282. fvc.Equals(cell, "37947")
  283. cell.NumFmt = "#,##0.00;(#,##0.00)"
  284. fvc.Equals(cell, "37947.75")
  285. cell.NumFmt = "0.00"
  286. fvc.Equals(cell, "37947.75")
  287. cell.NumFmt = "#,##0.00" // For the time being we're not doing
  288. // this comma formatting, so it'll fall back to the related
  289. // non-comma form.
  290. fvc.Equals(cell, "37947.75")
  291. cell.NumFmt = "#,##0 ;(#,##0)"
  292. fvc.Equals(cell, "37947")
  293. negativeCell.NumFmt = "#,##0 ;(#,##0)"
  294. fvc.Equals(negativeCell, "(37947)")
  295. cell.NumFmt = "#,##0 ;[red](#,##0)"
  296. fvc.Equals(cell, "37947")
  297. negativeCell.NumFmt = "#,##0 ;[red](#,##0)"
  298. fvc.Equals(negativeCell, "(37947)")
  299. negativeCell.NumFmt = "#,##0.00;(#,##0.00)"
  300. fvc.Equals(negativeCell, "(-37947.75)")
  301. cell.NumFmt = "0%"
  302. fvc.Equals(cell, "3794775%")
  303. cell.NumFmt = "0.00%"
  304. fvc.Equals(cell, "3794775.00%")
  305. cell.NumFmt = "0.00e+00"
  306. fvc.Equals(cell, "3.794775e+04")
  307. cell.NumFmt = "##0.0e+0" // This is wrong, but we'll use it for now.
  308. fvc.Equals(cell, "3.794775e+04")
  309. cell.NumFmt = "mm-dd-yy"
  310. fvc.Equals(cell, "11-22-03")
  311. cell.NumFmt = "d-mmm-yy"
  312. fvc.Equals(cell, "22-Nov-03")
  313. earlyCell.NumFmt = "d-mmm-yy"
  314. fvc.Equals(earlyCell, "1-Jan-00")
  315. cell.NumFmt = "d-mmm"
  316. fvc.Equals(cell, "22-Nov")
  317. earlyCell.NumFmt = "d-mmm"
  318. fvc.Equals(earlyCell, "1-Jan")
  319. cell.NumFmt = "mmm-yy"
  320. fvc.Equals(cell, "Nov-03")
  321. cell.NumFmt = "h:mm am/pm"
  322. fvc.Equals(cell, "6:00 pm")
  323. smallCell.NumFmt = "h:mm am/pm"
  324. fvc.Equals(smallCell, "12:10 am")
  325. cell.NumFmt = "h:mm:ss am/pm"
  326. fvc.Equals(cell, "6:00:00 pm")
  327. cell.NumFmt = "hh:mm:ss"
  328. fvc.Equals(cell, "18:00:00")
  329. smallCell.NumFmt = "h:mm:ss am/pm"
  330. fvc.Equals(smallCell, "12:10:04 am")
  331. cell.NumFmt = "h:mm"
  332. fvc.Equals(cell, "18:00")
  333. smallCell.NumFmt = "h:mm"
  334. fvc.Equals(smallCell, "00:10")
  335. smallCell.NumFmt = "hh:mm"
  336. fvc.Equals(smallCell, "00:10")
  337. cell.NumFmt = "h:mm:ss"
  338. fvc.Equals(cell, "18:00:00")
  339. cell.NumFmt = "hh:mm:ss"
  340. fvc.Equals(cell, "18:00:00")
  341. smallCell.NumFmt = "hh:mm:ss"
  342. fvc.Equals(smallCell, "00:10:04")
  343. smallCell.NumFmt = "h:mm:ss"
  344. fvc.Equals(smallCell, "00:10:04")
  345. cell.NumFmt = "m/d/yy h:mm"
  346. fvc.Equals(cell, "11/22/03 18:00")
  347. cell.NumFmt = "m/d/yy hh:mm"
  348. fvc.Equals(cell, "11/22/03 18:00")
  349. smallCell.NumFmt = "m/d/yy h:mm"
  350. fvc.Equals(smallCell, "12/30/99 00:10")
  351. smallCell.NumFmt = "m/d/yy hh:mm"
  352. fvc.Equals(smallCell, "12/30/99 00:10")
  353. earlyCell.NumFmt = "m/d/yy hh:mm"
  354. fvc.Equals(earlyCell, "1/1/00 02:24")
  355. earlyCell.NumFmt = "m/d/yy h:mm"
  356. fvc.Equals(earlyCell, "1/1/00 02:24")
  357. cell.NumFmt = "mm:ss"
  358. fvc.Equals(cell, "00:00")
  359. smallCell.NumFmt = "mm:ss"
  360. fvc.Equals(smallCell, "10:04")
  361. cell.NumFmt = "[hh]:mm:ss"
  362. fvc.Equals(cell, "18:00:00")
  363. cell.NumFmt = "[h]:mm:ss"
  364. fvc.Equals(cell, "18:00:00")
  365. smallCell.NumFmt = "[h]:mm:ss"
  366. fvc.Equals(smallCell, "10:04")
  367. const (
  368. expect1 = "0000.0086"
  369. expect2 = "1004.8000"
  370. format = "mmss.0000"
  371. tlen = len(format)
  372. )
  373. for i := 0; i < 3; i++ {
  374. tfmt := format[0 : tlen-i]
  375. cell.NumFmt = tfmt
  376. fvc.Equals(cell, expect1[0:tlen-i])
  377. smallCell.NumFmt = tfmt
  378. fvc.Equals(smallCell, expect2[0:tlen-i])
  379. }
  380. cell.NumFmt = "yyyy\\-mm\\-dd"
  381. fvc.Equals(cell, "2003\\-11\\-22")
  382. cell.NumFmt = "dd/mm/yyyy hh:mm:ss"
  383. fvc.Equals(cell, "22/11/2003 18:00:00")
  384. cell.NumFmt = "dd/mm/yy"
  385. fvc.Equals(cell, "22/11/03")
  386. earlyCell.NumFmt = "dd/mm/yy"
  387. fvc.Equals(earlyCell, "01/01/00")
  388. cell.NumFmt = "hh:mm:ss"
  389. fvc.Equals(cell, "18:00:00")
  390. smallCell.NumFmt = "hh:mm:ss"
  391. fvc.Equals(smallCell, "00:10:04")
  392. cell.NumFmt = "dd/mm/yy\\ hh:mm"
  393. fvc.Equals(cell, "22/11/03\\ 18:00")
  394. cell.NumFmt = "yyyy/mm/dd"
  395. fvc.Equals(cell, "2003/11/22")
  396. cell.NumFmt = "yy-mm-dd"
  397. fvc.Equals(cell, "03-11-22")
  398. cell.NumFmt = "d-mmm-yyyy"
  399. fvc.Equals(cell, "22-Nov-2003")
  400. earlyCell.NumFmt = "d-mmm-yyyy"
  401. fvc.Equals(earlyCell, "1-Jan-1900")
  402. cell.NumFmt = "m/d/yy"
  403. fvc.Equals(cell, "11/22/03")
  404. earlyCell.NumFmt = "m/d/yy"
  405. fvc.Equals(earlyCell, "1/1/00")
  406. cell.NumFmt = "m/d/yyyy"
  407. fvc.Equals(cell, "11/22/2003")
  408. earlyCell.NumFmt = "m/d/yyyy"
  409. fvc.Equals(earlyCell, "1/1/1900")
  410. cell.NumFmt = "dd-mmm-yyyy"
  411. fvc.Equals(cell, "22-Nov-2003")
  412. cell.NumFmt = "dd/mm/yyyy"
  413. fvc.Equals(cell, "22/11/2003")
  414. cell.NumFmt = "mm/dd/yy hh:mm am/pm"
  415. fvc.Equals(cell, "11/22/03 06:00 pm")
  416. cell.NumFmt = "mm/dd/yy h:mm am/pm"
  417. fvc.Equals(cell, "11/22/03 6:00 pm")
  418. cell.NumFmt = "mm/dd/yyyy hh:mm:ss"
  419. fvc.Equals(cell, "11/22/2003 18:00:00")
  420. smallCell.NumFmt = "mm/dd/yyyy hh:mm:ss"
  421. fvc.Equals(smallCell, "12/30/1899 00:10:04")
  422. cell.NumFmt = "yyyy-mm-dd hh:mm:ss"
  423. fvc.Equals(cell, "2003-11-22 18:00:00")
  424. smallCell.NumFmt = "yyyy-mm-dd hh:mm:ss"
  425. fvc.Equals(smallCell, "1899-12-30 00:10:04")
  426. cell.NumFmt = "mmmm d, yyyy"
  427. fvc.Equals(cell, "November 22, 2003")
  428. smallCell.NumFmt = "mmmm d, yyyy"
  429. fvc.Equals(smallCell, "December 30, 1899")
  430. cell.NumFmt = "dddd, mmmm dd, yyyy"
  431. fvc.Equals(cell, "Saturday, November 22, 2003")
  432. smallCell.NumFmt = "dddd, mmmm dd, yyyy"
  433. fvc.Equals(smallCell, "Saturday, December 30, 1899")
  434. }
  435. // test setters and getters
  436. func (s *CellSuite) TestSetterGetters(c *C) {
  437. cell := Cell{}
  438. cell.SetString("hello world")
  439. if val, err := cell.FormattedValue(); err != nil {
  440. c.Error(err)
  441. } else {
  442. c.Assert(val, Equals, "hello world")
  443. }
  444. c.Assert(cell.Type(), Equals, CellTypeString)
  445. cell.SetInt(1024)
  446. intValue, _ := cell.Int()
  447. c.Assert(intValue, Equals, 1024)
  448. c.Assert(cell.NumFmt, Equals, builtInNumFmt[builtInNumFmtIndex_GENERAL])
  449. c.Assert(cell.Type(), Equals, CellTypeGeneral)
  450. cell.SetInt64(1024)
  451. int64Value, _ := cell.Int64()
  452. c.Assert(int64Value, Equals, int64(1024))
  453. c.Assert(cell.NumFmt, Equals, builtInNumFmt[builtInNumFmtIndex_GENERAL])
  454. c.Assert(cell.Type(), Equals, CellTypeGeneral)
  455. cell.SetFloat(1.024)
  456. float, _ := cell.Float()
  457. intValue, _ = cell.Int() // convert
  458. c.Assert(float, Equals, 1.024)
  459. c.Assert(intValue, Equals, 1)
  460. c.Assert(cell.NumFmt, Equals, builtInNumFmt[builtInNumFmtIndex_GENERAL])
  461. c.Assert(cell.Type(), Equals, CellTypeGeneral)
  462. cell.SetFormula("10+20")
  463. c.Assert(cell.Formula(), Equals, "10+20")
  464. c.Assert(cell.Type(), Equals, CellTypeFormula)
  465. }
  466. // TestOddInput is a regression test for #101. When the number format
  467. // was "@" (string), the input below caused a crash in strconv.ParseFloat.
  468. // The solution was to check if cell.Value was both a CellTypeString and
  469. // had a NumFmt of "general" or "@" and short-circuit FormattedValue() if so.
  470. func (s *CellSuite) TestOddInput(c *C) {
  471. cell := Cell{}
  472. odd := `[1],[12,"DATE NOT NULL DEFAULT '0000-00-00'"]`
  473. cell.Value = odd
  474. cell.NumFmt = "@"
  475. if val, err := cell.FormattedValue(); err != nil {
  476. c.Error(err)
  477. } else {
  478. c.Assert(val, Equals, odd)
  479. }
  480. }
  481. // TestBool tests basic Bool getting and setting booleans.
  482. func (s *CellSuite) TestBool(c *C) {
  483. cell := Cell{}
  484. cell.SetBool(true)
  485. c.Assert(cell.Value, Equals, "1")
  486. c.Assert(cell.Bool(), Equals, true)
  487. cell.SetBool(false)
  488. c.Assert(cell.Value, Equals, "0")
  489. c.Assert(cell.Bool(), Equals, false)
  490. }
  491. // TestStringBool tests calling Bool on a non CellTypeBool value.
  492. func (s *CellSuite) TestStringBool(c *C) {
  493. cell := Cell{}
  494. cell.SetInt(0)
  495. c.Assert(cell.Bool(), Equals, false)
  496. cell.SetInt(1)
  497. c.Assert(cell.Bool(), Equals, true)
  498. cell.SetString("")
  499. c.Assert(cell.Bool(), Equals, false)
  500. cell.SetString("0")
  501. c.Assert(cell.Bool(), Equals, true)
  502. }
  503. // TestSetValue tests whether SetValue handle properly for different type values.
  504. func (s *CellSuite) TestSetValue(c *C) {
  505. cell := Cell{}
  506. // int
  507. for _, i := range []interface{}{1, int8(1), int16(1), int32(1), int64(1)} {
  508. cell.SetValue(i)
  509. val, err := cell.Int64()
  510. c.Assert(err, IsNil)
  511. c.Assert(val, Equals, int64(1))
  512. }
  513. // float
  514. for _, i := range []interface{}{1.11, float32(1.11), float64(1.11)} {
  515. cell.SetValue(i)
  516. val, err := cell.Float()
  517. c.Assert(err, IsNil)
  518. c.Assert(val, Equals, 1.11)
  519. }
  520. // time
  521. cell.SetValue(time.Unix(0, 0))
  522. val, err := cell.Float()
  523. c.Assert(err, IsNil)
  524. c.Assert(math.Floor(val), Equals, 25569.0)
  525. // string and nil
  526. for _, i := range []interface{}{nil, "", []byte("")} {
  527. cell.SetValue(i)
  528. c.Assert(cell.Value, Equals, "")
  529. }
  530. // others
  531. cell.SetValue([]string{"test"})
  532. c.Assert(cell.Value, Equals, "[test]")
  533. }
  534. func (s *CellSuite) TestSetDateWithOptions(c *C) {
  535. cell := Cell{}
  536. // time
  537. cell.SetDate(time.Unix(0, 0))
  538. val, err := cell.Float()
  539. c.Assert(err, IsNil)
  540. c.Assert(math.Floor(val), Equals, 25569.0)
  541. // our test subject
  542. date2016UTC := time.Date(2016, 1, 1, 12, 0, 0, 0, time.UTC)
  543. // test ny timezone
  544. nyTZ, err := time.LoadLocation("America/New_York")
  545. c.Assert(err, IsNil)
  546. cell.SetDateWithOptions(date2016UTC, DateTimeOptions{
  547. ExcelTimeFormat: "test_format1",
  548. Location: nyTZ,
  549. })
  550. val, err = cell.Float()
  551. c.Assert(err, IsNil)
  552. c.Assert(val, Equals, TimeToExcelTime(time.Date(2016, 1, 1, 7, 0, 0, 0, time.UTC)))
  553. // test jp timezone
  554. jpTZ, err := time.LoadLocation("Asia/Tokyo")
  555. c.Assert(err, IsNil)
  556. cell.SetDateWithOptions(date2016UTC, DateTimeOptions{
  557. ExcelTimeFormat: "test_format2",
  558. Location: jpTZ,
  559. })
  560. val, err = cell.Float()
  561. c.Assert(err, IsNil)
  562. c.Assert(val, Equals, TimeToExcelTime(time.Date(2016, 1, 1, 21, 0, 0, 0, time.UTC)))
  563. }
  564. func (s *CellSuite) TestIsTimeFormat(c *C) {
  565. c.Assert(isTimeFormat("yy"), Equals, true)
  566. c.Assert(isTimeFormat("hh"), Equals, true)
  567. c.Assert(isTimeFormat("h"), Equals, true)
  568. c.Assert(isTimeFormat("am/pm"), Equals, true)
  569. c.Assert(isTimeFormat("AM/PM"), Equals, true)
  570. c.Assert(isTimeFormat("A/P"), Equals, true)
  571. c.Assert(isTimeFormat("a/p"), Equals, true)
  572. c.Assert(isTimeFormat("ss"), Equals, true)
  573. c.Assert(isTimeFormat("mm"), Equals, true)
  574. c.Assert(isTimeFormat(":"), Equals, true)
  575. c.Assert(isTimeFormat("z"), Equals, false)
  576. }
  577. func (s *CellSuite) TestIs12HourtTime(c *C) {
  578. c.Assert(is12HourTime("am/pm"), Equals, true)
  579. c.Assert(is12HourTime("AM/PM"), Equals, true)
  580. c.Assert(is12HourTime("a/p"), Equals, true)
  581. c.Assert(is12HourTime("A/P"), Equals, true)
  582. c.Assert(is12HourTime("x"), Equals, false)
  583. }