|
16 | 16 | package bricksindex |
17 | 17 |
|
18 | 18 | import ( |
| 19 | + "os" |
19 | 20 | "testing" |
20 | 21 |
|
| 22 | + "github.com/arduino/go-paths-helper" |
21 | 23 | yaml "github.com/goccy/go-yaml" |
22 | 24 | "github.com/stretchr/testify/require" |
23 | 25 | ) |
@@ -184,3 +186,155 @@ func TestBricksIndex(t *testing.T) { |
184 | 186 | require.False(t, b.Variables[0].IsRequired()) |
185 | 187 | require.False(t, b.Variables[1].IsRequired()) |
186 | 188 | } |
| 189 | + |
| 190 | +func TestBricksIndexYAMLFormats(t *testing.T) { |
| 191 | + testCases := []struct { |
| 192 | + name string |
| 193 | + yamlContent string |
| 194 | + expectedError string |
| 195 | + expectedBricks []Brick |
| 196 | + }{ |
| 197 | + { |
| 198 | + // TODO: the validator of the brick-list must not allow this |
| 199 | + name: "missing bricks field does not cuase error", |
| 200 | + yamlContent: `other_field: value`, |
| 201 | + expectedBricks: nil, |
| 202 | + }, |
| 203 | + { |
| 204 | + name: "bad YAML format - invalid indentation", |
| 205 | + yamlContent: `bricks: |
| 206 | + - id: arduino:test_brick |
| 207 | + name: Test Brick |
| 208 | + description: A test brick`, |
| 209 | + expectedError: "found character '\t' that cannot start any token", |
| 210 | + }, |
| 211 | + { |
| 212 | + name: "empty bricks", |
| 213 | + yamlContent: `bricks: []`, |
| 214 | + expectedBricks: []Brick{}, |
| 215 | + }, |
| 216 | + { |
| 217 | + name: "bad YAML format - unclosed quotes", |
| 218 | + yamlContent: `bricks: |
| 219 | +- id: "arduino:test_brick |
| 220 | + name: Test Brick |
| 221 | + description: A test brick`, |
| 222 | + expectedError: "could not find end character of double-quoted text", |
| 223 | + }, |
| 224 | + { |
| 225 | + name: "bad YAML format - missing colon", |
| 226 | + yamlContent: `bricks: |
| 227 | +- id arduino:test_brick |
| 228 | + name: Test Brick`, |
| 229 | + expectedError: "unexpected key name", |
| 230 | + }, |
| 231 | + { |
| 232 | + name: "bad YAML format - invalid syntax", |
| 233 | + yamlContent: `bricks: |
| 234 | +- id: arduino:test_brick |
| 235 | + name: Test Brick |
| 236 | + description: A test brick |
| 237 | + ports: [7000,`, |
| 238 | + expectedError: "sequence end token ']' not found", |
| 239 | + }, |
| 240 | + { |
| 241 | + name: "bad YAML format - tab characters", |
| 242 | + yamlContent: "bricks:\n\t- id: arduino:test_brick\n\t name: Test Brick", |
| 243 | + expectedError: "found character '\t' that cannot start any token", |
| 244 | + }, |
| 245 | + { |
| 246 | + name: "simple brick", |
| 247 | + yamlContent: `bricks: |
| 248 | +- id: arduino:simple_brick |
| 249 | + name: Test Brick |
| 250 | + description: A test brick |
| 251 | +`, |
| 252 | + expectedBricks: []Brick{ |
| 253 | + { |
| 254 | + ID: "arduino:simple_brick", |
| 255 | + Name: "Test Brick", |
| 256 | + Description: "A test brick", |
| 257 | + Category: "", |
| 258 | + RequiresDisplay: "", |
| 259 | + RequireContainer: false, |
| 260 | + RequireModel: false, |
| 261 | + RequiredDevices: nil, |
| 262 | + Variables: nil, |
| 263 | + Ports: nil, |
| 264 | + ModelName: "", |
| 265 | + MountDevicesIntoContainer: false, |
| 266 | + }, |
| 267 | + }, |
| 268 | + }, |
| 269 | + { |
| 270 | + name: "valid YAML with complex variables", |
| 271 | + yamlContent: `bricks: |
| 272 | +- id: arduino:complex_brick |
| 273 | + name: Complex Brick |
| 274 | + description: A complex test brick |
| 275 | + category: storage |
| 276 | + require_container: true |
| 277 | + require_model: true |
| 278 | + require_devices: false |
| 279 | + mount_devices_into_container: true |
| 280 | + model_name: a-complex-model |
| 281 | + required_devices: |
| 282 | + - camera |
| 283 | + ports: |
| 284 | + - 7000 |
| 285 | + - 8080 |
| 286 | + variables: |
| 287 | + - name: REQUIRED_VAR |
| 288 | + default_value: "" |
| 289 | + description: A required variable |
| 290 | + - name: OPTIONAL_VAR |
| 291 | + default_value: "default_value" |
| 292 | + description: An optional variable`, |
| 293 | + expectedBricks: []Brick{ |
| 294 | + { |
| 295 | + ID: "arduino:complex_brick", |
| 296 | + Name: "Complex Brick", |
| 297 | + Description: "A complex test brick", |
| 298 | + Category: "storage", |
| 299 | + RequiresDisplay: "", |
| 300 | + RequireContainer: true, |
| 301 | + RequireModel: true, |
| 302 | + RequiredDevices: []string{"camera"}, |
| 303 | + MountDevicesIntoContainer: true, |
| 304 | + Variables: []BrickVariable{ |
| 305 | + { |
| 306 | + Name: "REQUIRED_VAR", |
| 307 | + DefaultValue: "", |
| 308 | + Description: "A required variable", |
| 309 | + }, |
| 310 | + { |
| 311 | + Name: "OPTIONAL_VAR", |
| 312 | + DefaultValue: "default_value", |
| 313 | + Description: "An optional variable", |
| 314 | + }, |
| 315 | + }, |
| 316 | + Ports: []string{"7000", "8080"}, |
| 317 | + ModelName: "a-complex-model", |
| 318 | + }, |
| 319 | + }, |
| 320 | + }, |
| 321 | + } |
| 322 | + |
| 323 | + for _, tc := range testCases { |
| 324 | + t.Run(tc.name, func(t *testing.T) { |
| 325 | + tempDir := t.TempDir() |
| 326 | + brickIndex := paths.New(tempDir, "bricks-list.yaml") |
| 327 | + err := os.WriteFile(brickIndex.String(), []byte(tc.yamlContent), 0600) |
| 328 | + require.NoError(t, err) |
| 329 | + |
| 330 | + index, err := GenerateBricksIndexFromFile(paths.New(tempDir)) |
| 331 | + if tc.expectedError != "" { |
| 332 | + require.Error(t, err) |
| 333 | + require.Contains(t, err.Error(), tc.expectedError) |
| 334 | + } else { |
| 335 | + require.NoError(t, err) |
| 336 | + require.Equal(t, index.Bricks, tc.expectedBricks, "bricsk mistmatch") |
| 337 | + } |
| 338 | + }) |
| 339 | + } |
| 340 | +} |
0 commit comments