Steps to generate a GoogleAppsScript.Document.Text object

I am looking to conduct unit testing on this Typescript code that has been 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()
}

In order to proceed with the unit testing, I must initialize an instance of GoogleAppsScript.Document.Text

Could you please guide me on how to achieve that?

Answer №1

Summary

To effectively test the function, you need to create a mock for the class.

Detailed Explanation

In order to properly test the functionality of the function, it is essential to simulate the behavior of the constructor, getText, and getLinkUrl methods through mocking. Additionally, it is recommended to also mock the setText method for better accuracy:

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));

Assuming that TextIterator represents your custom class, a basic shallow mock has been created for illustrative purposes:

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 );

Additional Resources

  1. Text class documentation

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are the limitations of using concatMap for handling multiple requests simultaneously?

In my current function, I am receiving an array of objects called data/ids as a parameter. Within this function, I need to execute a post request for each element/id: fillProfile(users) { const requests = []; console.log( 'USERS.length:&apos ...

What is the process for linking my component to my socket.io server?

I am facing a challenge in setting up a socket.io server to facilitate communication between two components: a command interface for sending data, and an overlay component for receiving it. Below is the code snippet: interface.component.html : <input ...

Dropzone and Typescript: A Powerful Combination

I'm currently working on an application that utilizes Dropzone 4.3 and is built with Typescript. Previously, we needed to set a global variable on Dropzone for everything to work smoothly. Dropzone.autoDiscover = false; These are the node packages I ...

Node appears to be struggling to find the cors

I added the cors package and confirmed that it's inside the node_modules directory. However, I keep encountering this error message. /usr/src/app/node_modules/ts-node/src/index.ts:859 server | return new TSError(diagnosticText, diagnosticCodes, ...

Utilizing PrimeNG dropdowns within various p-tree nodes: Distinguishing between selected choices

I am working with a PrimeNg p-tree component <p-tree [value]="treeNodes" selectionMode="single" [(selection)]="selectedNode"></p-tree> The treeNodes are defined using ng-templates, with one template looking li ...

Utilize generic types as object properties in TypeScript

Is there a way to achieve something similar in TypeScript like the following: export type CoordinateSelector = <T>(d: Coordinate) => d[T]; export interface LinkVerticalLineProps { x: CoordinateSelector<'x'>; y: CoordinateSele ...

callback triggering state change

This particular member function is responsible for populating a folder_structure object with fabricated data asynchronously: fake(folders_: number, progress_callback_: (progress_: number) => void = (progress_: number) => null): Promise<boolean ...

The behavior of an Angular 2 method varies depending on whether it is called in ngOnInit or triggered by a button

In the process of constructing a website with the Angular 2 CLI, I have encountered a perplexing issue. Specifically, I am working on a page that features a reactive form and have developed a method named addQuestion() that is invoked within the ngOnInit l ...

Angular/Typescript: Getting the enum name instead of its value in a key-value pair

In my project, I have defined the interfaces Meal and Mealplan to handle data retrieved from an api. Every Mealplan includes key-value pairs, where each key corresponds to a day of the week and is stored in the enum Weekday. Therefore, each Mealplan contai ...

Discovering the Error Message within the Error Object transmitted by NodeJS to Angular

When handling errors in Nodejs functions using a try/catch scope, an error may be returned in cases such as when the user doesn't exist or when the database is unreachable. The code snippet below demonstrates this scenario: router.delete('/delete ...

Angular project icons not displaying in the browser

My current project in Angular was functioning properly until recently. I am facing an issue where the images are not being displayed on the browser when I run ng serve, resulting in a 404 error. Interestingly, everything else seems to be working fine witho ...

What are the best ways to incorporate a theme into your ReactJS project?

Looking to create a context for applying dark or light themes in repositories without the need for any manual theme change buttons. The goal is to simply set the theme and leave it as is. Currently, I have a context setup like this: import { createContext ...

Can inner function calls be mimicked?

Consider this scenario where a module is defined as follows: // utils.ts function innerFunction() { return 28; } function testing() { return innerFunction(); } export {testing} To write a unit test for the testing function and mock the return value ...

Issue with triggering blur event in Internet Explorer while using Angular 2+

The issue discussed in the Blur not working - Angular 2 thread is relevant here. I have a custom select shared component and I am attempting to implement a blur event to close it when the component loses focus. // HTML <div (blur)="closeDropDown()" t ...

Use ng2-select2 directive to connect a reactive form formControlName

For managing forms in my Angular 5 project, I have implemented Reactive Form. Within the form, I integrated ng2-select2 to create a dropdown. However, when attempting to bind formControlName to the <select2></select2> directive, an error is thr ...

Adal TypeScript Document

Recently, I've been experimenting with the TypeScript version of adal.js. As part of my setup process, I'm referring to this link to install adal.ts. However, after executing the command: npm install adal-typescript --save a new "node_modules" ...

Incorporating the Chartist plugin into an Angular 5 application

Currently, I am facing an issue while attempting to create a project in Angular 5 that involves utilizing chartist @types and js files of chartist plugins. Interestingly, the files compile without any issues in Angular 4, but encounter difficulties when t ...

Having issues with using the class selector in SVG.select() method of the svg.js library when working with TypeScript

Exploring the capabilities of the svg.js library with typescript has presented some challenges when it comes to utilizing CSS selectors. My goal is to select an SVG element using the select() method with a class selector. In this interactive example, this ...

Conceal components using routing in Angular2 release candidate 1

I have a request regarding certain elements that are to be displayed on all pages except the login page. I am considering using either ngIf or the hidden property of the elements to hide them when the user is on the login page. Here is what I have attempt ...

Transforming data objects into simplified interfaces using Typescript

Issue Explanation Current data: { "field1": "value", "field2": 3, "field3": true, "extraField": "toRemove" } An interface is defined as follows: export interface MyInterface { field1: string; field2: number; field3: boolean; } Objective ...