0

My project's configuration is a bit complex, so I think it's more appropriate if I shared the commit state link. But, in short, somehow, in the utils.test.ts file, starting today, almost anything I add related to it makes the whole project so finicky.

It starts complaing about ReferenceError: HTMLElement is not defined in a totally unrelated file, which is also not referenced in the test files. Here is the whole error message:

 PASS  dist/test/elo.test.js
 FAIL  dist/test/utils.test.js
  ● Test suite failed to run

    ReferenceError: HTMLElement is not defined

      1 | import { Globals as g } from "../../infra/globals";
      2 |
    > 3 | export default class AboutView extends HTMLElement {
        |                                        ^
      4 |   static readonly tag: string = "about-view";
      5 |
      6 |   async connectedCallback(): Promise<void> {

      at Object.HTMLElement (src/ui/views/about-view.ts:3:40)
      at Object.<anonymous> (src/routing/switcher.ts:4:1)
      at Object.<anonymous> (src/routing/router.ts:3:1)
      at Object.<anonymous> (src/infra/setup.ts:13:1)
      at Object.<anonymous> (src/infra/globals.ts:2:1)
      at Object.<anonymous> (src/infra/utils.ts:3:1)
      at Object.<anonymous> (src/test/utils.test.ts:3:1)

Test Suites: 1 failed, 1 passed, 2 total
Tests:       6 passed, 6 total
Snapshots:   0 total
Time:        0.653 s, estimated 1 s
Ran all test suites matching /.\/dist\//i.

I did try to add stuff to my "lib": [] configuration in my tsconfig.json, as mentioned in this answer, but it didn't work.

The even weirder part is that, for example, the dateSorter function, which is very simple and doesn't depend on anything only runs without error if I copy-paste it into the file (I know, I know, terrible). Here is the utils.test.ts file for reference:

import * as chai from "chai";

import { paginationSlicer } from "../infra/utils";

import { GameEventTypes, TournamentOrLeague } from "../models/game_event";

describe("Pagination", () => {
  it("Pagination Slicer", () => {
    const events: TournamentOrLeague[] = [
      {
        type: GameEventTypes.tournament,
        name: "Comp 1",
        dates: [new Date(2022, 0, 29).getTime()],
      },
      {
        type: GameEventTypes.league,
        name: "Comp 2",
        dates: [new Date(2022, 0, 29).getTime()],
      },
      {
        type: GameEventTypes.league,
        name: "Comp 3",
        dates: [new Date(2022, 0, 29).getTime()],
      },
      {
        type: GameEventTypes.league,
        name: "Comp 4",
        dates: [new Date(2022, 0, 29).getTime()],
      },
      {
        type: GameEventTypes.league,
        name: "Comp 5",
        dates: [new Date(2022, 0, 29).getTime()],
      },
      {
        type: GameEventTypes.league,
        name: "Comp 6",
        dates: [new Date(2022, 0, 29).getTime()],
      },
    ];
    
    // With any of the lines below, we get the aforementioned error.
    // expect(paginationSlicer(0, events)).toEqual(5)
    // chai.expect(paginationSlicer(0, events).length).equal(5);
  });
});

// Zero idea why, but having this specific function in only one place
// doesn't work, otherwise the whole project errors in a weird fashion. This is
// currently copied in 3 different places.
const dateSorter = <T extends { date: number }>(
  dateAble1: T,
  dateAble2: T,
  desc: boolean = false
): number => {
  const [d1, d2] = [new Date(dateAble1.date), new Date(dateAble2.date)];
  const coeff = d1 > d2 ? 1 : d1 < d2 ? -1 : 0;
  return desc ? -coeff : coeff;
};

describe("Date Sorter", () => {
  it("Positive Dates", () => {
    const dateAbles = [
      { date: 1507593600003 },
      { date: 1507593600001 },
      { date: 1507593600000 },
    ];

    dateAbles.sort(dateSorter);

    chai
      .expect(dateAbles)
      .to.deep.equal([
        { date: 1507593600000 },
        { date: 1507593600001 },
        { date: 1507593600003 },
      ]);
  });

  it("Positive Descending Dates", () => {
    const dateAbles = [
      { date: 1507593600003 },
      { date: 1507593600001 },
      { date: 1507593600000 },
    ];

    dateAbles.sort((d1, d2) => dateSorter(d1, d2, true));

    chai
      .expect(dateAbles)
      .to.deep.equal([
        { date: 1507593600003 },
        { date: 1507593600001 },
        { date: 1507593600000 },
      ]);
  });

  it("Negative Dates", () => {
    const dateAbles = [
      { date: -1507593600003 },
      { date: -1507593600001 },
      { date: -1507593600000 },
    ];

    dateAbles.sort(dateSorter);

    chai
      .expect(dateAbles)
      .to.deep.equal([
        { date: -1507593600003 },
        { date: -1507593600001 },
        { date: -1507593600000 },
      ]);
  });
});

My project is organized in this way:

├── frontend/
│   ├── src/
│   │   ├── infra/
│   │   │   ├── utils.ts
│   │   ├── test/
│   │   │   ├── utils.test.ts
└── functions/

I use the frontend folder as a base and reference for the functions project. For that, in the functions' tsconfig added a reference path, and I added "composite": true.

I ended up also creating an issue on TypeScript's Github repo.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Philippe Fanaro
  • 6,148
  • 6
  • 38
  • 76
  • Do not edit the tags back into the title. They don't belong there. See [ask], specifically the section about writing a good title. I removed them for a reason. The tag system works extremely well, and doesn't need help. Adding the tags to the title is unnecessary noise and clutter. – Ken White Oct 12 '22 at 02:31
  • The error messages I'm getting are appearing within testing context. I still think it is relevant to have that configuration into the title. And that type of redundancy does make this sort of problem more searchable for people in the future. – Philippe Fanaro Oct 12 '22 at 02:34
  • The tags provide that information. It's redundant noise to add them to the title. Read the link I provided, which specifically mentions the tags in the title and why it is not necessary to add them. – Ken White Oct 12 '22 at 02:36
  • It says it will prepend *only the most important tag* into the title, not all of them, so I still disagree. And, besides, when it comes to external search, I find it very unlikely that this sort of redundancy is noise, since they mostly use a bird's eye view of what they are searching for. And, in human terms, I personally don't find this sort of stuff to be noise, if I had this same problem, I would find it useful when looking at the search results titles. – Philippe Fanaro Oct 12 '22 at 02:41
  • People who are interested in topics here follow tags. Adding the tags automatically highlight posts that use them, so it gets the post to their attention. Adding noise and clutter to the title does not help you get help any faster, and often ends up attracting downvotes. There's no point in adding unnecessary content and waste your time typing the repetitive content into your title. Besides, SO does SEO optimizations for external search engines, and I'm sure they address tags when doing so. – Ken White Oct 12 '22 at 02:45
  • I have no idea why, but eliminating a `Globals` `namespace` I had created in a file makes everything work as expected. I believe I had already had trouble with namespaces and transpilation before, but I'm still not sure why. – Philippe Fanaro Oct 12 '22 at 12:38

1 Answers1

0

Here is what I had to do in order to solve this issue:

  1. Get rid of the Globals namespace I was using, for global variables to the whole project.
  2. Install a bunch of babel packages and core-js in the functions package.json:
    "devDependencies": {
      "@babel/cli": "^7.19.3",
      "@babel/core": "^7.19.3",
      "@babel/preset-env": "^7.19.4",
      "@babel/preset-flow": "^7.18.6",
      "@babel/preset-typescript": "^7.18.6",
      "core-js": "^3.25.5",
      ...
    }
    
  3. Add a Babel configuration file to the functions folder:
    {
        "presets": [
            "@babel/preset-typescript",
            "@babel/preset-flow",
            [
                "@babel/preset-env",
                {
                    "targets": {
                        "edge": "17",
                        "firefox": "60",
                        "chrome": "67",
                        "safari": "11.1"
                    },
                    "useBuiltIns": "usage",
                    "corejs": "3.6.5"
                }
            ]
        ]
    }
    
  4. Install core-js to the frontend folder/project.

I don't know if there was something simpler, but that's what worked.

Philippe Fanaro
  • 6,148
  • 6
  • 38
  • 76