Back to Repositories

Testing Font Preload Cache Management in GatsbyJS

This test suite validates the caching functionality in Gatsby’s font preload plugin, focusing on cache initialization, persistence, and error handling. It ensures proper cache management for font preloading operations.

Test Coverage Overview

The test suite provides comprehensive coverage of the font preload cache mechanism.

Key areas tested include:
  • Initial cache creation and default values
  • In-memory cache retrieval
  • Disk-based cache operations
  • Error handling for file operations
  • Cache persistence verification

Implementation Analysis

The testing approach uses Jest’s mocking capabilities to simulate file system operations and process behaviors. The implementation employs mock functions for fs-extra operations and process methods, allowing controlled testing of cache operations without actual file system interaction.

Notable patterns include:
  • Mock implementations for file system operations
  • Process.cwd() mocking for consistent path resolution
  • Error scenario simulation

Technical Details

Testing tools and setup:
  • Jest as the testing framework
  • fs-extra mock for file operations
  • find-cache-dir mock for cache location
  • Process exit mocking for error handling
  • UTF-8 encoding for cache file operations

Best Practices Demonstrated

The test suite exemplifies several testing best practices in JavaScript unit testing.

Notable practices include:
  • Isolated test cases with proper setup/teardown
  • Comprehensive error path testing
  • Mock cleanup between tests
  • Consistent assertion patterns
  • Clear test case organization

gatsbyjs/gatsby

packages/gatsby-plugin-preload-fonts/src/__tests__/cache.test.js

            
jest.spyOn(process, `cwd`).mockImplementationOnce(() => `/project/root`)
const mockExit = jest.spyOn(process, `exit`).mockImplementation(() => {})

const { readFileSync, writeFileSync } = require(`fs-extra`)
const { load, save } = require(`../prepare/cache`)
const { join } = require(`path`)

jest.mock(`fs-extra`, () => {
  return {
    accessSync: jest.fn(),
    readFileSync: jest.fn(),
    writeFileSync: jest.fn(),
    constants: { W_OK: 1 },
  }
})
jest.mock(`find-cache-dir`, () => () => ``)

const resetCache = () => save(undefined)

describe(`cache`, () => {
  const defaultCache = {
    timestamp: expect.any(Number),
    hash: `initial-run`,
    assets: {},
  }

  afterEach(() => {
    resetCache()
  })

  it(`returns default cache on first run`, () => {
    expect(load()).toMatchObject(defaultCache)
  })

  it(`loads cache from memory if its already been read from disk`, () => {
    save({ from: `memory` })

    expect(load()).toMatchObject({ from: `memory` })
  })

  it(`returns default cache if reading from disk fails`, () => {
    readFileSync
      .mockImplementationOnce(() => {
        throw new Error(`file doesn't exist`)
      })
      .mockImplementationOnce(() => `malformed json`)

    expect(load()).toMatchObject(defaultCache)
    expect(load()).toMatchObject(defaultCache)
  })

  it(`persists cache to disk`, () => {
    save({ some: `cache` })

    expect(writeFileSync).toHaveBeenCalledWith(
      join(`/project/root`, `font-preload-cache.json`),
      `{"some":"cache"}`,
      `utf-8`
    )
  })

  it(`exits if writing to disk fails`, () => {
    writeFileSync.mockImplementationOnce(() => {
      throw new Error(`file not writable`)
    })

    save({ some: `cache` })

    expect(mockExit).toHaveBeenCalledWith(1)
  })
})