Search code examples
typescriptgoogle-apps-scriptmockinggoogle-docsclasp

How to create an instance of GoogleAppsScript.Document.Text


I want to unit test this code, which is Typescript transpiled using Clasp into Google App Script:

function onLinksInText(text: GoogleAppsScript.Document.Text, onLink: OnLinkCallback) {
    const iterator = new TextIterator(text, onLink)
    const characters = text.getText();
    for (let i = 0; i < characters.length; i++) {
        iterator.handle(i, text.getLinkUrl(i));
    }
    iterator.end()
}

To do that, I need to create an instance of GoogleAppsScript.Document.Text

How do I do that?


Solution

  • Short answer

    You will have to mock the class.

    Long answer

    To successfully test the function, you only need the constructor, getText and getLinkUrl methods mocked. Let us also mock setText for good measure:

    function TextFactory() {
    
      const linkMatcher = /https?:\/\/(?:www\.)?(?:\.{0,1}(?:\w|-)+)+/ig;
    
      let private = "";
      
      return {
        setText(text) {
          private = text.toString();
          return this;
        },
        getText() {
          return private;
        },
        getLinkUrl(offset) {
          const idx = private.search(linkMatcher);
                
          if(idx < 0 || offset > idx ) { return null; }
          
          return private.slice(idx);
        }
      };
    }
    
    const mock = TextFactory();
    mock.setText("Find me at https://example.com ");
    
    console.log(mock.getText());
    console.log(mock.getLinkUrl(4));
    console.log(mock.getLinkUrl(12));

    I assume TextIterator is your custom class, so, for demonstration, I made a simple shallow mock:

    function TextFactory() {
    
      const linkMatcher = /https?:\/\/(?:www\.)?(?:\.{0,1}(?:\w|-)+)+/ig;
    
      let private = "";
      
      return {
        setText(text) {
          private = text.toString();
          return this;
        },
        getText() {
          return private;
        },
        getLinkUrl(offset) {
          const idx = private.search(linkMatcher);
                
          if(idx < 0 || offset > idx ) { return null; }
          
          return private.slice(idx);
        }
      };
    }
    
    const mock = TextFactory();
    mock.setText("Find me at https://example.com ");
    
    class TextIterator {
    
      constructor(text, onLink) {
        this.text = text;
        this.callback = onLink;
      }
    
      handle(index, link) {
        this.callback(`${link} at index ${index}`);
      }
    
      end() {
        console.log("ended");
      }
    }
    
    
    function onLinksInText(text, onLink) {
        const iterator = new TextIterator(text, onLink)
        const characters = text.getText();
        for (let i = 0; i < characters.length; i++) {
            iterator.handle(i, text.getLinkUrl(i));
        }
        iterator.end()
    }
    
    onLinksInText(mock, console.log );

    References

    1. Text class documentation