# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # Array Comprehension Test Suite # Tests array comprehensions - collect transformed values based on conditions # Corresponds to Rego's "[transform | condition]" patterns cases: - note: array_simple_transform description: Simple array comprehension with transformation example_rego: | # Transform array elements by doubling them [x * 2 | x := [1, 2, 3][_]] # [2, 4, 6] literals: - 1 - 2 - 3 - 2 # multiplier instruction_params: comprehension_begin_params: - mode: "Array" collection_reg: 7 key_reg: 4 value_reg: 5 body_start: 8 comprehension_end: 11 loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 8 body_start: 9 loop_end: 12 instructions: - "ArrayNew { dest: 0 }" # Create input array [1, 2, 3] in register 0 - "Load { dest: 1, literal_idx: 0 }" # Load 1 into register 1 - "ArrayPush { arr: 0, value: 1 }" # Push 1 to array - "Load { dest: 2, literal_idx: 1 }" # Load 2 into register 2 - "ArrayPush { arr: 0, value: 2 }" # Push 2 to array - "Load { dest: 3, literal_idx: 2 }" # Load 3 into register 3 - "ArrayPush { arr: 0, value: 3 }" # Push 3 to array - "ComprehensionBegin { params_index: 0 }" # Start array comprehension and initialize result in register 7 - "LoopStart { params_index: 0 }" # Start loop over array elements - "Load { dest: 6, literal_idx: 3 }" # Load multiplier 2 into register 6 - "Mul { dest: 9, left: 5, right: 6 }" # Multiply current value by 2, store result in register 9 - "ComprehensionYield { value_reg: 9 }" # Add transformed value to comprehension - "LoopNext { body_start: 9, loop_end: 12 }" # Continue to next iteration or exit - "Return { value: 7 }" # Return comprehension collection want_result: [2, 4, 6] - note: array_empty_input description: Array comprehension with empty input example_rego: | # Transform empty array [x + 5 | x := [][_]] # [] (empty array) literals: - 5 # addend instruction_params: comprehension_begin_params: - mode: "Array" collection_reg: 7 key_reg: 4 value_reg: 5 body_start: 2 comprehension_end: 6 loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 8 body_start: 3 loop_end: 6 instructions: - "ArrayNew { dest: 0 }" # Create empty input array in register 0 - "ComprehensionBegin { params_index: 0 }" # Start array comprehension and initialize result in register 7 - "LoopStart { params_index: 0 }" # Start loop over array elements - "Load { dest: 6, literal_idx: 0 }" # Load addend 5 into register 6 - "Add { dest: 8, left: 5, right: 6 }" # Add 5 to current value, store result in register 8 - "ComprehensionYield { value_reg: 8 }" # Add transformed value to comprehension - "LoopNext { body_start: 3, loop_end: 6 }" # Continue to next iteration or exit - "Return { value: 7 }" # Return comprehension collection want_result: [] - note: array_single_element description: Array comprehension with single element example_rego: | # Transform single element array [x - 1 | x := [10][_]] # [9] literals: - 10 - 1 # subtrahend instruction_params: comprehension_begin_params: - mode: "Array" collection_reg: 7 key_reg: 4 value_reg: 5 body_start: 4 comprehension_end: 8 loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 8 body_start: 5 loop_end: 8 instructions: - "ArrayNew { dest: 0 }" # Create input array [10] in register 0 - "Load { dest: 1, literal_idx: 0 }" # Load 10 into register 1 - "ArrayPush { arr: 0, value: 1 }" # Push 10 to array - "ComprehensionBegin { params_index: 0 }" # Start array comprehension and initialize result in register 7 - "LoopStart { params_index: 0 }" # Start loop over array elements - "Load { dest: 6, literal_idx: 1 }" # Load subtrahend 1 into register 6 - "Sub { dest: 9, left: 5, right: 6 }" # Subtract 1 from current value, store result in register 9 - "ComprehensionYield { value_reg: 9 }" # Add transformed value to comprehension - "LoopNext { body_start: 5, loop_end: 8 }" # Continue to next iteration or exit - "Return { value: 7 }" # Return comprehension collection want_result: [9] - note: array_with_null_values description: Array comprehension with null value handling example_rego: | # Process array with null values - nulls are preserved [x | x := [1, null, 3][_]] # [1, null, 3] literals: - 1 - 3 instruction_params: comprehension_begin_params: - mode: "Array" collection_reg: 7 key_reg: 4 value_reg: 5 body_start: 8 comprehension_end: 11 loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 8 body_start: 9 loop_end: 11 instructions: - "ArrayNew { dest: 0 }" # Create input array in register 0 - "Load { dest: 1, literal_idx: 0 }" # Load 1 - "ArrayPush { arr: 0, value: 1 }" # Push 1 to array - "LoadNull { dest: 2 }" # Load null value - "ArrayPush { arr: 0, value: 2 }" # Push null to array - "Load { dest: 3, literal_idx: 1 }" # Load 3 - "ArrayPush { arr: 0, value: 3 }" # Push 3 to array - "ComprehensionBegin { params_index: 0 }" # Start array comprehension and initialize result in register 7 - "LoopStart { params_index: 0 }" # Start loop over array elements - "ComprehensionYield { value_reg: 5 }" # Add current value (including null) to comprehension - "LoopNext { body_start: 9, loop_end: 11 }" # Continue to next iteration or exit - "Return { value: 7 }" # Return comprehension collection want_result: [1, null, 3]