npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fnless

v0.1.11

Published

Package to make testing functionless code easier.

Readme

fnless

Description

fnless is intended to make testing functionless code easier. The term functionless code used in this documentation refers to code like below.

// index.js
let str = 'Hello world!';
let times = 5;
for (let i = 0; i < times; i++) {
  console.log(str);
}

Variables whose value will be changed during the test (str and times in the example above) must be included in initialization. fnless will then wrap the code inside a .testProcess method, that way it can be tested. .testProcess will return string value, the same as what you get when running the source code above in terminal.

const fnless = require('fnless');
const mfnless = new fnless('./index.js', ['str', 'times']);

// Change str's value to 'Happy Holiday!' and times' value to 7
console.log(mfnless.testProcess({ str: 'Happy Holiday!', times: 7 }));

Installation

This package can be installed using npm command npm i fnless.

Usage

Constructor

Constructor of fnless class.

const fnless = require('fnless');
const mfnless = new fnless('./index.js', ['a', 'b']);

Parameters

  • solutionPath: Functionless code file path.
  • keyVars: An array of string. Each string represents a key variable's name in the functionless code.

Return

fnless object instance.

isKeyVarsValid

Check the validity of key variables in the functionless code. Invalid key variables means that some are missing or have been redeclared.

const fnless = require('fnless');
const mfnless = new fnless('./index.js', ['a', 'b']);
if (mfnless.isKeyVarsValid()) {
  console.log('Key variables valid');
} else {
  console.log('Key variables invalid');
}

Parameters

Nothing

Return

  • true: If key variables valid.
  • false: If key variables invalid.

testProcess

Wrapper of the functionless code. The value of key variables inside the functionless code can be changed according to objParams.

const fnless = require('fnless');
const mfnless = new fnless('./index.js', ['a', 'b']);
const result = mfnless.testProcess({ a: 'Acong', b: 10 });

Parameters

  • objParams: An object that contains keys that have been mentioned during object instantiation as keyVars.

Since fnless uses JSON.parse(), there will be limitations when inserting array or object as value.

  • Data types that have been tested are string, number and boolean.
  • Falsy values that are safe to be put inside array or object are false, 0, '' and null.
  • Falsy value -0 will be converted to 0.
  • When undefined is used in array, it will be converted to null. When undefined is used in object, the key will be skipped.
  • Falsy value NaN will be converted to null.
  • Both Infinity and -Infinity cannot be used because they will be converted to null.

Return

Same string you get when running the functionless code in terminal.

deleteInstrumentFile

Delete instrument file that was created by .testProcess method. This method should be called after all testing has been completed.

Parameters

Nothing

Return

Nothing

Example

This is an example when using fnless with jest.

index.js

var scrollPos = 'bottom';
var agree = true;
var spyware = true;

// Your code here

__test__/index.test.js

const fs = require('fs');
const fnless = require('fnless');

const mfnless = new fnless('./index.js', ['scrollPos', 'agree', 'spyware']);

afterAll(() => {
  mfnless.deleteInstrumentFile();
});

it('Key variables valid', () => {
  expect(mfnless.isKeyVarsValid()).toBe(true);
});

describe(`Testing invalid inputs`, () => {
  it(`scrollPos: 'bottom'`, async () => {
    expect(mfnless.testProcess({ scrollPos: 'bottom' })).toMatch('Unknown error');
  });
  it(`agree: true`, async () => {
    expect(mfnless.testProcess({ agree: true })).toMatch('Unknown error');
  });
  it(`spyware: true`, async () => {
    expect(mfnless.testProcess({ spyware: true })).toMatch('Unknown error');
  });
  it(`scrollPos: '', agree: true, spyware: true`, async () => {
    expect(mfnless.testProcess({ scrollPos: '', agree: true, spyware: true })).toMatch('Unknown error');
  });
});

describe(`Testing valid inputs`, () => {
  it(`scrollPos: 'bottom', agree: false, spyware: true`, async () => {
    expect(mfnless.testProcess({ scrollPos: 'bottom', agree: false, spyware: true })).toMatch('Cannot proceed when not agree');
  });
  it(`scrollPos: 'bottom', agree: true, spyware: false`, async () => {
    expect(mfnless.testProcess({ scrollPos: 'bottom', agree: true, spyware: false })).toMatch('Installing software');
  });
  it(`scrollPos: 'bottom', agree: true, spyware: true`, async () => {
    expect(mfnless.testProcess({ scrollPos: 'bottom', agree: true, spyware: true })).toMatch('Installing software + spyware remover');
  });
  it(`scrollPos: 'qwerty', agree: true, spyware: true`, async () => {
    expect(mfnless.testProcess({ scrollPos: 'qwerty', agree: true, spyware: true })).toMatch('You have to read all the clauses before accepting');
  });
  it(`scrollPos: 'qwerty', agree: true, spyware: false`, async () => {
    expect(mfnless.testProcess({ scrollPos: 'qwerty', agree: true, spyware: false })).toMatch('You have to read all the clauses before accepting');
  });
  it(`scrollPos: 'qwerty', agree: false, spyware: true`, async () => {
    expect(mfnless.testProcess({ scrollPos: 'qwerty', agree: false, spyware: true })).toMatch('You have to read all the clauses before accepting');
  });
  it(`scrollPos: 'qwerty', agree: false, spyware: false`, async () => {
    expect(mfnless.testProcess({ scrollPos: 'qwerty', agree: false, spyware: false })).toMatch('You have to read all the clauses before accepting');
  });
});