github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/datastore/revisions/commonrevision_test.go (about) 1 package revisions 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 ) 9 10 var kinds = map[RevisionKind]bool{Timestamp: false, TransactionID: false, HybridLogicalClock: true} 11 12 func TestRevisionEqual(t *testing.T) { 13 tcs := []struct { 14 left string 15 right string 16 isEqual bool 17 }{ 18 { 19 "1", 20 "2", 21 false, 22 }, 23 { 24 "2", 25 "1", 26 false, 27 }, 28 { 29 "1", 30 "1", 31 true, 32 }, 33 { 34 "1.0000000004", 35 "1", 36 false, 37 }, 38 { 39 "1", 40 "1.0000000004", 41 false, 42 }, 43 { 44 "1.0000000004", 45 "1.0000000004", 46 true, 47 }, 48 } 49 50 for _, tc := range tcs { 51 t.Run(tc.left+"-"+tc.right, func(t *testing.T) { 52 for kind, supportsDecimals := range kinds { 53 t.Run(string(kind), func(t *testing.T) { 54 if !supportsDecimals && strings.Contains(tc.left, ".") { 55 return 56 } 57 58 if !supportsDecimals && strings.Contains(tc.right, ".") { 59 return 60 } 61 62 parser := RevisionParser(kind) 63 64 leftRev, err := parser(tc.left) 65 require.NoError(t, err) 66 67 rightRev, err := parser(tc.right) 68 require.NoError(t, err) 69 70 require.Equal(t, tc.isEqual, leftRev.Equal(rightRev)) 71 require.Equal(t, tc.isEqual, rightRev.Equal(leftRev)) 72 }) 73 } 74 }) 75 } 76 } 77 78 func TestRevisionComparison(t *testing.T) { 79 tcs := []struct { 80 left string 81 right string 82 isLeftGreaterThan bool 83 }{ 84 { 85 "1", 86 "2", 87 false, 88 }, 89 { 90 "2", 91 "1", 92 true, 93 }, 94 { 95 "1", 96 "1", 97 false, 98 }, 99 { 100 "1.0000000004", 101 "1", 102 true, 103 }, 104 { 105 "1", 106 "1.0000000004", 107 false, 108 }, 109 { 110 "1.0000000004", 111 "1.0000000004", 112 false, 113 }, 114 } 115 116 for _, tc := range tcs { 117 t.Run(tc.left+"-"+tc.right, func(t *testing.T) { 118 for kind, supportsDecimals := range kinds { 119 t.Run(string(kind), func(t *testing.T) { 120 if !supportsDecimals && strings.Contains(tc.left, ".") { 121 return 122 } 123 124 if !supportsDecimals && strings.Contains(tc.right, ".") { 125 return 126 } 127 128 parser := RevisionParser(kind) 129 130 leftRev, err := parser(tc.left) 131 require.NoError(t, err) 132 133 rightRev, err := parser(tc.right) 134 require.NoError(t, err) 135 136 if leftRev.Equal(rightRev) { 137 require.False(t, tc.isLeftGreaterThan) 138 return 139 } 140 141 require.Equal(t, tc.isLeftGreaterThan, leftRev.GreaterThan(rightRev)) 142 require.Equal(t, !tc.isLeftGreaterThan, !leftRev.GreaterThan(rightRev)) 143 144 require.Equal(t, !tc.isLeftGreaterThan, leftRev.LessThan(rightRev)) 145 require.Equal(t, tc.isLeftGreaterThan, !leftRev.LessThan(rightRev)) 146 }) 147 } 148 }) 149 } 150 } 151 152 func TestRevisionBidirectionalParsing(t *testing.T) { 153 tcs := []string{ 154 "1", "2", "42", "192747564535", "1.0000000004", "1.0000000002", "1.0000000042", "-1235", 155 } 156 157 for _, tc := range tcs { 158 t.Run(tc, func(t *testing.T) { 159 for kind := range kinds { 160 t.Run(string(kind), func(t *testing.T) { 161 parser := RevisionParser(kind) 162 parsed, err := parser(tc) 163 if err != nil { 164 return 165 } 166 167 require.Equal(t, tc, parsed.String()) 168 }) 169 } 170 }) 171 } 172 } 173 174 func TestTimestampRevisionParsing(t *testing.T) { 175 tcs := map[string]bool{ 176 "1": false, 177 "2": false, 178 "42": false, 179 "1257894000000000000": false, 180 "-1": false, 181 "1.0000000004": true, 182 } 183 184 for tc, expectError := range tcs { 185 t.Run(tc, func(t *testing.T) { 186 parser := RevisionParser(Timestamp) 187 parsed, err := parser(tc) 188 if expectError { 189 require.Error(t, err) 190 return 191 } 192 193 require.NoError(t, err) 194 require.Equal(t, tc, parsed.String()) 195 }) 196 } 197 } 198 199 func TestTransactionIDRevisionParsing(t *testing.T) { 200 tcs := map[string]bool{ 201 "1": false, 202 "2": false, 203 "42": false, 204 "1257894000000000000": false, 205 "-1": true, 206 "1.0000000004": true, 207 } 208 209 for tc, expectError := range tcs { 210 t.Run(tc, func(t *testing.T) { 211 parser := RevisionParser(TransactionID) 212 parsed, err := parser(tc) 213 if expectError { 214 require.Error(t, err) 215 return 216 } 217 218 require.NoError(t, err) 219 require.Equal(t, tc, parsed.String()) 220 }) 221 } 222 } 223 224 func TestHLCRevisionParsing(t *testing.T) { 225 tcs := map[string]bool{ 226 "1": false, 227 "2": false, 228 "42": false, 229 "1257894000000000000": false, 230 "-1": false, 231 "1.0000000004": false, 232 "9223372036854775807.0000000004": false, 233 } 234 235 for tc, expectError := range tcs { 236 t.Run(tc, func(t *testing.T) { 237 parser := RevisionParser(HybridLogicalClock) 238 parsed, err := parser(tc) 239 if expectError { 240 require.Error(t, err) 241 return 242 } 243 244 require.NoError(t, err) 245 require.Equal(t, tc, parsed.String()) 246 }) 247 } 248 }