# Testing the Custom ESLint Rules

This guide shows you how to test the `no-nested-i18n-calls` ESLint rule.

## Method 1: Test on a Sample File

A test file is provided in the root: `test-eslint-rule.js`

Run the test:

```bash
npx eslint test-eslint-rule.js --rulesdir eslint-rules --rule 'no-nested-i18n-calls: error'
```

**Expected output:**

```
/Users/.../test-eslint-rule.js
   8:32  error  Avoid calling formatMessage/formatUpperCase outside of rendering...  no-nested-i18n-calls
  12:12  error  Avoid calling formatMessage/formatUpperCase outside of rendering...  no-nested-i18n-calls
  16:21  error  Avoid calling formatMessage/formatUpperCase outside of rendering...  no-nested-i18n-calls
  16:37  error  Avoid passing formatMessage/formatUpperCase results to formatMessage/formatUpperCase...   no-nested-i18n-calls
  16:37  error  Avoid calling formatMessage/formatUpperCase outside of rendering...  no-nested-i18n-calls
  19:21  error  Avoid calling formatMessage/formatUpperCase outside of rendering...  no-nested-i18n-calls
  23:12  error  Avoid calling formatMessage/formatUpperCase outside of rendering...  no-nested-i18n-calls
```

The rule should catch **7 violations**:

-   Line 8: formatUpperCase in mock function (outside component)
-   Line 12: formatMessage in utility function `getDisplayName()`
-   Line 16: formatUpperCase at module level
-   Line 16: Nested formatMessage (double translation)
-   Line 16: The nested formatMessage (also outside rendering)
-   Line 19: formatMessage at module level
-   Line 23: formatMessage in utility function `formatTitle()`

**What's allowed (no errors):**

-   Line 33: formatMessage in `MyComponent` (React component with uppercase name)
-   Line 39: formatMessage in `useTranslatedTitle` (custom hook starting with 'use')
-   Line 44: formatMessage inside JSX expression

## Method 2: Test on the Actual Codebase

Run ESLint with the custom rule on your source code:

```bash
# Test on specific directory
npx eslint src/components/ --ext .js,.jsx,.ts,.tsx --rulesdir eslint-rules --rule 'no-nested-i18n-calls: error'

# Test on specific file
npx eslint src/components/SourceOfStreamsTable/SourceOfStreamsTable.tsx --rulesdir eslint-rules --rule 'no-nested-i18n-calls: error'
```

After the GO-4217 fix, the codebase should have **zero violations**.

## Method 3: Use the Lint Script

The rule is automatically included when you run:

```bash
yarn lint
```

This runs the full lint suite including the custom rule.

## Method 4: Test in Your Editor

If your editor has ESLint integration (like VS Code with the ESLint extension), the rule will automatically run and show violations inline.

Make sure your editor's ESLint plugin is:

1. Enabled
2. Using the workspace's `.eslintrc.js` configuration
3. Restarted after adding the custom rule

## Verifying the Fix

To verify the rule catches formatMessage outside rendering:

1. Create a test file with formatMessage in a utility function:

    ```typescript
    // test-violation.ts
    const getFormattedText = () => {
        return formatMessage('some.key'); // Should be flagged!
    };
    ```

2. Run ESLint:

    ```bash
    npx eslint test-violation.ts --rulesdir eslint-rules --rule 'no-nested-i18n-calls: error'
    ```

3. You should see an error: "Avoid calling formatMessage/formatUpperCase outside of rendering"

4. Fix it by returning the key and translating in a component:

    ```typescript
    // Correct approach
    const getTextKey = () => {
        return 'some.key'; // Returns key
    };

    const MyComponent = () => {
        const text = formatMessage(getTextKey()); // Translates in component
        return <div>{text}</div>;
    };
    ```

## Common Issues

### "Definition for rule 'no-nested-i18n-calls' was not found"

Make sure you're using the `--rulesdir eslint-rules` flag or that the lint script in `package.json` includes it.

### Rule not catching violations

Check that:

1. formatMessage/formatUpperCase is being called outside of React components, hooks, or JSX
2. Your function name starts with uppercase (treated as React component) or 'use' (treated as hook)
3. You're using the correct flags when running ESLint: `--rulesdir eslint-rules`

## Creating More Test Cases

You can add more test cases to `test-eslint-rule.js`:

```javascript
// ❌ Should be flagged - utility function
const getTitle = () => formatMessage('test');

// ❌ Should be flagged - module level
const CONSTANT = formatMessage('test');

// ❌ Should be flagged - nested call
const x = formatUpperCase(formatMessage('test'));

// ✅ Should NOT be flagged - returns key
const getTitleKey = () => 'test.key';

// ✅ Should NOT be flagged - React component
const Title = () => {
    return <h1>{formatMessage('test')}</h1>;
};

// ✅ Should NOT be flagged - custom hook
const useTitle = () => formatMessage('test');
```

Then run the test to see if they're caught correctly.
