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