Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/** replaceJSX
* RegExp search text and replace with JSX
* @see https://stackoverflow.com/a/63647844
* @param {string} str
* @param {RegExp} find
* @param {JSX} replace
* @returns {JSX}
*/
export default function replaceJSX(str, find, replace) {
const parts = str.split(find);
const result = [];
for (let i = 0; i < parts.length; i++) {
result.push(parts[i]);
if (i < parts.length - 1) result.push(replace);
}
return result;
}
@gdibble
Copy link
Author

gdibble commented Oct 13, 2021

Above file as /src/utils/replaceJSX/index.js

Jest Unit Test

Named /src/utils/replaceJSX/index.test.js:

/* eslint-disable no-unused-expressions */
import { render } from '@testing-library/react';
import replaceJSX from '.';

// Arrange
const textBlock = '"Number": "TOP-003-4",';
const textToMatch = 'TOP';
const matchText = new RegExp(textToMatch, 'gi');
const textToNotMatch = 'No Dice';
const noMatchText = new RegExp(textToNotMatch, 'gi');

/**
 * Tests for the `replaceJSX` util
 */
describe('replaceJSX Tests', () => {

  describe('Positive Result Tests', () => {

    test('Text to not include <span> used for highlighting', () => {

      // Act
      const div1 = document.createElement('div');

      // Assert
      expect(div1.querySelector('span')).not.toBeTrue;
    
    });

    test('Wrap matched text with <span> tag', () => {

      // Act
      const highlightedText = replaceJSX(
        textBlock,
        matchText,
        <span key={Math.random()}>{textToMatch}</span>,
      );
      render(<div key={Math.random()}>{highlightedText}</div>);

      // Assert
      expect(document.body.querySelector('span')).toBeTrue;
      expect(document.body.querySelector('span').innerHTML).toEqual(textToMatch);
    
    });
  
  });

  describe('Negative Result Tests', () => {

    test('Throw error with no arguments', () => {

      try {

        // Assert
        expect(replaceJSX()).toThrow();
      
      } catch (e) {} // eslint-disable-line no-empty
    
    });

    test('Does not wrap text with <em> tag', () => {

      // Act
      const highlightedText = replaceJSX(
        textBlock,
        noMatchText,
        <em key={Math.random()}>{textToNotMatch}</em>,
      );
      render(<div key={Math.random()}>{highlightedText}</div>);

      // Assert
      expect(document.body.querySelector('em')).toBeFalse;
    
    });
  
  });

});

Result:

 PASS  src/utils/replaceJSX/index.test.js
  replaceJSX Tests
    Positive Result Tests
      ✓ Text to not include <span> used for highlighting (6 ms)
      ✓ Wrap matched text with <span> tag (14 ms)
    Negative Result Tests
      ✓ Throw error with no arguments (1 ms)
      ✓ Does not wrap text with <em> tag (2 ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        1.933 s, estimated 2 s
Ran all test suites matching /src\/utils\/replaceJSX\/index.test.js/i.

@gdibble
Copy link
Author

gdibble commented Oct 14, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment