mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-13 16:43:36 -06:00
* Implements code-no-observable-get-in-reactive-context * Improves code * Fixes lint warnings
203 lines
5.9 KiB
TypeScript
203 lines
5.9 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
// Test file to verify the code-no-observable-get-in-reactive-context ESLint rule works correctly
|
|
|
|
import { observableValue, derived, autorun } from '../../src/vs/base/common/observable.js';
|
|
|
|
export function testValidUsage() {
|
|
const obs = observableValue('test', 0);
|
|
|
|
// Valid: Using .read(reader) in derived
|
|
const validDerived = derived(reader => {
|
|
const value = obs.read(reader);
|
|
return value * 2;
|
|
});
|
|
|
|
// Valid: Using .read(reader) in autorun
|
|
autorun(rdr => {
|
|
const value = validDerived.read(rdr);
|
|
console.log('Value:', value);
|
|
});
|
|
|
|
// Valid: Using .get() outside reactive context
|
|
const outsideValue = obs.get();
|
|
console.log('Outside value:', outsideValue);
|
|
}
|
|
|
|
export function testInvalidUsage() {
|
|
const obs = observableValue('test', 0);
|
|
|
|
// Invalid: Using .get() in derived instead of .read(reader)
|
|
const invalidDerived = derived(rdr => {
|
|
// This should use obs.read(reader) instead
|
|
// eslint-disable-next-line local/code-no-observable-get-in-reactive-context
|
|
const value = obs.get();
|
|
// Use reader for something valid to avoid unused var warning
|
|
const validValue = obs.read(rdr);
|
|
|
|
obs.read(undefined);
|
|
|
|
return value * 2 + validValue;
|
|
});
|
|
|
|
// Invalid: Using .get() in autorun instead of .read(reader)
|
|
autorun(reader => {
|
|
// This should use invalidDerived.read(reader) instead
|
|
// eslint-disable-next-line local/code-no-observable-get-in-reactive-context
|
|
const value = invalidDerived.get();
|
|
// Use reader for something valid to avoid unused var warning
|
|
const validValue = obs.read(reader);
|
|
console.log('Value:', value, validValue);
|
|
});
|
|
|
|
// Invalid: Using .get() in derivedWithStore
|
|
derived(reader => {
|
|
// eslint-disable-next-line local/code-no-observable-get-in-reactive-context
|
|
const value = obs.get();
|
|
reader.store.add({ dispose: () => { } });
|
|
return value;
|
|
});
|
|
}
|
|
|
|
export function testComplexCases() {
|
|
const obs1 = observableValue('test1', 0);
|
|
const obs2 = observableValue('test2', 10);
|
|
|
|
// Invalid: Using .get() in conditional within derived
|
|
derived(reader => {
|
|
const initial = obs1.read(reader);
|
|
|
|
if (initial > 0) {
|
|
// eslint-disable-next-line local/code-no-observable-get-in-reactive-context
|
|
return obs2.get();
|
|
}
|
|
|
|
return initial;
|
|
});
|
|
|
|
// Invalid: Using .get() in nested function call within autorun
|
|
autorun(reader => {
|
|
const process = () => {
|
|
// eslint-disable-next-line local/code-no-observable-get-in-reactive-context
|
|
return obs1.get() + obs2.get();
|
|
};
|
|
|
|
// Use reader for something valid to avoid unused var warning
|
|
const validValue = obs1.read(reader);
|
|
const result = process();
|
|
console.log('Result:', result, validValue);
|
|
});
|
|
|
|
// Invalid: Using .get() in try-catch within derived
|
|
derived(reader => {
|
|
try {
|
|
// eslint-disable-next-line local/code-no-observable-get-in-reactive-context
|
|
const value = obs1.get();
|
|
// Use reader for something valid to avoid unused var warning
|
|
const validValue = obs2.read(reader);
|
|
return value * 2 + validValue;
|
|
} catch (e) {
|
|
return obs2.read(reader);
|
|
}
|
|
});
|
|
}
|
|
|
|
export function testValidComplexCases() {
|
|
const obs1 = observableValue('test1', 0);
|
|
const obs2 = observableValue('test2', 10);
|
|
|
|
// Valid: Proper usage with .read(reader)
|
|
derived(reader => {
|
|
const value1 = obs1.read(reader);
|
|
const value2 = obs2.read(undefined);
|
|
|
|
if (value1 > 0) {
|
|
return value2;
|
|
}
|
|
|
|
return value1;
|
|
});
|
|
|
|
// Valid: Using .get() outside reactive context
|
|
function processValues() {
|
|
const val1 = obs1.get();
|
|
const val2 = obs2.get();
|
|
return val1 + val2;
|
|
}
|
|
|
|
// Valid: Mixed usage - .read(reader) inside reactive, .get() outside
|
|
autorun(reader => {
|
|
const reactiveValue = obs1.read(reader);
|
|
const outsideValue = processValues();
|
|
console.log('Values:', reactiveValue, outsideValue);
|
|
});
|
|
}
|
|
|
|
export function testEdgeCases() {
|
|
const obs = observableValue('test', 0);
|
|
|
|
// Valid: Function with no reader parameter
|
|
derived(() => {
|
|
const value = obs.get();
|
|
return value;
|
|
});
|
|
|
|
// Invalid: Function with differently named parameter (now also flagged)
|
|
derived(_someOtherName => {
|
|
// eslint-disable-next-line local/code-no-observable-get-in-reactive-context
|
|
const value = obs.get();
|
|
return value;
|
|
});
|
|
|
|
// Invalid: Correctly named reader parameter
|
|
derived(reader => {
|
|
// eslint-disable-next-line local/code-no-observable-get-in-reactive-context
|
|
const value = obs.get();
|
|
// Use reader for something valid to avoid unused var warning
|
|
const validValue = obs.read(reader);
|
|
return value + validValue;
|
|
});
|
|
}
|
|
|
|
export function testQuickFixScenarios() {
|
|
const obs = observableValue('test', 0);
|
|
const obs2 = observableValue('test2', 10);
|
|
|
|
// These examples show what the quick fix should transform:
|
|
|
|
// Example 1: Simple case with 'reader' parameter name
|
|
derived(_reader => {
|
|
const value = obs.read(undefined); // This should be the auto-fix result
|
|
return value;
|
|
});
|
|
|
|
// Example 2: Different parameter name
|
|
derived(rdr => {
|
|
// Before fix: obs2.get()
|
|
// After fix: obs2.read(rdr)
|
|
const value = obs2.read(rdr); // This should be the auto-fix result
|
|
return value;
|
|
});
|
|
|
|
// Example 3: Complex expression
|
|
derived(ctx => {
|
|
// Before fix: (someCondition ? obs : obs2).get()
|
|
// After fix: (someCondition ? obs : obs2).read(ctx)
|
|
const someCondition = true;
|
|
const value = (someCondition ? obs : obs2).read(ctx); // This should be the auto-fix result
|
|
return value;
|
|
});
|
|
|
|
// Example 4: Multiple calls in same function
|
|
autorun(reader => {
|
|
// Before fix: obs.get() and obs2.get()
|
|
// After fix: obs.read(reader) and obs2.read(reader)
|
|
const val1 = obs.read(reader); // This should be the auto-fix result
|
|
const val2 = obs2.read(reader); // This should be the auto-fix result
|
|
console.log(val1, val2);
|
|
});
|
|
}
|