node-libgpiod icon indicating copy to clipboard operation
node-libgpiod copied to clipboard

Attempting to test with Vitest

Open khill-fbmc opened this issue 2 years ago • 10 comments

I decided to take a stab at getting your tests you wrote to work with Vitest since it is the new hotness.

I am getting close but getting this weird error, and since I don't know C++ I don't know what it means heh

image

khill-fbmc avatar Nov 16 '23 17:11 khill-fbmc

Would I be correct to assume that it can only be imported / instantiated once?

I am trying to put this in a setup.mjs for vitest

import { gpiod } from "../index.mjs";

import { beforeAll } from "vitest";

beforeAll(() => {
    globalThis.gpiod = gpiod;
});

and this could be wrong, but I modded index.js => index.mjs

import os from 'node:os';
import bindings from 'bindings';

let libgpiod = { available: () => false };

// prevent module being loaded on anything other than Linux
if (os.type() === 'Linux') {
    // entry point
    try {
        libgpiod = bindings('node-libgpiod');

        libgpiod.Chip.prototype.getLine = (n) => {
            return new libgpiod.Line(this, n);
        };

        libgpiod.available = () => true;
    } catch (e) {
        console.error(e);
    }
}

export default libgpiod;
export const gpiod = libgpiod;

khill-fbmc avatar Nov 16 '23 17:11 khill-fbmc

Importing it directly works...

image

and the suite passes (because I put .skip on the others)

khill-fbmc avatar Nov 16 '23 17:11 khill-fbmc

yes it might be related with #4 , at some point i need to go back on the C++ side and see how to solve that.

besides that, going CommonsJS or ES6 modules should not cause any major issue.

that would be a cool enhancement.

sombriks avatar Nov 16 '23 17:11 sombriks

Getting closer!

import { gpiod } from "../index.mjs";

import { afterAll, beforeAll } from 'vitest';

beforeAll(() => {
    if (!globalThis.gpiod) {
        globalThis.gpiod = gpiod;
    }
});

afterAll(() => {
    delete globalThis.gpiod;
});

now works and

import { describe, it } from "vitest";

describe("libgpiod miscellaneous bindings", () => {
  it("should be available", async ({ expect }) => {
    expect(gpiod.available()).toBeTruthy();
  });

  it("should get libgpiod version", async ({ expect }) => {
    expect(gpiod.version()).toBe("1.6.2");
  });

  it("should get line instant value", async ({ expect }) => {
    const val = gpiod.getInstantLineValue(0, 17);
    expect(val).toBe(0);
  });

  it("should NOT get line instant value due wrong chip name", async ({ expect }) => {
    expect(() => {
      gpiod.getInstantLineValue("/dev/gpiochipZero", 17);
    }).toThrowError();
  });

  it("should blink line with instant value", async ({ expect }) => {
    let count = 7;
    const interval = setInterval(() => {
      gpiod.setInstantLineValue("/dev/gpiochip0", 17, count-- % 2);
      if (count == 0) {
        clearInterval(interval);
        return;
      }
    }, 70);
  });
});

passes :) and so does the chip tests.

It seems the initial error is part of the line tests...

khill-fbmc avatar Nov 16 '23 18:11 khill-fbmc

this is nice ;-) i have a PR to enable it to run on every commit but as you can imagine we're limited by the lack of gpio pins on github runners 😅

anyway, please open a PR to the repo when you feel you get a time so we can offer this to everyone consuming this library.

sombriks avatar Nov 16 '23 18:11 sombriks

made a workflow for testing... definitely will have to mock some things... 😄

image

khill-fbmc avatar Nov 16 '23 18:11 khill-fbmc

How attached to the implementation of index.js are you? I'm running into the issue where I can't seem to get the os module to be mocked for the tests... os.type() === 'Linux' continues to be Darwin on my computer and can't import the module.

I was thinking maybe a factory function that returns the library so the os type check isn't a side effect of importing the module. Maybe have it throw and the user can handle the error?

khill-fbmc avatar Nov 20 '23 11:11 khill-fbmc

Hi @khill-fbmc !

This is one issue i could address along the 'testing mode' for the library.

In order to proper cover the library with tests, i will need to simulate gpiopins so it can be transparent for the javascript wrapper if we are in a real hardware of inside a github runner or something.

my findings so far point to use exactly what ligpiod itself uses to test: https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/tests/Makefile.am?h=v1.6.x

but we can also make use of some environment variables to override a few things, the operating system environment for instance.

we could create a set of prefixed environment variables to override our system checks, for example NODE_LIBGPIOD_OS_TYPE ; lib bootstrap would stilll performing the check, but the env var would take precedence and then we use that.

i plan to spare time this weekend to move forward to it, we can discuss good overrides for this situation and others

sombriks avatar Nov 21 '23 14:11 sombriks

still blocked by #24

sombriks avatar Feb 25 '24 15:02 sombriks

issues cleanup.

our mocha test suite still need improvements, vite would be good, if the gpio-sim gets completely figured out on github actions besides local development.

we can back to the topic in the future, focusing on complete API parity for now, we still lack bulk read/write and callbacks.

sombriks avatar Jun 30 '24 16:06 sombriks

No worries! I did drive through in classic ADHD style, do some work that was interesting right then, and now I am miles away 🙃

khill-fbmc avatar Jul 01 '24 12:07 khill-fbmc