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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@liquify/ava

v0.0.6

Published

AVA Test runner extension pack for projects contained in the Liquify monorepo workspace.

Downloads

8

Readme

@liquify/ava

An AVA test runner extension pack for projects contained within the Liquify monorepo workspace. This module provides test utilities which help alleviate some of the complexities involved with testing AST structures in projects like @liquify/liquid-parser, Æsthetic and more!

The package is designed for usage on projects contained within the Liquify monorepo workspace.

Install

The module has a peer dependency on AVA.

pnpm add ava @liquify/ava -D

Workspace Types

Some additional configuration is required to ensure typings are made available in *.test.mjs files. Due to limitation imposed within pnpm workspace monorepos and modern package exports/imports fields. Containing tsconfig.json files will need to point to type declaration files explicitly.

Add the following configuration to tsconfig.json files.

{
  "extends": "@liquify/tsconfig",
  "include": ["tests/**/*.mjs"], // include test files
  "compilerOptions": {
    "allowJs": true, // ensure allow js is enabled
    "paths": {
      // Reference the declaration when importing @liquify/ava/parser
      "@liquify/ava/parser": ["./node_modules/@liquify/ava/package/parser.d.ts"],

      // Reference the declaration when importing @liquify/ava/prettify
      "@liquify/ava/esthetic": ["./node_modules/@liquify/ava/package/prettify.d.ts"]
    }
  }
}

Overview

The module provides various import files with exposed utilities as named exports. The Liquify monorepo workspace contains several different packages, each of which differ in terms their function and contribution to the project. You should consult the readme contained in the tests directory of each package for additional information for the test setups.

The import will pertain to the package it's leveraged by. Despite sharing identical naming conventions, the named exports of each import perform vastly different operations.

CLI

The module exposes a bin executable using the name tests and when invoked will provide a list of test files. The command accepts a single flag of -t and expects a list of directory names relative to the tests directory.

{
  "scripts": {
    "tests": "tests -t cases"
  }
}

@liquify/ava/parser

The parser import is used within the @liquify/liquid-language-parser package. The utilities provided in this import module are designed for test cases by this module.

Dev ~ @liquify/ava/parser

The dev export is used for development mode. Development mode for the Liquid Parser consists of parsing an external .liquid file and providing several utilities for inspecting the parse tree.

By default, the dev export will parse the containing dev.liquid file existing in the root of the parser/tests directory.

import test from 'ava';
import { dev, explore } from '@liquify/ava/parser';
import { LiquidParser } from '@liquify/liquid-parser';

export const parser = new LiquidParser({ engine: 'shopify' });

test('develop', async t => {

  await dev(t)(async text => {

    // Use the explore export for interfacing with the AST
    explore.ast = parser.scan(
      {
        languageId: 'liquid',
        version: 1,
        text,
        uri: 'test.liquid'
      }
    );

    // Print the parsed stack scope and objects in the tree
    explore.stack([ 'scope', 'objects' ]);

    // optionally return some additional operation instructions
    return {
      repeat: 1, // Repeat the parse
      logger: false // prints the parsed response
      finish: () => {} // A callback function to run after repeats finished
    };

  });

});

forSnippet ~ @liquify/ava/parser

The forSnippet export is used to test an array list of string literals, returning each literal in a curried callback function, which from here can be inspected using the explore export or have assertion applied.

import test from 'ava';
import { liquid, forSnippet, explore } from '@liquify/ava/parser';
import { LiquidParser } from '@liquify/liquid-parser';

const parser = new LiquidParser({ engine: 'shopify' });

test('Some Test', t => {

  forSnippet(t)(
    [
      liquid`{% assign is_nil = nil %}` // use the liquid literal to pass code samples
    ]
  )(function (sample) {

    const ast = parser.parse(sample);

    // Use explore to print sane parse errors
    explore.errors(t)(ast);

    // snapshot testing
    t.snapshot(ast);

  });

});

forSample ~ @liquify/ava/parser

The forSample export resolves a list of sample files. It will return the code snippet

import test from 'ava';
import { liquid, forSample, explore } from '@liquify/ava/parser';
import { LiquidParser } from '@liquify/liquid-parser';

const parser = new LiquidParser({ engine: 'shopify' });

test('Some Test', t => {

  // TODO

});

@liquify/ava/esthetic

The esthetic import is used within the @liquify/esthetic package. The utilities provided in this import module are designed for exhaustive and extensive testing of code formatting.

Dev ~ @liquify/ava/esthetic

