Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: service/datastore/pls_test.go

Issue 1667403003: Add support for uint8, uint16 and uint32 in luci/gae (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: allow negative Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « service/datastore/pls_impl.go ('k') | service/datastore/properties.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 Other string 147 Other string
148 } 148 }
149 149
150 type N2 struct { 150 type N2 struct {
151 N1 `gae:"red"` 151 N1 `gae:"red"`
152 Green N1 `gae:"green"` 152 Green N1 `gae:"green"`
153 Blue N1 153 Blue N1
154 White N1 `gae:"-"` 154 White N1 `gae:"-"`
155 } 155 }
156 156
157 type N3 struct {
158 ID uint32 `gae:"$id,200"`
159 }
160
157 type O0 struct { 161 type O0 struct {
158 I int64 162 I int64
159 } 163 }
160 164
161 type O1 struct { 165 type O1 struct {
162 I int32 166 I int32
163 } 167 }
164 168
165 type U0 struct { 169 type U0 struct {
166 » U uint 170 » U uint32
167 } 171 }
168 172
169 type U1 struct { 173 type U1 struct {
170 » U string 174 » U byte
175 }
176
177 type U2 struct {
178 » U int64
171 } 179 }
172 180
173 type T struct { 181 type T struct {
174 T time.Time 182 T time.Time
175 } 183 }
176 184
177 type X0 struct { 185 type X0 struct {
178 S string 186 S string
179 I int 187 I int
180 i int 188 i int
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 src: &K1{[]*Key{testKey1a, nil, testKey2a}}, 776 src: &K1{[]*Key{testKey1a, nil, testKey2a}},
769 want: &K1{[]*Key{testKey1b, nil, testKey2b}}, 777 want: &K1{[]*Key{testKey1b, nil, testKey2b}},
770 }, 778 },
771 { 779 {
772 desc: "overflow", 780 desc: "overflow",
773 src: &O0{I: 1 << 48}, 781 src: &O0{I: 1 << 48},
774 want: &O1{}, 782 want: &O1{},
775 loadErr: "overflow", 783 loadErr: "overflow",
776 }, 784 },
777 { 785 {
786 desc: "underflow",
787 src: &O0{I: math.MaxInt64},
788 want: &O1{},
789 loadErr: "overflow",
790 },
791 {
778 desc: "time", 792 desc: "time",
779 src: &T{T: time.Unix(1e9, 0).UTC()}, 793 src: &T{T: time.Unix(1e9, 0).UTC()},
780 want: &T{T: time.Unix(1e9, 0).UTC()}, 794 want: &T{T: time.Unix(1e9, 0).UTC()},
781 }, 795 },
782 { 796 {
783 desc: "time as props", 797 desc: "time as props",
784 src: &T{T: time.Unix(1e9, 0).UTC()}, 798 src: &T{T: time.Unix(1e9, 0).UTC()},
785 want: PropertyMap{ 799 want: PropertyMap{
786 "T": {mp(time.Unix(1e9, 0).UTC())}, 800 "T": {mp(time.Unix(1e9, 0).UTC())},
787 }, 801 },
788 }, 802 },
789 { 803 {
790 » » desc: "uint save", 804 » » desc: "uint32 save",
791 » » src: &U0{U: 1}, 805 » » src: &U0{U: 1},
792 » » plsErr: `field "U" has invalid type: uint`, 806 » » want: PropertyMap{
807 » » » "U": {mp(1)},
808 » » },
793 }, 809 },
794 { 810 {
795 » » desc: "uint load", 811 » » desc: "uint32 load",
796 » » src: &U1{U: "not a uint"}, 812 » » src: &U2{U: 100},
797 » » want: &U0{}, 813 » » want: &U0{U: 100},
798 » » plsLoadErr: `field "U" has invalid type: uint`, 814 » },
815 » {
816 » » desc: "uint32 load oob (neg)",
817 » » src: &U2{U: -1},
818 » » want: &U0{},
819 » » loadErr: "overflow",
820 » },
821 » {
822 » » desc: "uint32 load oob (huge)",
823 » » src: &U2{U: math.MaxInt64},
824 » » want: &U0{},
825 » » loadErr: "overflow",
826 » },
827 » {
828 » » desc: "byte save",
829 » » src: &U1{U: 1},
830 » » want: PropertyMap{
831 » » » "U": {mp(1)},
832 » » },
833 » },
834 » {
835 » » desc: "byte load",
836 » » src: &U2{U: 100},
837 » » want: &U1{U: 100},
838 » },
839 » {
840 » » desc: "byte load oob (neg)",
841 » » src: &U2{U: -1},
842 » » want: &U1{},
843 » » loadErr: "overflow",
844 » },
845 » {
846 » » desc: "byte load oob (huge)",
847 » » src: &U2{U: math.MaxInt64},
848 » » want: &U1{},
849 » » loadErr: "overflow",
799 }, 850 },
800 { 851 {
801 desc: "zero", 852 desc: "zero",
802 src: &X0{}, 853 src: &X0{},
803 want: &X0{}, 854 want: &X0{},
804 }, 855 },
805 { 856 {
806 desc: "basic", 857 desc: "basic",
807 src: &X0{S: "one", I: 2, i: 3}, 858 src: &X0{S: "one", I: 2, i: 3},
808 want: &X0{S: "one", I: 2}, 859 want: &X0{S: "one", I: 2},
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 desc: "json.RawMessage to myBlob", 1645 desc: "json.RawMessage to myBlob",
1595 src: &struct { 1646 src: &struct {
1596 B json.RawMessage 1647 B json.RawMessage
1597 }{ 1648 }{
1598 B: json.RawMessage("rawr"), 1649 B: json.RawMessage("rawr"),
1599 }, 1650 },
1600 want: &B2{B: myBlob("rawr")}, 1651 want: &B2{B: myBlob("rawr")},
1601 }, 1652 },
1602 } 1653 }
1603 1654
1604 // checkErr returns the empty string if either both want and err are zero,
1605 // or if want is a non-empty substring of err's string representation.
1606 func checkErr(want string, err error) string {
1607 if err != nil {
1608 got := err.Error()
1609 if want == "" || strings.Index(got, want) == -1 {
1610 return got
1611 }
1612 } else if want != "" {
1613 return fmt.Sprintf("want error %q", want)
1614 }
1615 return ""
1616 }
1617
1618 func TestRoundTrip(t *testing.T) { 1655 func TestRoundTrip(t *testing.T) {
1619 t.Parallel() 1656 t.Parallel()
1620 1657
1621 checkErr := func(actual interface{}, expected string) bool {
1622 if expected == "" {
1623 So(actual, ShouldErrLike, nil)
1624 } else {
1625 So(actual, ShouldErrLike, expected)
1626 }
1627 return expected != ""
1628 }
1629
1630 getPLSErr := func(obj interface{}) (pls PropertyLoadSaver, err error) { 1658 getPLSErr := func(obj interface{}) (pls PropertyLoadSaver, err error) {
1631 defer func() { 1659 defer func() {
1632 if v := recover(); v != nil { 1660 if v := recover(); v != nil {
1633 err = v.(error) 1661 err = v.(error)
1634 } 1662 }
1635 }() 1663 }()
1636 pls = GetPLS(obj) 1664 pls = GetPLS(obj)
1637 return 1665 return
1638 } 1666 }
1639 1667
1640 Convey("Test round-trip", t, func() { 1668 Convey("Test round-trip", t, func() {
1641 for _, tc := range testCases { 1669 for _, tc := range testCases {
1642 tc := tc 1670 tc := tc
1643 Convey(tc.desc, func() { 1671 Convey(tc.desc, func() {
1644 pls, ok := tc.src.(PropertyLoadSaver) 1672 pls, ok := tc.src.(PropertyLoadSaver)
1645 if !ok { 1673 if !ok {
1646 var err error 1674 var err error
1647 pls, err = getPLSErr(tc.src) 1675 pls, err = getPLSErr(tc.src)
1648 » » » » » if checkErr(err, tc.plsErr) { 1676 » » » » » if tc.plsErr != "" {
1677 » » » » » » So(err, ShouldErrLike, tc.plsErr )
1649 return 1678 return
1650 } 1679 }
1651 } 1680 }
1652 So(pls, ShouldNotBeNil) 1681 So(pls, ShouldNotBeNil)
1653 1682
1654 savedProps, err := pls.Save(false) 1683 savedProps, err := pls.Save(false)
1655 » » » » if checkErr(err, tc.saveErr) { 1684 » » » » if tc.saveErr != "" {
1685 » » » » » So(err, ShouldErrLike, tc.saveErr)
1656 return 1686 return
1657 } 1687 }
1658 So(savedProps, ShouldNotBeNil) 1688 So(savedProps, ShouldNotBeNil)
1659 1689
1660 var got interface{} 1690 var got interface{}
1661 if _, ok := tc.want.(PropertyMap); ok { 1691 if _, ok := tc.want.(PropertyMap); ok {
1662 pls = PropertyMap{} 1692 pls = PropertyMap{}
1663 got = pls 1693 got = pls
1664 } else { 1694 } else {
1665 got = reflect.New(reflect.TypeOf(tc.want ).Elem()).Interface() 1695 got = reflect.New(reflect.TypeOf(tc.want ).Elem()).Interface()
1666 if pls, ok = got.(PropertyLoadSaver); !o k { 1696 if pls, ok = got.(PropertyLoadSaver); !o k {
1667 var err error 1697 var err error
1668 pls, err = getPLSErr(got) 1698 pls, err = getPLSErr(got)
1669 » » » » » » if checkErr(err, tc.plsLoadErr) { 1699 » » » » » » if tc.plsLoadErr != "" {
1700 » » » » » » » So(err, ShouldErrLike, t c.plsLoadErr)
1670 return 1701 return
1671 } 1702 }
1672 } 1703 }
1673 } 1704 }
1674 1705
1675 So(pls, ShouldNotBeNil) 1706 So(pls, ShouldNotBeNil)
1676 1707
1677 err = pls.Load(savedProps) 1708 err = pls.Load(savedProps)
1678 » » » » if checkErr(err, tc.loadErr) { 1709 » » » » if tc.loadErr != "" {
1710 » » » » » So(err, ShouldErrLike, tc.loadErr)
1679 return 1711 return
1680 } 1712 }
1681 if tc.want == nil { 1713 if tc.want == nil {
1682 return 1714 return
1683 } 1715 }
1684 1716
1685 if gotT, ok := got.(*T); ok { 1717 if gotT, ok := got.(*T); ok {
1686 // Round tripping a time.Time can result in a different time.Location: Local instead of UTC. 1718 // Round tripping a time.Time can result in a different time.Location: Local instead of UTC.
1687 // We therefore test equality explicitly , instead of relying on reflect.DeepEqual. 1719 // We therefore test equality explicitly , instead of relying on reflect.DeepEqual.
1688 So(gotT.T.Equal(tc.want.(*T).T), ShouldB eTrue) 1720 So(gotT.T.Equal(tc.want.(*T).T), ShouldB eTrue)
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 So(mgs.SetMeta("id", int64(200)), ShouldBeTrue) 1770 So(mgs.SetMeta("id", int64(200)), ShouldBeTrue)
1739 So(o.ID, ShouldEqual, 200) 1771 So(o.ID, ShouldEqual, 200)
1740 }) 1772 })
1741 1773
1742 Convey("assigning to unsassiagnable fields returns !ok", func() { 1774 Convey("assigning to unsassiagnable fields returns !ok", func() {
1743 o := &N0{ID: 100} 1775 o := &N0{ID: 100}
1744 mgs := getMGS(o) 1776 mgs := getMGS(o)
1745 So(mgs.SetMeta("kind", "hi"), ShouldBeFalse) 1777 So(mgs.SetMeta("kind", "hi"), ShouldBeFalse)
1746 So(mgs.SetMeta("noob", "hi"), ShouldBeFalse) 1778 So(mgs.SetMeta("noob", "hi"), ShouldBeFalse)
1747 }) 1779 })
1780
1781 Convey("unsigned int meta fields work", func() {
1782 o := &N3{}
1783 mgs := getMGS(o)
1784 v, ok := mgs.GetMeta("id")
1785 So(v, ShouldEqual, int64(200))
1786 So(ok, ShouldBeTrue)
1787
1788 So(mgs.SetMeta("id", 20), ShouldBeTrue)
1789 So(o.ID, ShouldEqual, 20)
1790
1791 So(mgs.SetMeta("id", math.MaxInt64), ShouldBeFalse)
1792 So(o.ID, ShouldEqual, 20)
1793
1794 So(mgs.SetMeta("id", math.MaxUint32), ShouldBeTrue)
1795 So(o.ID, ShouldEqual, math.MaxUint32)
1796 })
1748 }) 1797 })
1749 1798
1750 Convey("StructPLS Miscellaneous", t, func() { 1799 Convey("StructPLS Miscellaneous", t, func() {
1751 Convey("a simple struct has a default $kind", func() { 1800 Convey("a simple struct has a default $kind", func() {
1752 So(GetPLS(&Simple{}).GetAllMeta(), ShouldResemble, Prope rtyMap{ 1801 So(GetPLS(&Simple{}).GetAllMeta(), ShouldResemble, Prope rtyMap{
1753 "$kind": []Property{mpNI("Simple")}, 1802 "$kind": []Property{mpNI("Simple")},
1754 }) 1803 })
1755 }) 1804 })
1756 1805
1757 Convey("multiple overlapping fields is an error", func() { 1806 Convey("multiple overlapping fields is an error", func() {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1855 v, ok := mgs.GetMeta("val") 1904 v, ok := mgs.GetMeta("val")
1856 So(ok, ShouldBeTrue) 1905 So(ok, ShouldBeTrue)
1857 So(v, ShouldEqual, int64(100)) 1906 So(v, ShouldEqual, int64(100))
1858 1907
1859 o.Val = 10 1908 o.Val = 10
1860 v, ok = mgs.GetMeta("val") 1909 v, ok = mgs.GetMeta("val")
1861 So(ok, ShouldBeTrue) 1910 So(ok, ShouldBeTrue)
1862 So(v, ShouldEqual, int64(10)) 1911 So(v, ShouldEqual, int64(10))
1863 }) 1912 })
1864 1913
1914 Convey("underflow", func() {
1915 type UnderflowMeta struct {
1916 ID int16 `gae:"$id"`
1917 }
1918 um := &UnderflowMeta{}
1919 mgs := getMGS(um)
1920 So(mgs.SetMeta("id", -20), ShouldBeTrue)
1921 So(mgs.SetMeta("id", math.MinInt64), ShouldBeFalse)
1922 })
1923
1924 Convey("negative default", func() {
1925 type UnderflowMeta struct {
1926 ID int16 `gae:"$id,-30"`
1927 }
1928 um := &UnderflowMeta{}
1929 mgs := getMGS(um)
1930 val, ok := mgs.GetMeta("id")
1931 So(ok, ShouldBeTrue)
1932 So(val, ShouldEqual, -30)
1933 })
1934
1865 Convey("Derived metadata fields", func() { 1935 Convey("Derived metadata fields", func() {
1866 type DerivedString string 1936 type DerivedString string
1867 type DerivedInt int16 1937 type DerivedInt int16
1868 type DerivedStruct struct { 1938 type DerivedStruct struct {
1869 ID DerivedString `gae:"$id"` 1939 ID DerivedString `gae:"$id"`
1870 Foo DerivedInt `gae:"$foo"` 1940 Foo DerivedInt `gae:"$foo"`
1871 } 1941 }
1872 o := &DerivedStruct{"hello", 10} 1942 o := &DerivedStruct{"hello", 10}
1873 mgs := getMGS(o) 1943 mgs := getMGS(o)
1874 v, ok := mgs.GetMeta("id") 1944 v, ok := mgs.GetMeta("id")
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1953 So(pls.SetMeta("id", "sup|1337"), ShouldBeTrue) 2023 So(pls.SetMeta("id", "sup|1337"), ShouldBeTrue)
1954 So(ide.EmbeddedID, ShouldResemble, EmbeddedID{"sup", 133 7}) 2024 So(ide.EmbeddedID, ShouldResemble, EmbeddedID{"sup", 133 7})
1955 2025
1956 So(pls.GetAllMeta(), ShouldResembleV, PropertyMap{ 2026 So(pls.GetAllMeta(), ShouldResembleV, PropertyMap{
1957 "$id": {mpNI("sup|1337")}, 2027 "$id": {mpNI("sup|1337")},
1958 "$kind": {mpNI("IDEmbedder")}, 2028 "$kind": {mpNI("IDEmbedder")},
1959 }) 2029 })
1960 }) 2030 })
1961 }) 2031 })
1962 } 2032 }
OLDNEW
« no previous file with comments | « service/datastore/pls_impl.go ('k') | service/datastore/properties.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698