# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # Object Comprehension Test Suite # Tests object comprehensions - construct objects with key-value pairs based on conditions # Corresponds to Rego's "{key: value | condition}" patterns cases: - note: object_simple_key_value description: Simple object comprehension with computed values example_rego: | # Create object mapping each value to its double {x: x * 2 | x := [1, 2, 3][_]} # {1: 2, 2: 4, 3: 6} literals: - {} - 1 - 2 - 3 - 2 # multiplier instruction_params: object_create_params: - dest: 9 template_literal_idx: 0 literal_key_fields: [] fields: [] comprehension_begin_params: - mode: "Object" collection_reg: 9 result_reg: 9 key_reg: 4 value_reg: 5 body_start: 10 comprehension_end: 13 loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 10 body_start: 10 loop_end: 14 instructions: - "ArrayNew { dest: 0 }" # Index 0: Create input array [1, 2, 3] - "Load { dest: 1, literal_idx: 1 }" # Index 1: Load 1 - "ArrayPush { arr: 0, value: 1 }" # Index 2 - "Load { dest: 2, literal_idx: 2 }" # Index 3: Load 2 - "ArrayPush { arr: 0, value: 2 }" # Index 4 - "Load { dest: 3, literal_idx: 3 }" # Index 5: Load 3 - "ArrayPush { arr: 0, value: 3 }" # Index 6 - "ObjectCreate { params_index: 0 }" # Index 7: Create empty result object in r9 - "ComprehensionBegin { params_index: 0 }" # Index 8: Start object comprehension - "LoopStart { params_index: 0 }" # Index 9: Start loop - "Load { dest: 11, literal_idx: 4 }" # Index 10: Load multiplier 2 - "Mul { dest: 12, left: 5, right: 11 }" # Index 11: Multiply value by 2 - "ComprehensionYield { value_reg: 12, key_reg: 5 }" # Index 12: Add key-value pair - "LoopNext { body_start: 10, loop_end: 14 }" # Index 13: Continue loop - "Return { value: 9 }" # Index 14: Return result object want_result: {1: 2, 2: 4, 3: 6} - note: object_empty_input description: Object comprehension with empty input example_rego: | # Create object from empty array {x: x + 5 | x := [][_]} # {} (empty object) literals: - {} - 5 # addend instruction_params: object_create_params: - dest: 9 template_literal_idx: 0 literal_key_fields: [] fields: [] comprehension_begin_params: - mode: "Object" collection_reg: 9 result_reg: 9 key_reg: 4 value_reg: 5 body_start: 4 comprehension_end: 7 loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 10 body_start: 4 loop_end: 8 instructions: - "ArrayNew { dest: 0 }" # Index 0: Create empty input array - "ObjectCreate { params_index: 0 }" # Index 1: Create empty result object in r9 - "ComprehensionBegin { params_index: 0 }" # Index 2: Start object comprehension - "LoopStart { params_index: 0 }" # Index 3: Start loop - "Load { dest: 10, literal_idx: 1 }" # Index 4: Load addend 5 - "Add { dest: 11, left: 5, right: 10 }" # Index 5: Add 5 to value - "ComprehensionYield { value_reg: 11, key_reg: 5 }" # Index 6: Add key-value pair - "LoopNext { body_start: 4, loop_end: 8 }" # Index 7: Continue loop - "Return { value: 9 }" # Index 8: Return result object want_result: {} - note: object_single_element description: Object comprehension with single element example_rego: | # Create object with single key-value pair {x: x - 1 | x := [5][_]} # {5: 4} literals: - {} - 5 - 1 # subtrahend instruction_params: object_create_params: - dest: 9 template_literal_idx: 0 literal_key_fields: [] fields: [] comprehension_begin_params: - mode: "Object" collection_reg: 9 result_reg: 9 key_reg: 4 value_reg: 5 body_start: 6 comprehension_end: 9 loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 10 body_start: 6 loop_end: 10 instructions: - "ArrayNew { dest: 0 }" # Index 0: Create input array [5] - "Load { dest: 1, literal_idx: 1 }" # Index 1: Load 5 - "ArrayPush { arr: 0, value: 1 }" # Index 2: Push 5 to array - "ObjectCreate { params_index: 0 }" # Index 3: Create empty result object in r9 - "ComprehensionBegin { params_index: 0 }" # Index 4: Start object comprehension - "LoopStart { params_index: 0 }" # Index 5: Start loop - "Load { dest: 10, literal_idx: 2 }" # Index 6: Load subtrahend 1 - "Sub { dest: 11, left: 5, right: 10 }" # Index 7: Subtract 1 from value - "ComprehensionYield { value_reg: 11, key_reg: 5 }" # Index 8: Add key-value pair - "LoopNext { body_start: 6, loop_end: 10 }" # Index 9: Continue loop - "Return { value: 9 }" # Index 10: Return result object want_result: {5: 4} - note: object_with_null_keys description: Object comprehension with null keys and values example_rego: | # Create object with null keys/values {x: x | x := [1, null, 2][_]} # {1: 1, null: null, 2: 2} literals: - {} - 1 - 2 instruction_params: object_create_params: - dest: 9 template_literal_idx: 0 literal_key_fields: [] fields: [] comprehension_begin_params: - mode: "Object" collection_reg: 9 result_reg: 9 key_reg: 4 value_reg: 5 body_start: 10 comprehension_end: 11 loop_params: - mode: "ForEach" collection: 0 key_reg: 4 value_reg: 5 result_reg: 10 body_start: 10 loop_end: 12 instructions: - "ArrayNew { dest: 0 }" # Index 0: Create input array - "Load { dest: 1, literal_idx: 1 }" # Index 1: Load 1 - "ArrayPush { arr: 0, value: 1 }" # Index 2: Push 1 to array - "LoadNull { dest: 2 }" # Index 3: Load null value - "ArrayPush { arr: 0, value: 2 }" # Index 4: Push null to array - "Load { dest: 3, literal_idx: 2 }" # Index 5: Load 2 - "ArrayPush { arr: 0, value: 3 }" # Index 6: Push 2 to array - "ObjectCreate { params_index: 0 }" # Index 7: Create empty result object in r9 - "ComprehensionBegin { params_index: 0 }" # Index 8: Start object comprehension - "LoopStart { params_index: 0 }" # Index 9: Start loop - "ComprehensionYield { value_reg: 5, key_reg: 5 }" # Index 10: Use value as both key and value - "LoopNext { body_start: 10, loop_end: 12 }" # Index 11: Continue loop - "Return { value: 9 }" # Index 12: Return result object want_result: {1: 1, null: null, 2: 2}