• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2021 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 {
16  arrayOf,
17  num,
18  oneOf,
19  optStr,
20  record,
21  requiredStr,
22  runValidator,
23  ValidatedType,
24  ValidationError,
25} from './validators';
26
27const colors = ['RED', 'GREEN', 'BLUE'] as const;
28
29type Color = (typeof colors)[number];
30
31const point = record({
32  id: requiredStr,
33  color: oneOf<Color>(colors, 'RED'),
34  x: num(),
35  y: num(1),
36  properties: record({mass: num(10)}),
37});
38
39type Point = ValidatedType<typeof point>;
40
41const nested = record({
42  deeply: record({nested: record({array: arrayOf(point)})}),
43});
44
45test('validator ensures presence of required fields', () => {
46  expect(() => {
47    runValidator(point, {});
48  }).toThrow(ValidationError);
49});
50
51test('validator ensures correct type of required fields', () => {
52  expect(() => {
53    runValidator(point, {id: 0});
54  }).toThrow(ValidationError);
55});
56
57test('validator fills default values', () => {
58  const p: Point = runValidator(point, {id: 'test'}).result;
59
60  expect(p.color).toEqual('RED');
61  expect(p.x).toEqual(0);
62  expect(p.y).toEqual(1);
63  expect(p.properties.mass).toEqual(10);
64});
65
66test('validator uses provided values', () => {
67  const p: Point = runValidator(point, {
68    id: 'test',
69    x: 100,
70    y: 200,
71    color: 'GREEN',
72    properties: {mass: 20},
73  }).result;
74
75  expect(p.color).toEqual('GREEN');
76  expect(p.x).toEqual(100);
77  expect(p.y).toEqual(200);
78  expect(p.properties.mass).toEqual(20);
79});
80
81test('validator keeps information about extra and invalid keys', () => {
82  const result = runValidator(point, {
83    id: 'test',
84    x: 'should not be a string',
85    extra: 'should not be here',
86    properties: {mass: 'should be a number', weight: 'should not be here'},
87  });
88
89  expect(result.extraKeys).toContain('extra');
90  expect(result.extraKeys).toContain('properties.weight');
91  expect(result.invalidKeys).toContain('x');
92  expect(result.invalidKeys).toContain('properties.mass');
93});
94
95test('validator correctly keeps track of path when reporting keys', () => {
96  const result = runValidator(nested, {
97    extra1: 0,
98    deeply: {
99      extra2: 1,
100      nested: {
101        array: [
102          {id: 'point1', x: 'should not be a string'},
103          {id: 'point2', extra3: 'should not be here'},
104        ],
105      },
106    },
107  });
108
109  expect(result.extraKeys).toContain('extra1');
110  expect(result.extraKeys).toContain('deeply.extra2');
111  expect(result.extraKeys).toContain('deeply.nested.array[1].extra3');
112  expect(result.invalidKeys).toContain('deeply.nested.array[0].x');
113});
114
115describe('optStr', () => {
116  test('it validates undefined', () => {
117    const validation = runValidator(optStr, undefined);
118    expect(validation.result).toEqual(undefined);
119    expect(validation.invalidKeys).toEqual([]);
120    expect(validation.extraKeys).toEqual([]);
121  });
122
123  test('it validates string', () => {
124    const validation = runValidator(optStr, 'foo');
125    expect(validation.result).toEqual('foo');
126    expect(validation.invalidKeys).toEqual([]);
127    expect(validation.extraKeys).toEqual([]);
128  });
129
130  test('it reports numbers', () => {
131    const validation = runValidator(optStr, 42);
132    expect(validation.result).toEqual(undefined);
133    expect(validation.invalidKeys).toEqual(['']);
134    expect(validation.extraKeys).toEqual([]);
135  });
136});
137