github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/schemadsl/compiler/development_test.go (about) 1 package compiler 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 8 "github.com/authzed/spicedb/pkg/schemadsl/dslshape" 9 "github.com/authzed/spicedb/pkg/schemadsl/input" 10 ) 11 12 func TestPositionToAstNode(t *testing.T) { 13 tcs := []struct { 14 name string 15 schema string 16 line int 17 column int 18 expected []dslshape.NodeType 19 expectedError string 20 }{ 21 { 22 name: "empty schema", 23 schema: "", 24 line: 1, 25 column: 1, 26 expected: nil, 27 expectedError: "unknown line 1 in source file", 28 }, 29 { 30 name: "single def", 31 schema: `definition user {}`, 32 line: 0, 33 column: 0, 34 expected: []dslshape.NodeType{dslshape.NodeTypeDefinition, dslshape.NodeTypeFile}, 35 }, 36 { 37 name: "single def, later on line", 38 schema: `definition user {}`, 39 line: 0, 40 column: 10, 41 expected: []dslshape.NodeType{dslshape.NodeTypeDefinition, dslshape.NodeTypeFile}, 42 }, 43 { 44 name: "relation", 45 schema: `definition resource { 46 relation viewer: user 47 }`, 48 line: 1, 49 column: 10, 50 expected: []dslshape.NodeType{dslshape.NodeTypeRelation, dslshape.NodeTypeDefinition, dslshape.NodeTypeFile}, 51 }, 52 { 53 name: "relation subject type", 54 schema: `definition resource { 55 relation viewer: user 56 }`, 57 line: 1, 58 column: 22, 59 expected: []dslshape.NodeType{ 60 dslshape.NodeTypeSpecificTypeReference, 61 dslshape.NodeTypeTypeReference, 62 dslshape.NodeTypeRelation, 63 dslshape.NodeTypeDefinition, 64 dslshape.NodeTypeFile, 65 }, 66 }, 67 { 68 name: "reference in permission", 69 schema: `definition resource { 70 relation viewer: user 71 permission view = viewer 72 }`, 73 line: 2, 74 column: 26, 75 expected: []dslshape.NodeType{ 76 dslshape.NodeTypeIdentifier, 77 dslshape.NodeTypePermission, 78 dslshape.NodeTypeDefinition, 79 dslshape.NodeTypeFile, 80 }, 81 }, 82 { 83 name: "reference in union permission", 84 schema: `definition resource { 85 relation viewer: user 86 relation editor: user 87 permission view = viewer + editor 88 }`, 89 line: 3, 90 column: 34, 91 expected: []dslshape.NodeType{ 92 dslshape.NodeTypeIdentifier, 93 dslshape.NodeTypeUnionExpression, 94 dslshape.NodeTypePermission, 95 dslshape.NodeTypeDefinition, 96 dslshape.NodeTypeFile, 97 }, 98 }, 99 { 100 name: "reference in caveat expression", 101 schema: ` 102 caveat some_caveat(someparam int) { 103 someparam > 42 104 } 105 106 definition resource { 107 relation viewer: user 108 permission view = viewer 109 }`, 110 line: 2, 111 column: 6, 112 expected: []dslshape.NodeType{ 113 dslshape.NodeTypeCaveatExpression, 114 dslshape.NodeTypeCaveatDefinition, 115 dslshape.NodeTypeFile, 116 }, 117 }, 118 { 119 name: "reference in caveat parameter", 120 schema: ` 121 caveat some_caveat(someparam int) { 122 someparam > 42 123 } 124 125 definition resource { 126 relation viewer: user 127 permission view = viewer 128 }`, 129 line: 1, 130 column: 26, 131 expected: []dslshape.NodeType{ 132 dslshape.NodeTypeCaveatParameter, 133 dslshape.NodeTypeCaveatDefinition, 134 dslshape.NodeTypeFile, 135 }, 136 }, 137 { 138 name: "reference in caveat parameter type", 139 schema: ` 140 caveat some_caveat(someparam int) { 141 someparam > 42 142 } 143 144 definition resource { 145 relation viewer: user 146 permission view = viewer 147 }`, 148 line: 1, 149 column: 33, 150 expected: []dslshape.NodeType{ 151 dslshape.NodeTypeCaveatTypeReference, 152 dslshape.NodeTypeCaveatParameter, 153 dslshape.NodeTypeCaveatDefinition, 154 dslshape.NodeTypeFile, 155 }, 156 }, 157 { 158 name: "reference to caveat", 159 schema: ` 160 caveat some_caveat(someparam int) { 161 someparam > 42 162 } 163 164 definition resource { 165 relation viewer: user with some_caveat 166 permission view = viewer 167 }`, 168 line: 6, 169 column: 40, 170 expected: []dslshape.NodeType{ 171 dslshape.NodeTypeCaveatReference, 172 dslshape.NodeTypeSpecificTypeReference, 173 dslshape.NodeTypeTypeReference, 174 dslshape.NodeTypeRelation, 175 dslshape.NodeTypeDefinition, 176 dslshape.NodeTypeFile, 177 }, 178 }, 179 { 180 name: "multiline doc comment", 181 schema: ` 182 definition user {} 183 184 /** 185 * This is a doc comment 186 */ 187 definition resource { 188 relation viewer: user 189 } 190 `, 191 line: 4, 192 column: 2, 193 expected: []dslshape.NodeType{ 194 dslshape.NodeTypeFile, 195 }, 196 }, 197 { 198 name: "reference to commented", 199 schema: ` 200 definition user {} 201 202 definition resource { 203 // viewer is some sort of relation 204 relation viewer: user 205 } 206 `, 207 line: 5, 208 column: 10, 209 expected: []dslshape.NodeType{ 210 dslshape.NodeTypeRelation, 211 dslshape.NodeTypeDefinition, 212 dslshape.NodeTypeFile, 213 }, 214 }, 215 } 216 217 for _, tc := range tcs { 218 tc := tc 219 t.Run(tc.name, func(t *testing.T) { 220 t.Parallel() 221 222 compiled, err := Compile(InputSchema{ 223 Source: input.Source("test"), 224 SchemaString: tc.schema, 225 }, AllowUnprefixedObjectType()) 226 require.NoError(t, err) 227 228 nodeChain, err := PositionToAstNodeChain(compiled, input.Source("test"), input.Position{ 229 LineNumber: tc.line, 230 ColumnPosition: tc.column, 231 }) 232 if tc.expectedError != "" { 233 require.Error(t, err) 234 require.Contains(t, err.Error(), tc.expectedError) 235 return 236 } 237 238 require.NoError(t, err) 239 240 if tc.expected == nil { 241 require.Nil(t, nodeChain) 242 } else { 243 require.NotNil(t, nodeChain) 244 nodes := nodeChain.nodes 245 246 nodeTypes := make([]dslshape.NodeType, len(nodes)) 247 for idx, node := range nodes { 248 nodeTypes[idx] = node.GetType() 249 } 250 251 require.Equal(t, tc.expected, nodeTypes) 252 } 253 }) 254 } 255 }