addons/isl/src/__tests__/SuccessionTracker.test.tsxblame
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 {Tracker} from 'isl-server/src/analytics/tracker';
b69ab319
b69ab3110import {SuccessionTracker} from '../SuccessionTracker';
b69ab3111import {Dag, DagCommitInfo} from '../dag/dag';
b69ab3112import {COMMIT} from '../testUtils';
b69ab3113
b69ab3114describe('SuccessionTracker', () => {
b69ab3115 const dag = new Dag().add(
b69ab3116 [
b69ab3117 COMMIT('111', 'Public commit', '0', {}),
b69ab3118 COMMIT('aaa', 'Commit A', '1', {}),
b69ab3119 COMMIT('bbb', 'Commit B', '1', {}),
b69ab3120 ].map(DagCommitInfo.fromCommitInfo),
b69ab3121 );
b69ab3122 it('finds successions', () => {
b69ab3123 const onSuccession = jest.fn();
b69ab3124 const tracker = new SuccessionTracker();
b69ab3125 const dispose = tracker.onSuccessions(onSuccession);
b69ab3126
b69ab3127 tracker.findNewSuccessionsFromCommits(dag, [
b69ab3128 COMMIT('111', 'Public commit', '0', {}),
b69ab3129 COMMIT('aaa', 'Commit A', '1', {}),
b69ab3130 COMMIT('bbb', 'Commit B', '1', {}),
b69ab3131 ]);
b69ab3132 expect(onSuccession).not.toHaveBeenCalled();
b69ab3133
b69ab3134 tracker.findNewSuccessionsFromCommits(dag, [
b69ab3135 COMMIT('111', 'Public commit', '0', {}),
b69ab3136 COMMIT('aaa2', 'Commit A - updated', '1', {closestPredecessors: ['aaa']}),
b69ab3137 COMMIT('bbb', 'Commit B', '1', {}),
b69ab3138 ]);
b69ab3139 expect(onSuccession).toHaveBeenCalledTimes(1);
b69ab3140 expect(onSuccession).toHaveBeenCalledWith([['aaa', 'aaa2']]);
b69ab3141
b69ab3142 dispose();
b69ab3143 });
b69ab3144
b69ab3145 it('only reports successions once', () => {
b69ab3146 const onSuccession = jest.fn();
b69ab3147 const tracker = new SuccessionTracker();
b69ab3148 const dispose = tracker.onSuccessions(onSuccession);
b69ab3149
b69ab3150 tracker.findNewSuccessionsFromCommits(dag, [
b69ab3151 COMMIT('111', 'Public commit', '0', {}),
b69ab3152 COMMIT('aaa', 'Commit A', '1', {}),
b69ab3153 COMMIT('bbb', 'Commit B', '1', {}),
b69ab3154 ]);
b69ab3155
b69ab3156 tracker.findNewSuccessionsFromCommits(dag, [
b69ab3157 COMMIT('111', 'Public commit', '0', {}),
b69ab3158 COMMIT('aaa2', 'Commit A - updated', '1', {closestPredecessors: ['aaa']}),
b69ab3159 COMMIT('bbb', 'Commit B', '1', {}),
b69ab3160 ]);
b69ab3161 tracker.findNewSuccessionsFromCommits(dag, [
b69ab3162 COMMIT('111', 'Public commit', '0', {}),
b69ab3163 COMMIT('aaa2', 'Commit A - updated', '1', {closestPredecessors: ['aaa']}),
b69ab3164 COMMIT('bbb', 'Commit B', '1', {}),
b69ab3165 ]);
b69ab3166 expect(onSuccession).toHaveBeenCalledTimes(1);
b69ab3167 expect(onSuccession).toHaveBeenCalledWith([['aaa', 'aaa2']]);
b69ab3168
b69ab3169 dispose();
b69ab3170 });
b69ab3171
b69ab3172 it('skips new commits even if they have predecessors', () => {
b69ab3173 const onSuccession = jest.fn();
b69ab3174 const tracker = new SuccessionTracker();
b69ab3175 const dispose = tracker.onSuccessions(onSuccession);
b69ab3176
b69ab3177 tracker.findNewSuccessionsFromCommits(dag, [
b69ab3178 COMMIT('111', 'Public commit', '0', {}),
b69ab3179 COMMIT('aaa', 'Commit A', '1', {closestPredecessors: ['a0']}),
b69ab3180 COMMIT('bbb', 'Commit B', '1', {closestPredecessors: ['b0']}),
b69ab3181 ]);
b69ab3182 expect(onSuccession).not.toHaveBeenCalled();
b69ab3183 dispose();
b69ab3184 });
b69ab3185
b69ab3186 it('handles multiple predecessors (e.g. from fold)', () => {
b69ab3187 const onSuccession = jest.fn();
b69ab3188 const tracker = new SuccessionTracker();
b69ab3189 const dispose = tracker.onSuccessions(onSuccession);
b69ab3190
b69ab3191 tracker.findNewSuccessionsFromCommits(dag, [
b69ab3192 COMMIT('111', 'Public commit', '0', {}),
b69ab3193 COMMIT('aaa', 'Commit A', '1', {}),
b69ab3194 COMMIT('bbb', 'Commit B', 'aaa', {}),
b69ab3195 COMMIT('ccc', 'Commit C', 'bbb', {}),
b69ab3196 ]);
b69ab3197 expect(onSuccession).not.toHaveBeenCalled();
b69ab3198
b69ab3199 tracker.findNewSuccessionsFromCommits(dag, [
b69ab31100 COMMIT('111', 'Public commit', '0', {}),
b69ab31101 COMMIT('aaa', 'Commit A', '1', {}),
b69ab31102 COMMIT('bc', 'Fold B & C', '1', {closestPredecessors: ['bbb', 'ccc']}),
b69ab31103 ]);
b69ab31104 expect(onSuccession).toHaveBeenCalledTimes(1);
b69ab31105 expect(onSuccession).toHaveBeenCalledWith([
b69ab31106 ['bbb', 'bc'],
b69ab31107 ['ccc', 'bc'],
b69ab31108 ]);
b69ab31109
b69ab31110 dispose();
b69ab31111 });
b69ab31112
b69ab31113 it('looks for "buggy" successsions that modify diff numbers', () => {
b69ab31114 const onSuccession = jest.fn();
b69ab31115 const tracker = new SuccessionTracker();
b69ab31116 const dispose = tracker.onSuccessions(onSuccession);
b69ab31117 const mockTrack = jest.fn();
b69ab31118
b69ab31119 window.globalIslClientTracker = {track: mockTrack} as unknown as Tracker<Record<string, never>>;
b69ab31120
b69ab31121 let dag = new Dag().add(
b69ab31122 [
b69ab31123 COMMIT('111', 'Public commit', '0', {}),
b69ab31124 COMMIT('aaa', 'Commit A', '1', {}),
b69ab31125 COMMIT('bbb', 'Commit B', '1', {}),
b69ab31126 ].map(DagCommitInfo.fromCommitInfo),
b69ab31127 );
b69ab31128
b69ab31129 tracker.findNewSuccessionsFromCommits(dag, [
b69ab31130 COMMIT('111', 'Public commit', '0', {}),
b69ab31131 COMMIT('aaa', 'Commit A', '1', {diffId: 'D111', description: 'old: D111'}),
b69ab31132 COMMIT('bbb', 'Commit B', '1', {diffId: 'D222'}),
b69ab31133 ]);
b69ab31134 expect(onSuccession).not.toHaveBeenCalled();
b69ab31135
b69ab31136 dag = new Dag().add(
b69ab31137 [
b69ab31138 COMMIT('111', 'Public commit', '0', {}),
b69ab31139 COMMIT('aaa', 'Commit A', '1', {diffId: 'D111', description: 'old: D111'}),
b69ab31140 COMMIT('bbb', 'Commit B', '1', {diffId: 'D222'}),
b69ab31141 ].map(DagCommitInfo.fromCommitInfo),
b69ab31142 );
b69ab31143
b69ab31144 tracker.findNewSuccessionsFromCommits(dag, [
b69ab31145 COMMIT('111', 'Public commit', '0', {}),
b69ab31146 COMMIT('aaa2', 'Commit A - updated', '1', {
b69ab31147 closestPredecessors: ['aaa'],
b69ab31148 diffId: 'D333',
b69ab31149 description: 'new: D333',
b69ab31150 }),
b69ab31151 COMMIT('bbb', 'Commit B', '1', {diffId: 'D222'}),
b69ab31152 ]);
b69ab31153 expect(onSuccession).toHaveBeenCalledTimes(0);
b69ab31154
b69ab31155 expect(mockTrack).toHaveBeenCalledWith('BuggySuccessionDetected', {
b69ab31156 extras: {
b69ab31157 oldHash: 'aaa',
b69ab31158 newHash: 'aaa2',
b69ab31159 old: 'Commit A\nold: D111',
b69ab31160 new: 'Commit A - updated\nnew: D333',
b69ab31161 },
b69ab31162 });
b69ab31163
b69ab31164 dispose();
b69ab31165
b69ab31166 delete (window as {globalIslClientTracker?: unknown}).globalIslClientTracker;
b69ab31167 });
b69ab31168});