1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @emails react-core
    
  8.  */
    
  9. 
    
  10. 'use strict';
    
  11. 
    
  12. // TODO: can we express this test with only public API?
    
  13. const getNodeForCharacterOffset =
    
  14.   require('react-dom-bindings/src/client/getNodeForCharacterOffset').default;
    
  15. 
    
  16. // Create node from HTML string
    
  17. function createNode(html) {
    
  18.   const node = (getTestDocument() || document).createElement('div');
    
  19.   node.innerHTML = html;
    
  20.   return node;
    
  21. }
    
  22. 
    
  23. function getTestDocument(markup) {
    
  24.   const doc = document.implementation.createHTMLDocument('');
    
  25.   doc.open();
    
  26.   doc.write(
    
  27.     markup ||
    
  28.       '<!doctype html><html><meta charset=utf-8><title>test doc</title>',
    
  29.   );
    
  30.   doc.close();
    
  31.   return doc;
    
  32. }
    
  33. 
    
  34. // Check getNodeForCharacterOffset return value matches expected result.
    
  35. function expectNodeOffset(result, textContent, nodeOffset) {
    
  36.   expect(result.node.textContent).toBe(textContent);
    
  37.   expect(result.offset).toBe(nodeOffset);
    
  38. }
    
  39. 
    
  40. describe('getNodeForCharacterOffset', () => {
    
  41.   it('should handle siblings', () => {
    
  42.     const node = createNode('<i>123</i><i>456</i><i>789</i>');
    
  43. 
    
  44.     expectNodeOffset(getNodeForCharacterOffset(node, 0), '123', 0);
    
  45.     expectNodeOffset(getNodeForCharacterOffset(node, 4), '456', 1);
    
  46.   });
    
  47. 
    
  48.   it('should handle trailing chars', () => {
    
  49.     const node = createNode('<i>123</i><i>456</i><i>789</i>');
    
  50. 
    
  51.     expectNodeOffset(getNodeForCharacterOffset(node, 3), '123', 3);
    
  52.     expectNodeOffset(getNodeForCharacterOffset(node, 9), '789', 3);
    
  53.   });
    
  54. 
    
  55.   it('should handle trees', () => {
    
  56.     const node = createNode(
    
  57.       '<i>' +
    
  58.         '<i>1</i>' +
    
  59.         '<i>' +
    
  60.         '<i>' +
    
  61.         '<i>2</i>' +
    
  62.         '<i></i>' +
    
  63.         '</i>' +
    
  64.         '</i>' +
    
  65.         '<i>' +
    
  66.         '3' +
    
  67.         '<i>45</i>' +
    
  68.         '</i>' +
    
  69.         '</i>',
    
  70.     );
    
  71. 
    
  72.     expectNodeOffset(getNodeForCharacterOffset(node, 3), '3', 1);
    
  73.     expectNodeOffset(getNodeForCharacterOffset(node, 5), '45', 2);
    
  74.     expect(getNodeForCharacterOffset(node, 10)).toBeUndefined();
    
  75.   });
    
  76. 
    
  77.   it('should handle non-existent offset', () => {
    
  78.     const node = createNode('<i>123</i>');
    
  79. 
    
  80.     expect(getNodeForCharacterOffset(node, -1)).toBeUndefined();
    
  81.     expect(getNodeForCharacterOffset(node, 4)).toBeUndefined();
    
  82.   });
    
  83. });