• 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  record,
20  requiredStr,
21  runValidator,
22  ValidatedType,
23  ValidationError
24} from './validators';
25
26const colors = ['RED', 'GREEN', 'BLUE'] as const;
27
28type Color = typeof colors[number];
29
30const point = record({
31  id: requiredStr,
32  color: oneOf<Color>(colors, 'RED'),
33  x: num(),
34  y: num(1),
35  properties: record({mass: num(10)})
36});
37
38type Point = ValidatedType<typeof point>;
39
40const nested =
41    record({deeply: record({nested: record({array: arrayOf(point)})})});
42
43test('validator ensures presence of required fields', () => {
44  expect(() => {
45    runValidator(point, {});
46  }).toThrow(ValidationError);
47});
48
49test('validator ensures correct type of required fields', () => {
50  expect(() => {
51    runValidator(point, {id: 0});
52  }).toThrow(ValidationError);
53});
54
55test('validator fills default values', () => {
56  const p: Point = runValidator(point, {id: 'test'}).result;
57
58  expect(p.color).toEqual('RED');
59  expect(p.x).toEqual(0);
60  expect(p.y).toEqual(1);
61  expect(p.properties.mass).toEqual(10);
62});
63
64test('validator uses provided values', () => {
65  const p: Point =
66      runValidator(
67          point,
68          {id: 'test', x: 100, y: 200, color: 'GREEN', properties: {mass: 20}})
69          .result;
70
71  expect(p.color).toEqual('GREEN');
72  expect(p.x).toEqual(100);
73  expect(p.y).toEqual(200);
74  expect(p.properties.mass).toEqual(20);
75});
76
77test('validator keeps information about extra and invalid keys', () => {
78  const result = runValidator(point, {
79    id: 'test',
80    x: 'should not be a string',
81    extra: 'should not be here',
82    properties: {mass: 'should be a number', weight: 'should not be here'}
83  });
84
85  expect(result.extraKeys).toContain('extra');
86  expect(result.extraKeys).toContain('properties.weight');
87  expect(result.invalidKeys).toContain('x');
88  expect(result.invalidKeys).toContain('properties.mass');
89});
90
91test('validator correctly keeps track of path when reporting keys', () => {
92  const result = runValidator(nested, {
93    extra1: 0,
94    deeply: {
95      extra2: 1,
96      nested: {
97        array: [
98          {id: 'point1', x: 'should not be a string'},
99          {id: 'point2', extra3: 'should not be here'}
100        ]
101      }
102    }
103  });
104
105  expect(result.extraKeys).toContain('extra1');
106  expect(result.extraKeys).toContain('deeply.extra2');
107  expect(result.extraKeys).toContain('deeply.nested.array[1].extra3');
108  expect(result.invalidKeys).toContain('deeply.nested.array[0].x');
109});
110