go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/common/services/resultdb/resultdb.test.ts (about) 1 // Copyright 2021 The LUCI Authors. 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 15 import { 16 createTVCmpFn, 17 createTVPropGetter, 18 getInvIdFromBuildId, 19 getInvIdFromBuildNum, 20 TestVariant, 21 TestVariantStatus, 22 } from './resultdb'; 23 24 describe('resultdb', () => { 25 test('should compute invocation ID from build number correctly', async () => { 26 const invId = await getInvIdFromBuildNum( 27 { project: 'chromium', bucket: 'ci', builder: 'ios-device' }, 28 179945, 29 ); 30 expect(invId).toStrictEqual( 31 'build-135d246ed1a40cc3e77d8b1daacc7198fe344b1ac7b95c08cb12f1cc383867d7-179945', 32 ); 33 }); 34 35 test('should compute invocation ID from build ID correctly', async () => { 36 const invId = await getInvIdFromBuildId('123456'); 37 expect(invId).toStrictEqual('build-123456'); 38 }); 39 }); 40 41 describe('createTVPropGetter', () => { 42 test('can create a status getter', async () => { 43 const getter = createTVPropGetter('status'); 44 const prop = getter({ 45 status: TestVariantStatus.EXONERATED, 46 } as Partial<TestVariant> as TestVariant); 47 expect(prop).toStrictEqual(TestVariantStatus.EXONERATED); 48 }); 49 50 test('can create a name getter', async () => { 51 const getter = createTVPropGetter('Name'); 52 53 const prop1 = getter({ 54 testId: 'test-id', 55 testMetadata: { name: 'test-name' }, 56 } as Partial<TestVariant> as TestVariant); 57 expect(prop1).toStrictEqual('test-name'); 58 59 // Fallback to test id. 60 const prop2 = getter({ 61 testId: 'test-id', 62 } as Partial<TestVariant> as TestVariant); 63 expect(prop2).toStrictEqual('test-id'); 64 }); 65 66 test('can create a variant value getter', async () => { 67 const getter = createTVPropGetter('v.variant_key'); 68 69 const prop1 = getter({ 70 variant: { def: { variant_key: 'variant_value' } }, 71 } as Partial<TestVariant> as TestVariant); 72 expect(prop1).toStrictEqual('variant_value'); 73 74 // Fallback to empty string. 75 const prop2 = getter({} as Partial<TestVariant> as TestVariant); 76 expect(prop2).toStrictEqual(''); 77 }); 78 }); 79 80 describe('createTVCmpFn', () => { 81 const variant1 = { 82 status: TestVariantStatus.UNEXPECTED, 83 testMetadata: { 84 name: 'a', 85 }, 86 variant: { def: { key1: 'val1' } }, 87 } as Partial<TestVariant> as TestVariant; 88 const variant2 = { 89 status: TestVariantStatus.EXONERATED, 90 testMetadata: { 91 name: 'b', 92 }, 93 variant: { def: { key1: 'val2' } }, 94 } as Partial<TestVariant> as TestVariant; 95 const variant3 = { 96 status: TestVariantStatus.EXONERATED, 97 testMetadata: { 98 name: 'b', 99 }, 100 variant: { def: { key1: 'val1' } }, 101 } as Partial<TestVariant> as TestVariant; 102 103 test('can create a sort fn', async () => { 104 const cmpFn = createTVCmpFn(['name']); 105 106 expect(cmpFn(variant1, variant2)).toStrictEqual(-1); 107 expect(cmpFn(variant2, variant1)).toStrictEqual(1); 108 expect(cmpFn(variant1, variant1)).toStrictEqual(0); 109 }); 110 111 test('can sort in descending order', async () => { 112 const cmpFn = createTVCmpFn(['-name']); 113 114 expect(cmpFn(variant1, variant2)).toStrictEqual(1); 115 expect(cmpFn(variant2, variant1)).toStrictEqual(-1); 116 expect(cmpFn(variant1, variant1)).toStrictEqual(0); 117 }); 118 119 test('can sort by status correctly', async () => { 120 const cmpFn = createTVCmpFn(['status']); 121 122 // Status should be treated as numbers rather than as strings when sorting. 123 expect(cmpFn(variant1, variant2)).toStrictEqual(-1); 124 expect(cmpFn(variant2, variant1)).toStrictEqual(1); 125 expect(cmpFn(variant1, variant1)).toStrictEqual(0); 126 }); 127 128 test('can sort by multiple keys', async () => { 129 const cmpFn = createTVCmpFn(['status', '-v.key1']); 130 131 expect(cmpFn(variant1, variant2)).toStrictEqual(-1); 132 expect(cmpFn(variant2, variant1)).toStrictEqual(1); 133 expect(cmpFn(variant2, variant3)).toStrictEqual(-1); 134 }); 135 });