123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- package exchange_test
- import (
- "errors"
- "fmt"
- "io/ioutil"
- "strings"
- "testing"
- "time"
- "github.com/qor5/x/exchange"
- "github.com/stretchr/testify/assert"
- )
- func TestImport(t *testing.T) {
- for _, c := range []struct {
- name string
- metas []*exchange.Meta
- validators []func(metaValues exchange.MetaValues) error
- csvContent string
- expectRecords []*TestExchangeModel
- expectError error
- }{
- {
- name: "normal",
- metas: []*exchange.Meta{
- exchange.NewMeta("ID").PrimaryKey(true),
- exchange.NewMeta("Name").Header("Nameeee"),
- exchange.NewMeta("Age"),
- exchange.NewMeta("Birth").Setter(func(record interface{}, value string, metaValues exchange.MetaValues) error {
- r := record.(*TestExchangeModel)
- if value == "" {
- r.Birth = nil
- return nil
- }
- t, err := time.ParseInLocation("2006-01-02", value, time.UTC)
- if err != nil {
- return err
- }
- r.Birth = &t
- return nil
- }),
- },
- csvContent: `ID,Nameeee,Age,Birth
- 1,Tom,6,1939-01-01
- 2,Jerry,5,1940-02-10
- `,
- expectRecords: []*TestExchangeModel{
- {
- ID: 1,
- Name: "Tom",
- Age: ptrInt(6),
- Birth: ptrTime(time.Date(1939, 1, 1, 0, 0, 0, 0, time.UTC)),
- },
- {
- ID: 2,
- Name: "Jerry",
- Age: ptrInt(5),
- Birth: ptrTime(time.Date(1940, 2, 10, 0, 0, 0, 0, time.UTC)),
- },
- },
- expectError: nil,
- },
- {
- name: "has extra columns",
- metas: []*exchange.Meta{
- exchange.NewMeta("ID").PrimaryKey(true),
- exchange.NewMeta("Name").Header("Nameeee"),
- exchange.NewMeta("Age"),
- },
- csvContent: `ID,Nameeee,Name2,Age,Birth,Hobby
- 1,Tom,Tomey,6,1939-01-01,sleep
- `,
- expectRecords: []*TestExchangeModel{
- {
- ID: 1,
- Name: "Tom",
- Age: ptrInt(6),
- },
- },
- expectError: nil,
- },
- {
- name: "empty value",
- metas: []*exchange.Meta{
- exchange.NewMeta("ID").PrimaryKey(true),
- exchange.NewMeta("Name").Header("Nameeee"),
- exchange.NewMeta("Age"),
- },
- csvContent: `ID,Nameeee,Age,Birth
- 1,,,1939-01-01
- 2,Jerry,5,1940-02-10
- `,
- expectRecords: []*TestExchangeModel{
- {
- ID: 1,
- Name: "",
- Age: nil,
- },
- {
- ID: 2,
- Name: "Jerry",
- Age: ptrInt(5),
- },
- },
- expectError: nil,
- },
- {
- name: "missing columns",
- metas: []*exchange.Meta{
- exchange.NewMeta("ID").PrimaryKey(true),
- exchange.NewMeta("Name").Header("Nameeee"),
- exchange.NewMeta("Age"),
- },
- csvContent: `ID,Nameeee
- 1,Tom
- `,
- expectRecords: nil,
- expectError: errors.New("column Age not found"),
- },
- {
- name: "validator error",
- metas: []*exchange.Meta{
- exchange.NewMeta("ID").PrimaryKey(true),
- exchange.NewMeta("Name").Header("Nameeee"),
- },
- validators: []func(metaValues exchange.MetaValues) error{
- func(ms exchange.MetaValues) error {
- v := ms.Get("Name")
- if v == "" {
- return errors.New("name cannot be empty")
- }
- return nil
- },
- },
- csvContent: `ID,Nameeee,Age,Birth
- 1,Tom,6,1939-01-01
- 2,,5,1940-02-10
- `,
- expectRecords: nil,
- expectError: fmt.Errorf("name cannot be empty"),
- },
- } {
- initTables()
- r, err := exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(c.csvContent)))
- assert.NoError(t, err, c.name)
- err = exchange.NewImporter(&TestExchangeModel{}).
- Metas(c.metas...).
- Validators(c.validators...).
- Exec(db, r)
- if err != nil {
- assert.Equal(t, c.expectError, err, c.name)
- continue
- }
- var records []*TestExchangeModel
- err = db.Order("id asc").Find(&records).Error
- assert.NoError(t, err, c.name)
- assert.Equal(t, c.expectRecords, records, c.name)
- }
- }
- func TestReImport(t *testing.T) {
- initTables()
- var err error
- importer := exchange.NewImporter(&TestExchangeModel{}).
- Metas(
- exchange.NewMeta("ID").PrimaryKey(true),
- exchange.NewMeta("Name"),
- exchange.NewMeta("Appender").Setter(func(record interface{}, value string, metaValues exchange.MetaValues) error {
- r := record.(*TestExchangeModel)
- r.Appender += value
- return nil
- }),
- )
- // 1st import
- r, err := exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`ID,Name,Appender
- 1,Tom,aa
- 2,Jerry,bb
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- // 2nd import
- r, err = exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`ID,Name,Appender
- 1,Tomey,AA
- 2,,BB
- 3,Spike,cc
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- // 3nd import
- r, err = exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`ID,Name,Appender
- 1,Tomey2,aa
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- var records []*TestExchangeModel
- err = db.Order("id asc").Find(&records).Error
- assert.NoError(t, err)
- assert.Equal(t, []*TestExchangeModel{
- {
- ID: 1,
- Name: "Tomey2",
- Appender: "aaAAaa",
- },
- {
- ID: 2,
- Name: "",
- Appender: "bbBB",
- },
- {
- ID: 3,
- Name: "Spike",
- Appender: "cc",
- },
- }, records)
- }
- func TestEmptyPrimaryKeyValue(t *testing.T) {
- initTables()
- var err error
- importer := exchange.NewImporter(&TestExchangeModel{}).
- Metas(
- exchange.NewMeta("ID").PrimaryKey(true),
- exchange.NewMeta("Name"),
- )
- // 1st import
- r, err := exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`ID,Name
- ,Tom
- ,Jerry
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- records := make([]*TestExchangeModel, 0)
- err = db.Order("id asc").Find(&records).Error
- assert.NoError(t, err)
- assert.Equal(t, []*TestExchangeModel{
- {
- ID: 1,
- Name: "Tom",
- },
- {
- ID: 2,
- Name: "Jerry",
- },
- }, records)
- // 2nd import
- r, err = exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`ID,Name
- 1,Tomey
- ,Jerry
- ,Spike
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- records = make([]*TestExchangeModel, 0)
- err = db.Order("id asc").Find(&records).Error
- assert.NoError(t, err)
- assert.Equal(t, []*TestExchangeModel{
- {
- ID: 1,
- Name: "Tomey",
- },
- {
- ID: 2,
- Name: "Jerry",
- },
- {
- ID: 3,
- Name: "Jerry",
- },
- {
- ID: 4,
- Name: "Spike",
- },
- }, records)
- }
- func TestNoPrimaryKeyMeta(t *testing.T) {
- initTables()
- var err error
- importer := exchange.NewImporter(&TestExchangeModel{}).
- Metas(
- exchange.NewMeta("Name"),
- )
- // 1st import
- r, err := exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`Name
- Tom
- Jerry
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- records := make([]*TestExchangeModel, 0)
- err = db.Order("id asc").Find(&records).Error
- assert.NoError(t, err)
- assert.Equal(t, []*TestExchangeModel{
- {
- ID: 1,
- Name: "Tom",
- },
- {
- ID: 2,
- Name: "Jerry",
- },
- }, records)
- // 2nd import
- r, err = exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`Name
- Tom
- Jerry
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- records = make([]*TestExchangeModel, 0)
- err = db.Order("id asc").Find(&records).Error
- assert.NoError(t, err)
- assert.Equal(t, []*TestExchangeModel{
- {
- ID: 1,
- Name: "Tom",
- },
- {
- ID: 2,
- Name: "Jerry",
- },
- {
- ID: 3,
- Name: "Tom",
- },
- {
- ID: 4,
- Name: "Jerry",
- },
- }, records)
- }
- func TestCompositePrimaryKey(t *testing.T) {
- initTables()
- var err error
- // 1st import
- importer := exchange.NewImporter(&TestExchangeCompositePrimaryKeyModel{}).Metas(
- exchange.NewMeta("ID").PrimaryKey(true),
- exchange.NewMeta("Name").Header("Name").PrimaryKey(true),
- exchange.NewMeta("Age"),
- exchange.NewMeta("Appender").Setter(func(record interface{}, value string, metaValues exchange.MetaValues) error {
- r := record.(*TestExchangeCompositePrimaryKeyModel)
- r.Appender += value
- return nil
- }),
- )
- r, err := exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`ID,Name,Age,Appender
- 1,Tom,6,aa
- 1,Tom2,16,bb
- 2,Jerry,5,cc
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- records := []*TestExchangeCompositePrimaryKeyModel{}
- err = db.Order("id asc, name asc").Find(&records).Error
- assert.NoError(t, err)
- assert.Equal(t, []*TestExchangeCompositePrimaryKeyModel{
- {
- ID: 1,
- Name: "Tom",
- Age: ptrInt(6),
- Appender: "aa",
- },
- {
- ID: 1,
- Name: "Tom2",
- Age: ptrInt(16),
- Appender: "bb",
- },
- {
- ID: 2,
- Name: "Jerry",
- Age: ptrInt(5),
- Appender: "cc",
- },
- }, records)
- // 2nd import
- r, err = exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`ID,Name,Age,Appender
- 1,Tom,7,AA
- 1,Tom2,16,BB
- 2,Jerry2,6,dd
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- records = []*TestExchangeCompositePrimaryKeyModel{}
- err = db.Order("id asc, name asc").Find(&records).Error
- assert.NoError(t, err)
- assert.Equal(t, []*TestExchangeCompositePrimaryKeyModel{
- {
- ID: 1,
- Name: "Tom",
- Age: ptrInt(7),
- Appender: "aaAA",
- },
- {
- ID: 1,
- Name: "Tom2",
- Age: ptrInt(16),
- Appender: "bbBB",
- },
- {
- ID: 2,
- Name: "Jerry",
- Age: ptrInt(5),
- Appender: "cc",
- },
- {
- ID: 2,
- Name: "Jerry2",
- Age: ptrInt(6),
- Appender: "dd",
- },
- }, records)
- }
- func TestNoAffectOnOldData(t *testing.T) {
- initTables()
- var err error
- db.Create(&TestExchangeModel{
- ID: 1,
- Name: "Tom",
- Age: ptrInt(5),
- })
- importer := exchange.NewImporter(&TestExchangeModel{}).
- Metas(
- exchange.NewMeta("ID").PrimaryKey(true),
- exchange.NewMeta("Name"),
- )
- // 1st import
- r, err := exchange.NewCSVReader(ioutil.NopCloser(strings.NewReader(`ID,Name
- 1,Tom2
- `)))
- assert.NoError(t, err)
- err = importer.Exec(db, r)
- assert.NoError(t, err)
- records := make([]*TestExchangeModel, 0)
- err = db.Order("id asc").Find(&records).Error
- assert.NoError(t, err)
- assert.Equal(t, []*TestExchangeModel{
- {
- ID: 1,
- Name: "Tom2",
- Age: ptrInt(5),
- },
- }, records)
- }
|