The dev export is used for development mode. Development mode for esthetic consists of parsing an external .txt file and providing several utilities for inspecting the parse tree.

By default, the dev export will parse the containing dev.txt file existing in the root of the esthetic/tests directory.

import test from 'ava';
import { dev } from '@liquify/ava/esthetic';
import esthetic from '@liquify/esthetic';

test('develop', async t => {

  await dev(t)(async (source) => {

    const output = await esthetic.format(source, {
      language: 'liquid',
      wrap: 0,
      markup: {
        preserveText: true,
        forceIndent: false,
        forceAttribute: 3
      },
      json: {
        braceAllman: true,
        objectSort: true
      }
    });

    return {
      repeat: 4,
      source: output,
      logger: false,
      finish: () => t.log(output)
    };

  })

});

getSample ~ @liquify/ava/esthetic

The getSample utility resolves a sample file and returns it's source. It is a simple and trivial helper which merely resolves an external file and prints output to the terminal console. The method returns a function with 2 parameters. The first (source) contains the contents of the sample file as a string, the second optional parameter highlight will provide syntax highlighting in the CLI.

import test from 'ava'
import { getSample  } from '@liquify/ava/esthetic';

test('x', async t => {

  await getSample('path/to/sample', async (source, highlight) => {

    // The contents of the sample file as a string
    t.log(source)

    // optionally highlight output
    t.log(highlight(output, {

      // highlight options

    }))

  });

});

forSample ~ @liquify/ava/esthetic

The forSample utility resolves a list of sample files. It will return the code snippet and description in the callback function hook. This utility is great for running repeated test cases with a persisted set of rules to ensure the output is the same.

Callback

The callback function returns 3 parameters and is called in an iterable manner. The first parameter is the content contained in the sample file provided as a string type that you can pass to esthetic. The second is label generator for AVA snapshot reports that will stringify the rule options that the assertion ran and inject them into the markdown reports. The label parameter is a function that contains a getter, so you can optionally pass in the rules you've tested against.

import test from 'ava'
import { forSample  } from '@liquify/ava/esthetic';

test('x', async t => {

  await forSample('some/directory')([
    'file-1',
    'file-2',
    'file-3',
    'file-4'
  ], async function (source, label) {

      // The contents of each sample file as a string
      t.log(source)

      // Target the description contained the sample
      t.snapshot(output, label.description);

      // Optionally pass rules to be injected
      t.snapshot(output, label(rules))
    }
  );

});

forRule ~ @liquify/ava/esthetic

The forRule utility is designed for usage within esthetic. The method will resolve samples and pass different beautification rules and a second argument. This utility exposes several features for working with code snippet samples.

The function is curried, the first caller expects the sample directory relative path to be provided and also accepts a 2nd parameter that can infer a lexer target. The returning caller expects 2 parameters. The first parameter can be either an array list of options or object type map who's keys are the sample filenames contained in the directory provided in the first argument and the value an array list of lexer of options to run on each sample. The second parameter is a function callback that will be invoked for each rule (option) provided by the first argument.

Callback

The callback function returns 3 parameters and is called in an iterable manner. The first parameter is the content contained in the sample file provided as a string type that you can pass to esthetic. The second is the rule value and the third parameter is a label generator for AVA snapshot reports that will stringify the rule options that the assertion ran and inject them into the markdown reports.

import test from 'ava'
import { forRule  } from '@liquify/ava/esthetic';
import esthetic from 'esthetic';

test('x', async t => {

  await forRule('cases/directory', { lexer: 'markup' })({
    'casing-1': [
      {
        wrap: 80,
        attributeCasing: 'lowercase',
        forceAttribute: true
      }
    ],
    'casing-2': [
      {
        attributeCasing: 'preserve',
        attributeSorting: true,
        forceAttribute: true
      }
    ]
  }, async function (source, rule, label) {

    const output = await prettify.format(source, rule);

    t.snapshot(output, label.description);

  });

});

test('x', async t => {

  await util.forRule('markup/attribute-sort')([
    {
      attributeSort: true
    },
    {
      attributeSort: false
    },
  ], async function (source, markup, label) {

    const output = await prettify.format(source, { markup });

    t.snapshot(output, label({ markup }));

  });

});

test('x', async t => {

  await util.forRule('markup/attribute-casing')([
    'preserve',
    'lowercase',
    'lowercase-name',
    'lowercase-value'
  ], async function (source, attributeCasing, label) {

    const output = await prettify.format(source, { markup: { attributeCasing }});

    t.snapshot(output, label({ markup: { attributeCasing } }));

  });

});