• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2022 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 {EngineBase} from '../../trace_processor/engine';
16
17import {Column} from './column';
18import {SqlTableState} from './state';
19import {SqlTableDescription} from './table_description';
20
21const table: SqlTableDescription = {
22  name: 'table',
23  displayName: 'Table',
24  columns: [
25    {
26      name: 'id',
27    },
28    {
29      name: 'name',
30      title: 'Name',
31    },
32    {
33      name: 'ts',
34      display: {
35        type: 'timestamp',
36      },
37      startsHidden: true,
38    },
39    {
40      name: 'arg_set_id',
41      type: 'arg_set_id',
42      title: 'Arg',
43    },
44  ],
45};
46
47class FakeEngine extends EngineBase {
48  id: string = 'TestEngine';
49
50  rpcSendRequestBytes(_data: Uint8Array) {}
51}
52
53test('sqlTableState: columnManupulation', () => {
54  const engine = new FakeEngine();
55  const state = new SqlTableState(engine, table);
56
57  const idColumn = {
58    alias: 'id',
59    expression: 'id',
60    title: 'id',
61  };
62  const nameColumn = {
63    alias: 'name',
64    expression: 'name',
65    title: 'Name',
66  };
67  const tsColumn: Column = {
68    alias: 'ts',
69    expression: 'ts',
70    title: 'ts',
71    display: {
72      type: 'timestamp',
73    },
74  };
75
76  // The initial set of columns should include "id" and "name",
77  // but not "ts" (as it is marked as startsHidden) and not "arg_set_id"
78  // (as it is a special column).
79  expect(state.getSelectedColumns()).toEqual([idColumn, nameColumn]);
80
81  state.addColumn(tsColumn, 0);
82
83  expect(state.getSelectedColumns()).toEqual([idColumn, tsColumn, nameColumn]);
84
85  state.hideColumnAtIndex(0);
86
87  expect(state.getSelectedColumns()).toEqual([tsColumn, nameColumn]);
88});
89
90test('sqlTableState: sortedColumns', () => {
91  const engine = new FakeEngine();
92  const state = new SqlTableState(engine, table);
93
94  // Verify that we have two columns: "id" and "name" and
95  // save references to them.
96  expect(state.getSelectedColumns().length).toBe(2);
97  const idColumn = state.getSelectedColumns()[0];
98  expect(idColumn.alias).toBe('id');
99  const nameColumn = state.getSelectedColumns()[1];
100  expect(nameColumn.alias).toBe('name');
101
102  // Sort by name column and verify that it is sorted by.
103  state.sortBy({
104    column: nameColumn,
105    direction: 'ASC',
106  });
107  expect(state.isSortedBy(idColumn)).toBe(undefined);
108  expect(state.isSortedBy(nameColumn)).toBe('ASC');
109
110  // Sort by the same column in the opposite direction.
111  state.sortBy({
112    column: nameColumn,
113    direction: 'DESC',
114  });
115  expect(state.isSortedBy(idColumn)).toBe(undefined);
116  expect(state.isSortedBy(nameColumn)).toBe('DESC');
117
118  // Sort by the id column.
119  state.sortBy({
120    column: idColumn,
121    direction: 'ASC',
122  });
123  expect(state.isSortedBy(idColumn)).toBe('ASC');
124  expect(state.isSortedBy(nameColumn)).toBe(undefined);
125
126  // When the column is hidden, it should no longer be sorted by
127  // and we should fall back to the previously sorted by column.
128  state.hideColumnAtIndex(0);
129  expect(state.isSortedBy(nameColumn)).toBe('DESC');
130
131  // Remove the sorting and verify that we are no sorted by.
132  state.unsort();
133  expect(state.isSortedBy(nameColumn)).toBe(undefined);
134});
135
136// Clean up repeated whitespaces to allow for easier testing.
137function normalize(s: string): string {
138  return s.replace(/\s+/g, ' ').trim();
139}
140
141test('sqlTableState: sqlStatement', () => {
142  const engine = new FakeEngine();
143  const state = new SqlTableState(engine, table);
144
145  // Check the generated SQL statement.
146  expect(normalize(state.buildSqlSelectStatement().selectStatement)).toBe(
147    'SELECT id as id, name as name FROM table',
148  );
149});
150