• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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