read_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package xlsx
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. . "gopkg.in/check.v1"
  7. )
  8. type ReadSuite struct{}
  9. var _ = Suite(&ReadSuite{})
  10. var (
  11. errorNoPair = errors.New("Integer to be unmarshaled is not a pair")
  12. errorNotEnoughCells = errors.New("Row has not enough cells")
  13. )
  14. type pairUnmarshaler int
  15. func (i *pairUnmarshaler) Unmarshal(row *Row) error {
  16. if len(row.Cells) == 0 {
  17. return errorNotEnoughCells
  18. }
  19. cellInt, err := row.Cells[0].Int()
  20. if err != nil {
  21. return err
  22. }
  23. if cellInt%2 != 0 {
  24. return errorNoPair
  25. }
  26. *i = pairUnmarshaler(cellInt)
  27. return nil
  28. }
  29. type structUnmarshaler struct {
  30. private bool
  31. custom string
  32. normal int
  33. }
  34. func (s *structUnmarshaler) Unmarshal(r *Row) error {
  35. if len(r.Cells) < 3 {
  36. return errorNotEnoughCells
  37. }
  38. s.private = r.Cells[0].Bool()
  39. var err error
  40. s.normal, err = r.Cells[2].Int()
  41. if err != nil {
  42. return err
  43. }
  44. currency, err := r.Cells[1].FormattedValue()
  45. if err != nil {
  46. return err
  47. }
  48. s.custom = fmt.Sprintf("$ %s", currency)
  49. return nil
  50. }
  51. func (r *RowSuite) TestInterface(c *C) {
  52. var p pairUnmarshaler
  53. var s structUnmarshaler
  54. f := NewFile()
  55. sheet, _ := f.AddSheet("TestReadTime")
  56. row := sheet.AddRow()
  57. values := []interface{}{1, "500", true}
  58. row.WriteSlice(&values, -1)
  59. errPair := row.ReadStruct(&p)
  60. err := row.ReadStruct(&s)
  61. c.Assert(errPair, Equals, errorNoPair)
  62. c.Assert(err, Equals, nil)
  63. var empty pairUnmarshaler
  64. c.Assert(p, Equals, empty)
  65. c.Assert(s.normal, Equals, 1)
  66. c.Assert(s.private, Equals, true)
  67. c.Assert(s.custom, Equals, "$ 500")
  68. }
  69. func (r *RowSuite) TestTime(c *C) {
  70. type Timer struct {
  71. Initial time.Time `xlsx:"0"`
  72. Final time.Time `xlsx:"1"`
  73. }
  74. initial := time.Date(1990, 12, 30, 10, 30, 30, 0, time.UTC)
  75. t := Timer{
  76. Initial: initial,
  77. Final: initial.Add(time.Hour * 24),
  78. }
  79. f := NewFile()
  80. sheet, _ := f.AddSheet("TestReadTime")
  81. row := sheet.AddRow()
  82. row.AddCell().SetDateTime(t.Initial)
  83. ctime2 := row.AddCell()
  84. ctime2.SetDate(t.Final)
  85. t2 := Timer{}
  86. err := row.ReadStruct(&t2)
  87. if err != nil {
  88. c.Error(err)
  89. c.FailNow()
  90. }
  91. //removing ns precition
  92. t2.Initial = t2.Initial.Add(time.Duration(-1 * t2.Initial.Nanosecond()))
  93. t2.Final = t2.Final.Add(time.Duration(-1 * t2.Final.Nanosecond()))
  94. c.Assert(t2.Initial, Equals, t.Initial)
  95. c.Assert(t2.Final, Equals, t.Final)
  96. }
  97. func (r *RowSuite) TestEmbedStruct(c *C) {
  98. type Embed struct {
  99. privateVal bool `xlsx:"0"`
  100. IgnoredVal int `xlsx:"-"`
  101. VisibleVal string `xlsx:"2"`
  102. }
  103. type structTest struct {
  104. Embed
  105. FinalVal string `xlsx:"3"`
  106. }
  107. f := NewFile()
  108. sheet, _ := f.AddSheet("TestRead")
  109. row := sheet.AddRow()
  110. v := structTest{
  111. Embed: Embed{
  112. privateVal: true,
  113. IgnoredVal: 10,
  114. VisibleVal: "--This is a test value--",
  115. },
  116. FinalVal: "--end of struct",
  117. }
  118. values := []string{
  119. fmt.Sprint(v.privateVal),
  120. fmt.Sprint(v.IgnoredVal),
  121. fmt.Sprint(v.VisibleVal),
  122. fmt.Sprint(v.FinalVal),
  123. }
  124. row.WriteSlice(&values, -1)
  125. for _, cell := range row.Cells {
  126. v := cell.String()
  127. c.Log(v)
  128. }
  129. read := new(structTest)
  130. err := row.ReadStruct(read)
  131. if err != nil {
  132. c.Error(err)
  133. c.FailNow()
  134. }
  135. c.Assert(read.privateVal, Equals, false)
  136. c.Assert(read.VisibleVal, Equals, v.VisibleVal)
  137. c.Assert(read.IgnoredVal, Equals, 0)
  138. c.Assert(read.FinalVal, Equals, v.FinalVal)
  139. }
  140. func (r *RowSuite) TestReadStructPrivateFields(c *C) {
  141. type nested struct {
  142. IgnoredVal int `xlsx:"-"`
  143. VisibleVal string `xlsx:"6"`
  144. privateVal bool `xlsx:"7"`
  145. }
  146. type structTest struct {
  147. IntVal int16 `xlsx:"0"`
  148. StringVal string `xlsx:"1"`
  149. FloatVal float64 `xlsx:"2"`
  150. IgnoredVal int `xlsx:"-"`
  151. BoolVal bool `xlsx:"4"`
  152. Nested nested
  153. }
  154. val := structTest{
  155. IntVal: 16,
  156. StringVal: "heyheyhey :)!",
  157. FloatVal: 3.14159216,
  158. IgnoredVal: 7,
  159. BoolVal: true,
  160. Nested: nested{
  161. privateVal: true,
  162. IgnoredVal: 90,
  163. VisibleVal: "Hello",
  164. },
  165. }
  166. writtenValues := []string{
  167. fmt.Sprint(val.IntVal), val.StringVal, fmt.Sprint(val.FloatVal),
  168. fmt.Sprint(val.IgnoredVal), fmt.Sprint(val.BoolVal),
  169. fmt.Sprint(val.Nested.IgnoredVal), val.Nested.VisibleVal,
  170. fmt.Sprint(val.Nested.privateVal),
  171. }
  172. f := NewFile()
  173. sheet, _ := f.AddSheet("TestRead")
  174. row := sheet.AddRow()
  175. row.WriteSlice(&writtenValues, -1)
  176. for i, cell := range row.Cells {
  177. str := cell.String()
  178. c.Log(i, " ", str)
  179. }
  180. readStruct := structTest{}
  181. err := row.ReadStruct(&readStruct)
  182. if err != nil {
  183. c.Error(err)
  184. c.FailNow()
  185. }
  186. c.Assert(err, Equals, nil)
  187. c.Assert(readStruct.IntVal, Equals, val.IntVal)
  188. c.Assert(readStruct.StringVal, Equals, val.StringVal)
  189. c.Assert(readStruct.IgnoredVal, Equals, 0)
  190. c.Assert(readStruct.FloatVal, Equals, val.FloatVal)
  191. c.Assert(readStruct.BoolVal, Equals, val.BoolVal)
  192. c.Assert(readStruct.Nested.IgnoredVal, Equals, 0)
  193. c.Assert(readStruct.Nested.VisibleVal, Equals, "Hello")
  194. c.Assert(readStruct.Nested.privateVal, Equals, false)
  195. }
  196. func (r *RowSuite) TestReadStruct(c *C) {
  197. type structTest struct {
  198. IntVal int8 `xlsx:"0"`
  199. StringVal string `xlsx:"1"`
  200. FloatVal float64 `xlsx:"2"`
  201. IgnoredVal int `xlsx:"-"`
  202. BoolVal bool `xlsx:"4"`
  203. }
  204. structVal := structTest{
  205. IntVal: 10,
  206. StringVal: "heyheyhey :)!",
  207. FloatVal: 3.14159216,
  208. IgnoredVal: 7,
  209. BoolVal: true,
  210. }
  211. f := NewFile()
  212. sheet, _ := f.AddSheet("TestRead")
  213. row := sheet.AddRow()
  214. row.WriteStruct(&structVal, -1)
  215. for i, cell := range row.Cells {
  216. str := cell.String()
  217. c.Log(i, " ", str)
  218. }
  219. readStruct := &structTest{}
  220. err := row.ReadStruct(readStruct)
  221. c.Log(readStruct)
  222. c.Log(structVal)
  223. c.Assert(err, Equals, nil)
  224. c.Assert(readStruct.IntVal, Equals, structVal.IntVal)
  225. c.Assert(readStruct.StringVal, Equals, structVal.StringVal)
  226. c.Assert(readStruct.IgnoredVal, Equals, 0)
  227. c.Assert(readStruct.FloatVal, Equals, structVal.FloatVal)
  228. c.Assert(readStruct.BoolVal, Equals, structVal.BoolVal)
  229. }