main_test.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package main
  2. import (
  3. "encoding/json"
  4. "os"
  5. "path/filepath"
  6. "reflect"
  7. "testing"
  8. )
  9. func TestRecordRoundTrip(t *testing.T) {
  10. want := StudyRecord{Title: "学习 Go", Minutes: 30, Finished: true, Tags: []string{"Go", "JSON"}, Note: "复习"}
  11. data, err := encodeRecord(want)
  12. if err != nil {
  13. t.Fatalf("编码失败:%v", err)
  14. }
  15. // 测试使用隔离目录,结束后由测试框架清理。
  16. path := filepath.Join(t.TempDir(), "record.json")
  17. if err := os.WriteFile(path, data, 0600); err != nil {
  18. t.Fatalf("写文件失败:%v", err)
  19. }
  20. saved, err := os.ReadFile(path)
  21. if err != nil {
  22. t.Fatalf("读文件失败:%v", err)
  23. }
  24. got, err := decodeRecord(saved)
  25. if err != nil {
  26. t.Fatalf("解码失败:%v", err)
  27. }
  28. // 结构体含切片,不能直接用 == 比较;这里用 DeepEqual 检查内容。
  29. if !reflect.DeepEqual(got, want) {
  30. t.Errorf("往返结果=%+v,期望=%+v", got, want)
  31. }
  32. }
  33. func TestOmitEmptyNote(t *testing.T) {
  34. data, err := encodeRecord(StudyRecord{Title: "练习"})
  35. if err != nil {
  36. t.Fatal(err)
  37. }
  38. var fields map[string]json.RawMessage
  39. if err := json.Unmarshal(data, &fields); err != nil {
  40. t.Fatal(err)
  41. }
  42. if _, ok := fields["note"]; ok {
  43. t.Error("空 note 应当在编码时被省略")
  44. }
  45. if _, ok := fields["title"]; !ok {
  46. t.Error("应包含 title 字段")
  47. }
  48. }
  49. func TestDecodeInvalid(t *testing.T) {
  50. tests := []struct {
  51. name string
  52. data string
  53. }{
  54. {name: "malformed", data: `{"title":`},
  55. {name: "wrong_type", data: `{"minutes":"三十"}`},
  56. }
  57. for _, tt := range tests {
  58. t.Run(tt.name, func(t *testing.T) {
  59. if _, err := decodeRecord([]byte(tt.data)); err == nil {
  60. t.Error("非法输入应返回错误")
  61. }
  62. })
  63. }
  64. }