1// Copyright (C) 2023 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import {convertArgsToObject, convertArgsToTree} from './args_parser'; 16 17const args = [ 18 {key: 'simple_key', value: 'simple_value'}, 19 {key: 'thing.key', value: 'value'}, 20 {key: 'thing.point[0].x', value: 10}, 21 {key: 'thing.point[0].y', value: 20}, 22 {key: 'thing.point[1].x', value: 0}, 23 {key: 'thing.point[1].y', value: -10}, 24 {key: 'foo.bar.foo.bar', value: 'baz'}, 25]; 26 27describe('convertArgsToTree', () => { 28 test('converts example arg set', () => { 29 expect(convertArgsToTree(args)).toEqual([ 30 { 31 key: 'simple_key', 32 value: {key: 'simple_key', value: 'simple_value'}, 33 }, 34 { 35 key: 'thing', 36 children: [ 37 {key: 'key', value: {key: 'thing.key', value: 'value'}}, 38 { 39 key: 'point', 40 children: [ 41 { 42 key: 0, 43 children: [ 44 { 45 key: 'x', 46 value: {key: 'thing.point[0].x', value: 10}, 47 }, 48 { 49 key: 'y', 50 value: {key: 'thing.point[0].y', value: 20}, 51 }, 52 ], 53 }, 54 { 55 key: 1, 56 children: [ 57 { 58 key: 'x', 59 value: {key: 'thing.point[1].x', value: 0}, 60 }, 61 { 62 key: 'y', 63 value: {key: 'thing.point[1].y', value: -10}, 64 }, 65 ], 66 }, 67 ], 68 }, 69 ], 70 }, 71 { 72 key: 'foo', 73 children: [ 74 { 75 key: 'bar', 76 children: [ 77 { 78 key: 'foo', 79 children: [ 80 { 81 key: 'bar', 82 value: {key: 'foo.bar.foo.bar', value: 'baz'}, 83 }, 84 ], 85 }, 86 ], 87 }, 88 ], 89 }, 90 ]); 91 }); 92 93 test('handles value and children in same node', () => { 94 const args = [ 95 {key: 'foo', value: 'foo'}, 96 {key: 'foo.bar', value: 'bar'}, 97 ]; 98 expect(convertArgsToTree(args)).toEqual([ 99 { 100 key: 'foo', 101 value: {key: 'foo', value: 'foo'}, 102 children: [{key: 'bar', value: {key: 'foo.bar', value: 'bar'}}], 103 }, 104 ]); 105 }); 106 107 test('handles mixed key types', () => { 108 const args = [ 109 {key: 'foo[0]', value: 'foo'}, 110 {key: 'foo.bar', value: 'bar'}, 111 ]; 112 expect(convertArgsToTree(args)).toEqual([ 113 { 114 key: 'foo', 115 children: [ 116 {key: 0, value: {key: 'foo[0]', value: 'foo'}}, 117 {key: 'bar', value: {key: 'foo.bar', value: 'bar'}}, 118 ], 119 }, 120 ]); 121 }); 122 123 test('picks latest where duplicate keys exist', () => { 124 const args = [ 125 {key: 'foo', value: 'foo'}, 126 {key: 'foo', value: 'bar'}, 127 ]; 128 expect(convertArgsToTree(args)).toEqual([ 129 {key: 'foo', value: {key: 'foo', value: 'bar'}}, 130 ]); 131 }); 132 133 test('handles sparse arrays', () => { 134 const args = [{key: 'foo[12]', value: 'foo'}]; 135 expect(convertArgsToTree(args)).toEqual([ 136 { 137 key: 'foo', 138 children: [{key: 12, value: {key: 'foo[12]', value: 'foo'}}], 139 }, 140 ]); 141 }); 142}); 143 144describe('convertArgsToObject', () => { 145 it('converts example arg set', () => { 146 expect(convertArgsToObject(args)).toEqual({ 147 simple_key: 'simple_value', 148 thing: { 149 key: 'value', 150 point: [ 151 {x: 10, y: 20}, 152 {x: 0, y: -10}, 153 ], 154 }, 155 foo: {bar: {foo: {bar: 'baz'}}}, 156 }); 157 }); 158 159 test('throws on args containing a node with both value and children', () => { 160 expect(() => { 161 convertArgsToObject([ 162 {key: 'foo', value: 'foo'}, 163 {key: 'foo.bar', value: 'bar'}, 164 ]); 165 }).toThrow(); 166 }); 167 168 test('throws on args containing mixed key types', () => { 169 expect(() => { 170 convertArgsToObject([ 171 {key: 'foo[0]', value: 'foo'}, 172 {key: 'foo.bar', value: 'bar'}, 173 ]); 174 }).toThrow(); 175 }); 176 177 test('picks last one where duplicate keys exist', () => { 178 const args = [ 179 {key: 'foo', value: 'foo'}, 180 {key: 'foo', value: 'bar'}, 181 ]; 182 expect(convertArgsToObject(args)).toEqual({foo: 'bar'}); 183 }); 184 185 test('handles sparse arrays', () => { 186 const args = [{key: 'foo[3]', value: 'foo'}]; 187 expect(convertArgsToObject(args)).toEqual({ 188 foo: [undefined, undefined, undefined, 'foo'], 189 }); 190 }); 191}); 192