| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // adapted from github.com/golang/appengine/datastore | 5 // adapted from github.com/golang/appengine/datastore |
| 6 | 6 |
| 7 package datastore | 7 package datastore |
| 8 | 8 |
| 9 import ( | 9 import ( |
| 10 "bytes" | 10 "bytes" |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 func (i *IDParser) getFullID() string { | 572 func (i *IDParser) getFullID() string { |
| 573 return fmt.Sprintf("%s|%d", i.parent, i.id) | 573 return fmt.Sprintf("%s|%d", i.parent, i.id) |
| 574 } | 574 } |
| 575 | 575 |
| 576 func (i *IDParser) GetAllMeta() PropertyMap { | 576 func (i *IDParser) GetAllMeta() PropertyMap { |
| 577 pm := GetPLS(i).GetAllMeta() | 577 pm := GetPLS(i).GetAllMeta() |
| 578 pm.SetMeta("id", i.getFullID()) | 578 pm.SetMeta("id", i.getFullID()) |
| 579 return pm | 579 return pm |
| 580 } | 580 } |
| 581 | 581 |
| 582 func (i *IDParser) GetMeta(key string) (interface{}, error) { | 582 func (i *IDParser) GetMeta(key string) (interface{}, bool) { |
| 583 if key == "id" { | 583 if key == "id" { |
| 584 » » return i.getFullID(), nil | 584 » » return i.getFullID(), true |
| 585 } | 585 } |
| 586 return GetPLS(i).GetMeta(key) | 586 return GetPLS(i).GetMeta(key) |
| 587 } | 587 } |
| 588 | 588 |
| 589 func (i *IDParser) GetMetaDefault(key string, dflt interface{}) interface{} { | 589 func (i *IDParser) SetMeta(key string, value interface{}) bool { |
| 590 » return GetMetaDefaultImpl(i.GetMeta, key, dflt) | |
| 591 } | |
| 592 | |
| 593 func (i *IDParser) SetMeta(key string, value interface{}) (err error) { | |
| 594 if key == "id" { | 590 if key == "id" { |
| 595 // let the panics flooowwww | 591 // let the panics flooowwww |
| 596 vS := strings.SplitN(value.(string), "|", 2) | 592 vS := strings.SplitN(value.(string), "|", 2) |
| 597 i.parent = vS[0] | 593 i.parent = vS[0] |
| 594 var err error |
| 598 i.id, err = strconv.ParseInt(vS[1], 10, 64) | 595 i.id, err = strconv.ParseInt(vS[1], 10, 64) |
| 599 » » return | 596 » » if err != nil { |
| 597 » » » panic(err) |
| 598 » » } |
| 599 » » return true |
| 600 } | 600 } |
| 601 return GetPLS(i).SetMeta(key, value) | 601 return GetPLS(i).SetMeta(key, value) |
| 602 } | 602 } |
| 603 | 603 |
| 604 type KindOverride struct { | 604 type KindOverride struct { |
| 605 ID int64 `gae:"$id"` | 605 ID int64 `gae:"$id"` |
| 606 | 606 |
| 607 customKind string `gae:"-"` | 607 customKind string `gae:"-"` |
| 608 } | 608 } |
| 609 | 609 |
| 610 var _ MetaGetterSetter = (*KindOverride)(nil) | 610 var _ MetaGetterSetter = (*KindOverride)(nil) |
| 611 | 611 |
| 612 func (i *KindOverride) GetAllMeta() PropertyMap { | 612 func (i *KindOverride) GetAllMeta() PropertyMap { |
| 613 pm := GetPLS(i).GetAllMeta() | 613 pm := GetPLS(i).GetAllMeta() |
| 614 if i.customKind != "" { | 614 if i.customKind != "" { |
| 615 pm.SetMeta("kind", i.customKind) | 615 pm.SetMeta("kind", i.customKind) |
| 616 } | 616 } |
| 617 return pm | 617 return pm |
| 618 } | 618 } |
| 619 | 619 |
| 620 func (i *KindOverride) GetMeta(key string) (interface{}, error) { | 620 func (i *KindOverride) GetMeta(key string) (interface{}, bool) { |
| 621 if key == "kind" && i.customKind != "" { | 621 if key == "kind" && i.customKind != "" { |
| 622 » » return i.customKind, nil | 622 » » return i.customKind, true |
| 623 } | 623 } |
| 624 return GetPLS(i).GetMeta(key) | 624 return GetPLS(i).GetMeta(key) |
| 625 } | 625 } |
| 626 | 626 |
| 627 func (i *KindOverride) GetMetaDefault(key string, dflt interface{}) interface{}
{ | 627 func (i *KindOverride) SetMeta(key string, value interface{}) bool { |
| 628 » return GetMetaDefaultImpl(i.GetMeta, key, dflt) | |
| 629 } | |
| 630 | |
| 631 func (i *KindOverride) SetMeta(key string, value interface{}) error { | |
| 632 if key == "kind" { | 628 if key == "kind" { |
| 633 kind := value.(string) | 629 kind := value.(string) |
| 634 if kind != "KindOverride" { | 630 if kind != "KindOverride" { |
| 635 i.customKind = kind | 631 i.customKind = kind |
| 636 } else { | 632 } else { |
| 637 i.customKind = "" | 633 i.customKind = "" |
| 638 } | 634 } |
| 639 » » return nil | 635 » » return true |
| 640 } | 636 } |
| 641 » return ErrMetaFieldUnset | 637 » return GetPLS(i).SetMeta(key, value) |
| 642 } | 638 } |
| 643 | 639 |
| 644 type EmbeddedID struct { | 640 type EmbeddedID struct { |
| 645 Thing string | 641 Thing string |
| 646 Val int | 642 Val int |
| 647 } | 643 } |
| 648 | 644 |
| 649 var _ PropertyConverter = (*EmbeddedID)(nil) | 645 var _ PropertyConverter = (*EmbeddedID)(nil) |
| 650 | 646 |
| 651 func (e *EmbeddedID) ToProperty() (ret Property, err error) { | 647 func (e *EmbeddedID) ToProperty() (ret Property, err error) { |
| (...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1615 | 1611 |
| 1616 checkErr := func(actual interface{}, expected string) bool { | 1612 checkErr := func(actual interface{}, expected string) bool { |
| 1617 if expected == "" { | 1613 if expected == "" { |
| 1618 So(actual, ShouldErrLike, nil) | 1614 So(actual, ShouldErrLike, nil) |
| 1619 } else { | 1615 } else { |
| 1620 So(actual, ShouldErrLike, expected) | 1616 So(actual, ShouldErrLike, expected) |
| 1621 } | 1617 } |
| 1622 return expected != "" | 1618 return expected != "" |
| 1623 } | 1619 } |
| 1624 | 1620 |
| 1621 getPLSErr := func(obj interface{}) (pls PropertyLoadSaver, err error) { |
| 1622 defer func() { |
| 1623 if v := recover(); v != nil { |
| 1624 err = v.(error) |
| 1625 } |
| 1626 }() |
| 1627 pls = GetPLS(obj) |
| 1628 return |
| 1629 } |
| 1630 |
| 1625 Convey("Test round-trip", t, func() { | 1631 Convey("Test round-trip", t, func() { |
| 1626 for _, tc := range testCases { | 1632 for _, tc := range testCases { |
| 1627 tc := tc | 1633 tc := tc |
| 1628 Convey(tc.desc, func() { | 1634 Convey(tc.desc, func() { |
| 1629 pls, ok := tc.src.(PropertyLoadSaver) | 1635 pls, ok := tc.src.(PropertyLoadSaver) |
| 1630 if !ok { | 1636 if !ok { |
| 1631 » » » » » pls = GetPLS(tc.src) | 1637 » » » » » var err error |
| 1632 » » » » } | 1638 » » » » » pls, err = getPLSErr(tc.src) |
| 1633 » » » » if checkErr(pls.Problem(), tc.plsErr) { | 1639 » » » » » if checkErr(err, tc.plsErr) { |
| 1634 » » » » » return | 1640 » » » » » » return |
| 1641 » » » » » } |
| 1635 } | 1642 } |
| 1636 So(pls, ShouldNotBeNil) | 1643 So(pls, ShouldNotBeNil) |
| 1637 | 1644 |
| 1638 savedProps, err := pls.Save(false) | 1645 savedProps, err := pls.Save(false) |
| 1639 if checkErr(err, tc.saveErr) { | 1646 if checkErr(err, tc.saveErr) { |
| 1640 return | 1647 return |
| 1641 } | 1648 } |
| 1642 So(savedProps, ShouldNotBeNil) | 1649 So(savedProps, ShouldNotBeNil) |
| 1643 | 1650 |
| 1644 var got interface{} | 1651 var got interface{} |
| 1645 if _, ok := tc.want.(PropertyMap); ok { | 1652 if _, ok := tc.want.(PropertyMap); ok { |
| 1646 pls = PropertyMap{} | 1653 pls = PropertyMap{} |
| 1647 got = pls | 1654 got = pls |
| 1648 } else { | 1655 } else { |
| 1649 got = reflect.New(reflect.TypeOf(tc.want
).Elem()).Interface() | 1656 got = reflect.New(reflect.TypeOf(tc.want
).Elem()).Interface() |
| 1650 if pls, ok = got.(PropertyLoadSaver); !o
k { | 1657 if pls, ok = got.(PropertyLoadSaver); !o
k { |
| 1651 » » » » » » pls = GetPLS(got) | 1658 » » » » » » var err error |
| 1659 » » » » » » pls, err = getPLSErr(got) |
| 1660 » » » » » » if checkErr(err, tc.plsLoadErr)
{ |
| 1661 » » » » » » » return |
| 1662 » » » » » » } |
| 1652 } | 1663 } |
| 1653 } | 1664 } |
| 1654 | 1665 |
| 1655 if checkErr(pls.Problem(), tc.plsLoadErr) { | |
| 1656 return | |
| 1657 } | |
| 1658 So(pls, ShouldNotBeNil) | 1666 So(pls, ShouldNotBeNil) |
| 1659 | 1667 |
| 1660 err = pls.Load(savedProps) | 1668 err = pls.Load(savedProps) |
| 1661 if checkErr(err, tc.loadErr) { | 1669 if checkErr(err, tc.loadErr) { |
| 1662 return | 1670 return |
| 1663 } | 1671 } |
| 1664 if tc.want == nil { | 1672 if tc.want == nil { |
| 1665 return | 1673 return |
| 1666 } | 1674 } |
| 1667 | 1675 |
| 1668 if gotT, ok := got.(*T); ok { | 1676 if gotT, ok := got.(*T); ok { |
| 1669 // Round tripping a time.Time can result
in a different time.Location: Local instead of UTC. | 1677 // Round tripping a time.Time can result
in a different time.Location: Local instead of UTC. |
| 1670 // We therefore test equality explicitly
, instead of relying on reflect.DeepEqual. | 1678 // We therefore test equality explicitly
, instead of relying on reflect.DeepEqual. |
| 1671 So(gotT.T.Equal(tc.want.(*T).T), ShouldB
eTrue) | 1679 So(gotT.T.Equal(tc.want.(*T).T), ShouldB
eTrue) |
| 1672 } else { | 1680 } else { |
| 1673 So(got, ShouldResemble, tc.want) | 1681 So(got, ShouldResemble, tc.want) |
| 1674 } | 1682 } |
| 1675 }) | 1683 }) |
| 1676 } | 1684 } |
| 1677 }) | 1685 }) |
| 1678 } | 1686 } |
| 1679 | 1687 |
| 1680 func TestMeta(t *testing.T) { | 1688 func TestMeta(t *testing.T) { |
| 1681 t.Parallel() | 1689 t.Parallel() |
| 1682 | 1690 |
| 1683 Convey("Test meta fields", t, func() { | 1691 Convey("Test meta fields", t, func() { |
| 1684 Convey("Can retrieve from struct", func() { | 1692 Convey("Can retrieve from struct", func() { |
| 1685 o := &N0{ID: 100} | 1693 o := &N0{ID: 100} |
| 1686 mgs := getMGS(o) | 1694 mgs := getMGS(o) |
| 1687 » » » val, err := mgs.GetMeta("id") | 1695 » » » val, ok := mgs.GetMeta("id") |
| 1688 » » » So(err, ShouldBeNil) | 1696 » » » So(ok, ShouldBeTrue) |
| 1689 So(val, ShouldEqual, 100) | 1697 So(val, ShouldEqual, 100) |
| 1690 | 1698 |
| 1691 » » » val, err = mgs.GetMeta("kind") | 1699 » » » val, ok = mgs.GetMeta("kind") |
| 1692 » » » So(err, ShouldBeNil) | 1700 » » » So(ok, ShouldBeTrue) |
| 1693 So(val, ShouldEqual, "whatnow") | 1701 So(val, ShouldEqual, "whatnow") |
| 1694 | 1702 |
| 1695 » » » So(mgs.GetMetaDefault("kind", "zappo"), ShouldEqual, "wh
atnow") | 1703 » » » So(GetMetaDefault(mgs, "kind", "zappo"), ShouldEqual, "w
hatnow") |
| 1696 » » » So(mgs.GetMetaDefault("id", "stringID"), ShouldEqual, "s
tringID") | 1704 » » » So(GetMetaDefault(mgs, "id", "stringID"), ShouldEqual, "
stringID") |
| 1697 » » » So(mgs.GetMetaDefault("id", 6), ShouldEqual, 100) | 1705 » » » So(GetMetaDefault(mgs, "id", 6), ShouldEqual, 100) |
| 1698 }) | 1706 }) |
| 1699 | 1707 |
| 1700 Convey("Getting something not there is an error", func() { | 1708 Convey("Getting something not there is an error", func() { |
| 1701 o := &N0{ID: 100} | 1709 o := &N0{ID: 100} |
| 1702 mgs := getMGS(o) | 1710 mgs := getMGS(o) |
| 1703 » » » _, err := mgs.GetMeta("wat") | 1711 » » » _, ok := mgs.GetMeta("wat") |
| 1704 » » » So(err, ShouldEqual, ErrMetaFieldUnset) | 1712 » » » So(ok, ShouldBeFalse) |
| 1705 }) | 1713 }) |
| 1706 | 1714 |
| 1707 Convey("Default works for missing fields", func() { | 1715 Convey("Default works for missing fields", func() { |
| 1708 o := &N0{ID: 100} | 1716 o := &N0{ID: 100} |
| 1709 mgs := getMGS(o) | 1717 mgs := getMGS(o) |
| 1710 » » » So(mgs.GetMetaDefault("whozit", 10), ShouldEqual, 10) | 1718 » » » So(GetMetaDefault(mgs, "whozit", 10), ShouldEqual, 10) |
| 1711 }) | 1719 }) |
| 1712 | 1720 |
| 1713 » » Convey("getting/setting from a bad struct is an error", func() { | 1721 » » Convey("getting mgs for bad struct is an error", func() { |
| 1714 » » » o := &Recursive{} | 1722 » » » So(func() { getMGS(&Recursive{}) }, ShouldPanicLike, |
| 1715 » » » mgs := getMGS(o) | 1723 » » » » `field "R" is recursively defined`) |
| 1716 » » » _, err := mgs.GetMeta("wat") | |
| 1717 » » » So(err, ShouldNotBeNil) | |
| 1718 | |
| 1719 » » » err = mgs.SetMeta("wat", 100) | |
| 1720 » » » So(err, ShouldNotBeNil) | |
| 1721 » » }) | |
| 1722 | |
| 1723 » » Convey("Default works for bad structs", func() { | |
| 1724 » » » o := &Recursive{} | |
| 1725 » » » mgs := getMGS(o) | |
| 1726 » » » So(mgs.GetMetaDefault("whozit", 10), ShouldEqual, 10) | |
| 1727 }) | 1724 }) |
| 1728 | 1725 |
| 1729 Convey("can assign values to exported meta fields", func() { | 1726 Convey("can assign values to exported meta fields", func() { |
| 1730 o := &N0{ID: 100} | 1727 o := &N0{ID: 100} |
| 1731 mgs := getMGS(o) | 1728 mgs := getMGS(o) |
| 1732 » » » err := mgs.SetMeta("id", int64(200)) | 1729 » » » So(mgs.SetMeta("id", int64(200)), ShouldBeTrue) |
| 1733 » » » So(err, ShouldBeNil) | |
| 1734 So(o.ID, ShouldEqual, 200) | 1730 So(o.ID, ShouldEqual, 200) |
| 1735 | |
| 1736 }) | 1731 }) |
| 1737 | 1732 |
| 1738 » » Convey("assigning to unsassiagnable fields is a simple error", f
unc() { | 1733 » » Convey("assigning to unsassiagnable fields returns !ok", func()
{ |
| 1739 o := &N0{ID: 100} | 1734 o := &N0{ID: 100} |
| 1740 mgs := getMGS(o) | 1735 mgs := getMGS(o) |
| 1741 » » » err := mgs.SetMeta("kind", "hi") | 1736 » » » So(mgs.SetMeta("kind", "hi"), ShouldBeFalse) |
| 1742 » » » So(err.Error(), ShouldContainSubstring, "unexported fiel
d") | 1737 » » » So(mgs.SetMeta("noob", "hi"), ShouldBeFalse) |
| 1743 | |
| 1744 » » » err = mgs.SetMeta("noob", "hi") | |
| 1745 » » » So(err, ShouldEqual, ErrMetaFieldUnset) | |
| 1746 }) | 1738 }) |
| 1747 }) | 1739 }) |
| 1748 | 1740 |
| 1749 Convey("StructPLS Miscellaneous", t, func() { | 1741 Convey("StructPLS Miscellaneous", t, func() { |
| 1750 Convey("a simple struct has a default $kind", func() { | 1742 Convey("a simple struct has a default $kind", func() { |
| 1751 So(GetPLS(&Simple{}).GetAllMeta(), ShouldResemble, Prope
rtyMap{ | 1743 So(GetPLS(&Simple{}).GetAllMeta(), ShouldResemble, Prope
rtyMap{ |
| 1752 "$kind": []Property{mpNI("Simple")}, | 1744 "$kind": []Property{mpNI("Simple")}, |
| 1753 }) | 1745 }) |
| 1754 }) | 1746 }) |
| 1755 | 1747 |
| 1756 Convey("multiple overlapping fields is an error", func() { | 1748 Convey("multiple overlapping fields is an error", func() { |
| 1757 o := &BadMeta{} | 1749 o := &BadMeta{} |
| 1758 » » » pls := GetPLS(o) | 1750 » » » So(func() { GetPLS(o) }, ShouldPanicLike, "multiple time
s") |
| 1759 » » » err := pls.Load(nil) | |
| 1760 » » » So(err, ShouldErrLike, "multiple times") | |
| 1761 » » » e := pls.Problem() | |
| 1762 » » » _, err = pls.Save(true) | |
| 1763 » » » So(err, ShouldEqual, e) | |
| 1764 » » » err = pls.Load(nil) | |
| 1765 » » » So(err, ShouldEqual, e) | |
| 1766 }) | 1751 }) |
| 1767 | 1752 |
| 1768 Convey("empty property names are invalid", func() { | 1753 Convey("empty property names are invalid", func() { |
| 1769 So(validPropertyName(""), ShouldBeFalse) | 1754 So(validPropertyName(""), ShouldBeFalse) |
| 1770 }) | 1755 }) |
| 1771 | 1756 |
| 1772 Convey("attempting to get a PLS for a non *struct is an error",
func() { | 1757 Convey("attempting to get a PLS for a non *struct is an error",
func() { |
| 1773 » » » pls := GetPLS((*[]string)(nil)) | 1758 » » » So(func() { GetPLS((*[]string)(nil)) }, ShouldPanicLike, |
| 1774 » » » So(pls.Problem(), ShouldEqual, ErrInvalidEntityType) | 1759 » » » » "cannot GetPLS(*[]string): not a pointer-to-stru
ct") |
| 1775 | |
| 1776 » » » Convey("the error PLS can still be used", func() { | |
| 1777 » » » » k, _ := pls.GetMeta("kind") | |
| 1778 » » » » So(k, ShouldBeNil) | |
| 1779 | |
| 1780 » » » » props := pls.GetAllMeta() | |
| 1781 » » » » So(props, ShouldResemble, PropertyMap{ | |
| 1782 » » » » » "$kind": []Property{mpNI("")}, | |
| 1783 » » » » }) | |
| 1784 | |
| 1785 » » » » _, err := pls.Save(true) | |
| 1786 » » » » So(err, ShouldNotBeNil) | |
| 1787 » » » }) | |
| 1788 }) | 1760 }) |
| 1789 | 1761 |
| 1790 Convey("convertible meta default types", func() { | 1762 Convey("convertible meta default types", func() { |
| 1791 type OKDefaults struct { | 1763 type OKDefaults struct { |
| 1792 When string `gae:"$when,tomorrow"` | 1764 When string `gae:"$when,tomorrow"` |
| 1793 Amount int64 `gae:"$amt,100"` | 1765 Amount int64 `gae:"$amt,100"` |
| 1794 DoIt Toggle `gae:"$doit,on"` | 1766 DoIt Toggle `gae:"$doit,on"` |
| 1795 } | 1767 } |
| 1796 okd := &OKDefaults{} | 1768 okd := &OKDefaults{} |
| 1797 pls := GetPLS(okd) | |
| 1798 mgs := getMGS(okd) | 1769 mgs := getMGS(okd) |
| 1799 So(pls.Problem(), ShouldBeNil) | |
| 1800 | 1770 |
| 1801 » » » v, err := mgs.GetMeta("when") | 1771 » » » v, ok := mgs.GetMeta("when") |
| 1802 » » » So(err, ShouldBeNil) | 1772 » » » So(ok, ShouldBeTrue) |
| 1803 So(v, ShouldEqual, "tomorrow") | 1773 So(v, ShouldEqual, "tomorrow") |
| 1804 | 1774 |
| 1805 » » » v, err = mgs.GetMeta("amt") | 1775 » » » v, ok = mgs.GetMeta("amt") |
| 1806 » » » So(err, ShouldBeNil) | 1776 » » » So(ok, ShouldBeTrue) |
| 1807 So(v, ShouldEqual, int64(100)) | 1777 So(v, ShouldEqual, int64(100)) |
| 1808 | 1778 |
| 1809 So(okd.DoIt, ShouldEqual, Auto) | 1779 So(okd.DoIt, ShouldEqual, Auto) |
| 1810 » » » v, err = mgs.GetMeta("doit") | 1780 » » » v, ok = mgs.GetMeta("doit") |
| 1811 » » » So(err, ShouldBeNil) | 1781 » » » So(ok, ShouldBeTrue) |
| 1812 So(v, ShouldBeTrue) | 1782 So(v, ShouldBeTrue) |
| 1813 | 1783 |
| 1814 » » » err = mgs.SetMeta("doit", false) | 1784 » » » So(mgs.SetMeta("doit", false), ShouldBeTrue) |
| 1815 » » » So(err, ShouldBeNil) | 1785 » » » v, ok = mgs.GetMeta("doit") |
| 1816 » » » v, err = mgs.GetMeta("doit") | 1786 » » » So(ok, ShouldBeTrue) |
| 1817 » » » So(err, ShouldBeNil) | |
| 1818 So(v, ShouldBeFalse) | 1787 So(v, ShouldBeFalse) |
| 1819 So(okd.DoIt, ShouldEqual, Off) | 1788 So(okd.DoIt, ShouldEqual, Off) |
| 1820 | 1789 |
| 1821 » » » err = mgs.SetMeta("doit", true) | 1790 » » » So(mgs.SetMeta("doit", true), ShouldBeTrue) |
| 1822 » » » So(err, ShouldBeNil) | 1791 » » » v, ok = mgs.GetMeta("doit") |
| 1823 » » » v, err = mgs.GetMeta("doit") | 1792 » » » So(ok, ShouldBeTrue) |
| 1824 » » » So(err, ShouldBeNil) | |
| 1825 So(v, ShouldBeTrue) | 1793 So(v, ShouldBeTrue) |
| 1826 So(okd.DoIt, ShouldEqual, On) | 1794 So(okd.DoIt, ShouldEqual, On) |
| 1827 | 1795 |
| 1828 Convey("Toggle fields REQUIRE a default", func() { | 1796 Convey("Toggle fields REQUIRE a default", func() { |
| 1829 type BadToggle struct { | 1797 type BadToggle struct { |
| 1830 Bad Toggle `gae:"$wut"` | 1798 Bad Toggle `gae:"$wut"` |
| 1831 } | 1799 } |
| 1832 » » » » pls := GetPLS(&BadToggle{}) | 1800 » » » » So(func() { GetPLS(&BadToggle{}) }, ShouldPanicL
ike, "bad/missing default") |
| 1833 » » » » So(pls.Problem().Error(), ShouldContainSubstring
, "bad/missing default") | |
| 1834 }) | 1801 }) |
| 1835 }) | 1802 }) |
| 1836 | 1803 |
| 1837 Convey("meta fields can be saved", func() { | 1804 Convey("meta fields can be saved", func() { |
| 1838 type OKDefaults struct { | 1805 type OKDefaults struct { |
| 1839 When string `gae:"$when,tomorrow"` | 1806 When string `gae:"$when,tomorrow"` |
| 1840 Amount int64 `gae:"$amt,100"` | 1807 Amount int64 `gae:"$amt,100"` |
| 1841 } | 1808 } |
| 1842 pls := GetPLS(&OKDefaults{}) | 1809 pls := GetPLS(&OKDefaults{}) |
| 1843 pm, err := pls.Save(true) | 1810 pm, err := pls.Save(true) |
| 1844 So(err, ShouldBeNil) | 1811 So(err, ShouldBeNil) |
| 1845 So(pm, ShouldResemble, PropertyMap{ | 1812 So(pm, ShouldResemble, PropertyMap{ |
| 1846 "$when": {mpNI("tomorrow")}, | 1813 "$when": {mpNI("tomorrow")}, |
| 1847 "$amt": {mpNI(100)}, | 1814 "$amt": {mpNI(100)}, |
| 1848 "$kind": {mpNI("OKDefaults")}, | 1815 "$kind": {mpNI("OKDefaults")}, |
| 1849 }) | 1816 }) |
| 1850 | 1817 |
| 1851 » » » v, err := pm.GetMeta("when") | 1818 » » » v, ok := pm.GetMeta("when") |
| 1852 » » » So(err, ShouldBeNil) | 1819 » » » So(ok, ShouldBeTrue) |
| 1853 So(v, ShouldEqual, "tomorrow") | 1820 So(v, ShouldEqual, "tomorrow") |
| 1854 | 1821 |
| 1855 » » » v, err = pm.GetMeta("amt") | 1822 » » » v, ok = pm.GetMeta("amt") |
| 1856 » » » So(err, ShouldBeNil) | 1823 » » » So(ok, ShouldBeTrue) |
| 1857 So(v, ShouldEqual, int64(100)) | 1824 So(v, ShouldEqual, int64(100)) |
| 1858 }) | 1825 }) |
| 1859 | 1826 |
| 1860 Convey("default are optional", func() { | 1827 Convey("default are optional", func() { |
| 1861 type OverrideDefault struct { | 1828 type OverrideDefault struct { |
| 1862 Val int64 `gae:"$val"` | 1829 Val int64 `gae:"$val"` |
| 1863 } | 1830 } |
| 1864 o := &OverrideDefault{} | 1831 o := &OverrideDefault{} |
| 1865 mgs := getMGS(o) | 1832 mgs := getMGS(o) |
| 1866 | 1833 |
| 1867 » » » v, err := mgs.GetMeta("val") | 1834 » » » v, ok := mgs.GetMeta("val") |
| 1868 » » » So(err, ShouldBeNil) | 1835 » » » So(ok, ShouldBeTrue) |
| 1869 So(v, ShouldEqual, int64(0)) | 1836 So(v, ShouldEqual, int64(0)) |
| 1870 }) | 1837 }) |
| 1871 | 1838 |
| 1872 Convey("overridable defaults", func() { | 1839 Convey("overridable defaults", func() { |
| 1873 type OverrideDefault struct { | 1840 type OverrideDefault struct { |
| 1874 Val int64 `gae:"$val,100"` | 1841 Val int64 `gae:"$val,100"` |
| 1875 } | 1842 } |
| 1876 o := &OverrideDefault{} | 1843 o := &OverrideDefault{} |
| 1877 mgs := getMGS(o) | 1844 mgs := getMGS(o) |
| 1878 | 1845 |
| 1879 » » » v, err := mgs.GetMeta("val") | 1846 » » » v, ok := mgs.GetMeta("val") |
| 1880 » » » So(err, ShouldBeNil) | 1847 » » » So(ok, ShouldBeTrue) |
| 1881 So(v, ShouldEqual, int64(100)) | 1848 So(v, ShouldEqual, int64(100)) |
| 1882 | 1849 |
| 1883 o.Val = 10 | 1850 o.Val = 10 |
| 1884 » » » v, err = mgs.GetMeta("val") | 1851 » » » v, ok = mgs.GetMeta("val") |
| 1885 » » » So(err, ShouldBeNil) | 1852 » » » So(ok, ShouldBeTrue) |
| 1886 So(v, ShouldEqual, int64(10)) | 1853 So(v, ShouldEqual, int64(10)) |
| 1887 }) | 1854 }) |
| 1888 | 1855 |
| 1889 Convey("Derived metadata fields", func() { | 1856 Convey("Derived metadata fields", func() { |
| 1890 type DerivedString string | 1857 type DerivedString string |
| 1891 type DerivedInt int16 | 1858 type DerivedInt int16 |
| 1892 type DerivedStruct struct { | 1859 type DerivedStruct struct { |
| 1893 ID DerivedString `gae:"$id"` | 1860 ID DerivedString `gae:"$id"` |
| 1894 Foo DerivedInt `gae:"$foo"` | 1861 Foo DerivedInt `gae:"$foo"` |
| 1895 } | 1862 } |
| 1896 o := &DerivedStruct{"hello", 10} | 1863 o := &DerivedStruct{"hello", 10} |
| 1897 mgs := getMGS(o) | 1864 mgs := getMGS(o) |
| 1898 » » » v, err := mgs.GetMeta("id") | 1865 » » » v, ok := mgs.GetMeta("id") |
| 1899 » » » So(err, ShouldBeNil) | 1866 » » » So(ok, ShouldBeTrue) |
| 1900 So(v, ShouldEqual, "hello") | 1867 So(v, ShouldEqual, "hello") |
| 1901 | 1868 |
| 1902 » » » v, err = mgs.GetMeta("foo") | 1869 » » » v, ok = mgs.GetMeta("foo") |
| 1903 » » » So(err, ShouldBeNil) | 1870 » » » So(ok, ShouldBeTrue) |
| 1904 So(v, ShouldEqual, int64(10)) | 1871 So(v, ShouldEqual, int64(10)) |
| 1905 | 1872 |
| 1906 » » » So(mgs.SetMeta("id", "nerds"), ShouldBeNil) | 1873 » » » So(mgs.SetMeta("id", "nerds"), ShouldBeTrue) |
| 1907 » » » So(mgs.SetMeta("foo", 20), ShouldBeNil) | 1874 » » » So(mgs.SetMeta("foo", 20), ShouldBeTrue) |
| 1908 So(o.ID, ShouldEqual, DerivedString("nerds")) | 1875 So(o.ID, ShouldEqual, DerivedString("nerds")) |
| 1909 So(o.Foo, ShouldEqual, DerivedInt(20)) | 1876 So(o.Foo, ShouldEqual, DerivedInt(20)) |
| 1910 }) | 1877 }) |
| 1911 | 1878 |
| 1912 Convey("Bad default meta type", func() { | 1879 Convey("Bad default meta type", func() { |
| 1913 type BadDefault struct { | 1880 type BadDefault struct { |
| 1914 Val time.Time `gae:"$meta,tomorrow"` | 1881 Val time.Time `gae:"$meta,tomorrow"` |
| 1915 } | 1882 } |
| 1916 » » » pls := GetPLS(&BadDefault{}) | 1883 » » » So(func() { GetPLS(&BadDefault{}) }, ShouldPanicLike, "b
ad type") |
| 1917 » » » So(pls.Problem().Error(), ShouldContainSubstring, "bad t
ype") | |
| 1918 }) | 1884 }) |
| 1919 | 1885 |
| 1920 Convey("MetaGetterSetter implementation (IDParser)", func() { | 1886 Convey("MetaGetterSetter implementation (IDParser)", func() { |
| 1921 idp := &IDParser{parent: "moo", id: 100} | 1887 idp := &IDParser{parent: "moo", id: 100} |
| 1922 mgs := getMGS(idp) | 1888 mgs := getMGS(idp) |
| 1923 » » » So(mgs.GetMetaDefault("id", ""), ShouldEqual, "moo|100") | 1889 » » » So(GetMetaDefault(mgs, "id", ""), ShouldEqual, "moo|100"
) |
| 1924 » » » So(mgs.GetMetaDefault("kind", ""), ShouldEqual, "CoolKin
d") | |
| 1925 | 1890 |
| 1926 » » » So(mgs.SetMeta("kind", "Something"), ShouldErrLike, "une
xported field") | 1891 » » » So(GetMetaDefault(mgs, "kind", ""), ShouldEqual, "CoolKi
nd") |
| 1927 » » » So(mgs.SetMeta("id", "happy|27"), ShouldBeNil) | 1892 |
| 1893 » » » So(mgs.SetMeta("kind", "Something"), ShouldBeFalse) |
| 1894 » » » So(mgs.SetMeta("id", "happy|27"), ShouldBeTrue) |
| 1928 | 1895 |
| 1929 So(idp.parent, ShouldEqual, "happy") | 1896 So(idp.parent, ShouldEqual, "happy") |
| 1930 So(idp.id, ShouldEqual, 27) | 1897 So(idp.id, ShouldEqual, 27) |
| 1931 | 1898 |
| 1932 So(mgs.GetAllMeta(), ShouldResemble, PropertyMap{ | 1899 So(mgs.GetAllMeta(), ShouldResemble, PropertyMap{ |
| 1933 "$id": {mpNI("happy|27")}, | 1900 "$id": {mpNI("happy|27")}, |
| 1934 "$kind": {mpNI("CoolKind")}, | 1901 "$kind": {mpNI("CoolKind")}, |
| 1935 }) | 1902 }) |
| 1936 }) | 1903 }) |
| 1937 | 1904 |
| 1938 Convey("MetaGetterSetter implementation (KindOverride)", func()
{ | 1905 Convey("MetaGetterSetter implementation (KindOverride)", func()
{ |
| 1939 ko := &KindOverride{ID: 20} | 1906 ko := &KindOverride{ID: 20} |
| 1940 mgs := getMGS(ko) | 1907 mgs := getMGS(ko) |
| 1941 » » » So(mgs.GetMetaDefault("kind", ""), ShouldEqual, "KindOve
rride") | 1908 » » » So(GetMetaDefault(mgs, "kind", ""), ShouldEqual, "KindOv
erride") |
| 1942 | 1909 |
| 1943 ko.customKind = "something" | 1910 ko.customKind = "something" |
| 1944 » » » So(mgs.GetMetaDefault("kind", ""), ShouldEqual, "somethi
ng") | 1911 » » » So(GetMetaDefault(mgs, "kind", ""), ShouldEqual, "someth
ing") |
| 1945 | 1912 |
| 1946 » » » So(mgs.SetMeta("kind", "Nerp"), ShouldBeNil) | 1913 » » » So(mgs.SetMeta("kind", "Nerp"), ShouldBeTrue) |
| 1947 So(ko.customKind, ShouldEqual, "Nerp") | 1914 So(ko.customKind, ShouldEqual, "Nerp") |
| 1948 | 1915 |
| 1949 » » » So(mgs.SetMeta("kind", "KindOverride"), ShouldBeNil) | 1916 » » » So(mgs.SetMeta("kind", "KindOverride"), ShouldBeTrue) |
| 1950 So(ko.customKind, ShouldEqual, "") | 1917 So(ko.customKind, ShouldEqual, "") |
| 1951 | 1918 |
| 1952 So(mgs.GetAllMeta(), ShouldResemble, PropertyMap{ | 1919 So(mgs.GetAllMeta(), ShouldResemble, PropertyMap{ |
| 1953 "$id": {mpNI(20)}, | 1920 "$id": {mpNI(20)}, |
| 1954 "$kind": {mpNI("KindOverride")}, | 1921 "$kind": {mpNI("KindOverride")}, |
| 1955 }) | 1922 }) |
| 1956 ko.customKind = "wut" | 1923 ko.customKind = "wut" |
| 1957 So(mgs.GetAllMeta(), ShouldResemble, PropertyMap{ | 1924 So(mgs.GetAllMeta(), ShouldResemble, PropertyMap{ |
| 1958 "$id": {mpNI(20)}, | 1925 "$id": {mpNI(20)}, |
| 1959 "$kind": {mpNI("wut")}, | 1926 "$kind": {mpNI("wut")}, |
| 1960 }) | 1927 }) |
| 1961 | 1928 |
| 1962 props, err := GetPLS(ko).Save(true) | 1929 props, err := GetPLS(ko).Save(true) |
| 1963 So(err, ShouldBeNil) | 1930 So(err, ShouldBeNil) |
| 1964 So(props, ShouldResemble, PropertyMap{ | 1931 So(props, ShouldResemble, PropertyMap{ |
| 1965 "$id": {mpNI(20)}, | 1932 "$id": {mpNI(20)}, |
| 1966 "$kind": {mpNI("wut")}, | 1933 "$kind": {mpNI("wut")}, |
| 1967 }) | 1934 }) |
| 1968 }) | 1935 }) |
| 1969 | 1936 |
| 1970 Convey("Embeddable Metadata structs", func() { | 1937 Convey("Embeddable Metadata structs", func() { |
| 1971 ide := &IDEmbedder{EmbeddedID{"hello", 10}} | 1938 ide := &IDEmbedder{EmbeddedID{"hello", 10}} |
| 1972 pls := GetPLS(ide) | 1939 pls := GetPLS(ide) |
| 1973 » » » val, err := pls.GetMeta("id") | 1940 » » » val, ok := pls.GetMeta("id") |
| 1974 » » » So(err, ShouldBeNil) | 1941 » » » So(ok, ShouldBeTrue) |
| 1975 So(val, ShouldEqual, "hello|10") | 1942 So(val, ShouldEqual, "hello|10") |
| 1976 | 1943 |
| 1977 » » » So(pls.SetMeta("id", "sup|1337"), ShouldBeNil) | 1944 » » » So(pls.SetMeta("id", "sup|1337"), ShouldBeTrue) |
| 1978 So(ide.EmbeddedID, ShouldResemble, EmbeddedID{"sup", 133
7}) | 1945 So(ide.EmbeddedID, ShouldResemble, EmbeddedID{"sup", 133
7}) |
| 1979 | 1946 |
| 1980 So(pls.GetAllMeta(), ShouldResembleV, PropertyMap{ | 1947 So(pls.GetAllMeta(), ShouldResembleV, PropertyMap{ |
| 1981 "$id": {mpNI("sup|1337")}, | 1948 "$id": {mpNI("sup|1337")}, |
| 1982 "$kind": {mpNI("IDEmbedder")}, | 1949 "$kind": {mpNI("IDEmbedder")}, |
| 1983 }) | 1950 }) |
| 1984 }) | 1951 }) |
| 1985 }) | 1952 }) |
| 1986 } | 1953 } |
| OLD | NEW |