addons/isl/src/__tests__/pathTree.test.tsblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318import type {UseUncommittedSelection} from '../partialSelection';
b69ab319import type {PathTree} from '../pathTree';
b69ab3110
b69ab3111import {buildPathTree, calculateTreeSelectionStates} from '../pathTree';
b69ab3112
b69ab3113type FakeData = {name: string};
b69ab3114describe('pathTree', () => {
b69ab3115 it('constructs tree', () => {
b69ab3116 const tree = buildPathTree<FakeData>({
b69ab3117 'a/b/file1.txt': {name: 'file1.txt'},
b69ab3118 'a/b/file2.txt': {name: 'file2.txt'},
b69ab3119 'a/file3.txt': {name: 'file3.txt'},
b69ab3120 'a/d/e/f/file4.txt': {name: 'file4.txt'},
b69ab3121 'q/file5.txt': {name: 'file5.txt'},
b69ab3122 'file6.txt': {name: 'file5.txt'},
b69ab3123 });
b69ab3124
b69ab3125 expect(tree).toEqual(
b69ab3126 testTree([
b69ab3127 [
b69ab3128 'a',
b69ab3129 [
b69ab3130 [
b69ab3131 'b',
b69ab3132 [
b69ab3133 ['file1.txt', {name: 'file1.txt'}],
b69ab3134 ['file2.txt', {name: 'file2.txt'}],
b69ab3135 ],
b69ab3136 ],
b69ab3137 ['file3.txt', {name: 'file3.txt'}],
b69ab3138 ['d/e/f', [['file4.txt', {name: 'file4.txt'}]]],
b69ab3139 ],
b69ab3140 ],
b69ab3141 ['q', [['file5.txt', {name: 'file5.txt'}]]],
b69ab3142 ['file6.txt', {name: 'file5.txt'}],
b69ab3143 ]),
b69ab3144 );
b69ab3145 });
b69ab3146
b69ab3147 it('groups out of order elements tree', () => {
b69ab3148 const tree = buildPathTree<FakeData>({
b69ab3149 'a/b/file1.txt': {name: 'file1.txt'},
b69ab3150 'file6.txt': {name: 'file5.txt'},
b69ab3151 'a/file3.txt': {name: 'file3.txt'},
b69ab3152 'a/d/e/f/file4.txt': {name: 'file4.txt'},
b69ab3153 'q/file5.txt': {name: 'file5.txt'},
b69ab3154 'a/b/file2.txt': {name: 'file2.txt'},
b69ab3155 });
b69ab3156
b69ab3157 expect(tree).toEqual(
b69ab3158 testTree([
b69ab3159 [
b69ab3160 'a',
b69ab3161 [
b69ab3162 [
b69ab3163 'b',
b69ab3164 [
b69ab3165 ['file1.txt', {name: 'file1.txt'}],
b69ab3166 ['file2.txt', {name: 'file2.txt'}],
b69ab3167 ],
b69ab3168 ],
b69ab3169 ['file3.txt', {name: 'file3.txt'}],
b69ab3170 ['d/e/f', [['file4.txt', {name: 'file4.txt'}]]],
b69ab3171 ],
b69ab3172 ],
b69ab3173 ['q', [['file5.txt', {name: 'file5.txt'}]]],
b69ab3174 ['file6.txt', {name: 'file5.txt'}],
b69ab3175 ]),
b69ab3176 );
b69ab3177 });
b69ab3178
b69ab3179 it('groups with condensed prefixes', () => {
b69ab3180 const tree = buildPathTree<FakeData>({
b69ab3181 'a/b/file1.txt': {name: 'file1.txt'},
b69ab3182 'a/b/file2.txt': {name: 'file2.txt'},
b69ab3183 'a/b/c/d/e/file3.txt': {name: 'file3.txt'},
b69ab3184 'a/b/c/d/e/file4.txt': {name: 'file4.txt'},
b69ab3185 });
b69ab3186
b69ab3187 expect(tree).toEqual(
b69ab3188 testTree([
b69ab3189 [
b69ab3190 'a/b',
b69ab3191 [
b69ab3192 ['file1.txt', {name: 'file1.txt'}],
b69ab3193 ['file2.txt', {name: 'file2.txt'}],
b69ab3194 [
b69ab3195 'c/d/e',
b69ab3196 [
b69ab3197 ['file3.txt', {name: 'file3.txt'}],
b69ab3198 ['file4.txt', {name: 'file4.txt'}],
b69ab3199 ],
b69ab31100 ],
b69ab31101 ],
b69ab31102 ],
b69ab31103 ]),
b69ab31104 );
b69ab31105 });
b69ab31106
b69ab31107 it('testtree util works', () => {
b69ab31108 expect(
b69ab31109 testTree([
b69ab31110 [
b69ab31111 'a',
b69ab31112 [
b69ab31113 [
b69ab31114 'b',
b69ab31115 [
b69ab31116 ['file1.txt', {name: 'file1.txt'}],
b69ab31117 ['file2.txt', {name: 'file2.txt'}],
b69ab31118 ],
b69ab31119 ],
b69ab31120 ['file3.txt', {name: 'file3.txt'}],
b69ab31121 ],
b69ab31122 ],
b69ab31123 ['file4.txt', {name: 'file4.txt'}],
b69ab31124 ]),
b69ab31125 ).toEqual(
b69ab31126 new Map<string, FakeData | Map<string, FakeData | Map<string, FakeData>>>([
b69ab31127 [
b69ab31128 'a',
b69ab31129 new Map<string, FakeData | Map<string, FakeData>>([
b69ab31130 [
b69ab31131 'b',
b69ab31132 new Map([
b69ab31133 ['file1.txt', {name: 'file1.txt'}],
b69ab31134 ['file2.txt', {name: 'file2.txt'}],
b69ab31135 ]),
b69ab31136 ],
b69ab31137 ['file3.txt', {name: 'file3.txt'}],
b69ab31138 ]),
b69ab31139 ],
b69ab31140 ['file4.txt', {name: 'file4.txt'}],
b69ab31141 ]),
b69ab31142 );
b69ab31143 });
b69ab31144});
b69ab31145
b69ab31146type Data = Array<[string, Data | FakeData]>;
b69ab31147// make testing slightly easier so we don't need to construct maps in expected result
b69ab31148function testTree(data: Data): PathTree<FakeData> {
b69ab31149 return new Map(
b69ab31150 data.map(([k, v]): [string, FakeData | PathTree<FakeData>] =>
b69ab31151 Array.isArray(v) ? [k, testTree(v)] : [k, v],
b69ab31152 ),
b69ab31153 );
b69ab31154}
b69ab31155
b69ab31156describe('calculateTreeSelectionStates', () => {
b69ab31157 it('computes selection states', () => {
b69ab31158 const selection = {
b69ab31159 isFullySelected: (path: string) => {
b69ab31160 switch (path) {
b69ab31161 case 'file1.txt':
b69ab31162 case 'file2.txt':
b69ab31163 case 'file3.txt':
b69ab31164 case 'file5.txt':
b69ab31165 return true;
b69ab31166 default:
b69ab31167 return false;
b69ab31168 }
b69ab31169 },
b69ab31170 isFullyOrPartiallySelected: (path: string) => {
b69ab31171 switch (path) {
b69ab31172 case 'file1.txt':
b69ab31173 case 'file2.txt':
b69ab31174 case 'file3.txt':
b69ab31175 case 'file6.txt':
b69ab31176 return true;
b69ab31177 default:
b69ab31178 return false;
b69ab31179 }
b69ab31180 },
b69ab31181 } as UseUncommittedSelection;
b69ab31182 const tree = buildPathTree<{path: string}>({
b69ab31183 'a/b/file1.txt': {path: 'file1.txt'}, // checked
b69ab31184 'a/b/file2.txt': {path: 'file2.txt'}, // checked
b69ab31185 'a/c/file3.txt': {path: 'file3.txt'}, // checked
b69ab31186 'a/c/file4.txt': {path: 'file4.txt'}, // UNchecked
b69ab31187 'a/d/file5.txt': {path: 'file5.txt'}, // checked
b69ab31188 'a/d/file6.txt': {path: 'file6.txt'}, // partially checked
b69ab31189 'q/file7.txt': {path: 'file7.txt'}, // UNchecked
b69ab31190 });
b69ab31191
b69ab31192 expect(calculateTreeSelectionStates(tree, selection)).toEqual(
b69ab31193 new Map<string, boolean | 'indeterminate'>([
b69ab31194 ['', 'indeterminate'],
b69ab31195 ['/a', 'indeterminate'],
b69ab31196 ['/a/b', true],
b69ab31197 ['/a/c', 'indeterminate'],
b69ab31198 ['/a/d', 'indeterminate'],
b69ab31199 ['/q', false],
b69ab31200 ]),
b69ab31201 );
b69ab31202 });
b69ab31203});