babel/packages/babel-core/test/caching-api.js
2018-03-10 11:40:28 +01:00

414 lines
11 KiB
JavaScript

import { makeStrongCache } from "../lib/config/caching";
describe("caching API", () => {
it("should allow permacaching with .forever()", () => {
let count = 0;
const fn = makeStrongCache((arg, cache) => {
cache.forever();
return { arg, count: count++ };
});
expect(fn("one")).toEqual({ arg: "one", count: 0 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", count: 1 });
expect(fn("two")).toBe(fn("two"));
expect(fn("one")).not.toEqual(fn("two"));
});
it("should allow disabling caching with .never()", () => {
let count = 0;
const fn = makeStrongCache((arg, cache) => {
cache.never();
return { arg, count: count++ };
});
expect(fn("one")).toEqual({ arg: "one", count: 0 });
expect(fn("one")).toEqual({ arg: "one", count: 1 });
expect(fn("one")).not.toEqual(fn("one"));
expect(fn("two")).toEqual({ arg: "two", count: 4 });
expect(fn("two")).toEqual({ arg: "two", count: 5 });
expect(fn("two")).not.toEqual(fn("two"));
expect(fn("one")).not.toEqual(fn("two"));
});
it("should allow caching based on a value with .using(fn)", () => {
let count = 0;
let other = "default";
const fn = makeStrongCache((arg, cache) => {
const val = cache.using(() => other);
return { arg, val, count: count++ };
});
expect(fn("one")).toEqual({ arg: "one", val: "default", count: 0 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "default", count: 1 });
expect(fn("two")).toBe(fn("two"));
other = "new";
expect(fn("one")).toEqual({ arg: "one", val: "new", count: 2 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "new", count: 3 });
expect(fn("two")).toBe(fn("two"));
other = "default";
expect(fn("one")).toEqual({ arg: "one", val: "default", count: 0 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "default", count: 1 });
expect(fn("two")).toBe(fn("two"));
other = "new";
expect(fn("one")).toEqual({ arg: "one", val: "new", count: 2 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "new", count: 3 });
expect(fn("two")).toBe(fn("two"));
});
it("should allow invalidation based on a value with .invalidate(fn)", () => {
let count = 0;
let other = "default";
const fn = makeStrongCache((arg, cache) => {
const val = cache.invalidate(() => other);
return { arg, val, count: count++ };
});
expect(fn("one")).toEqual({ arg: "one", val: "default", count: 0 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "default", count: 1 });
expect(fn("two")).toBe(fn("two"));
other = "new";
expect(fn("one")).toEqual({ arg: "one", val: "new", count: 2 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "new", count: 3 });
expect(fn("two")).toBe(fn("two"));
other = "default";
expect(fn("one")).toEqual({ arg: "one", val: "default", count: 4 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "default", count: 5 });
expect(fn("two")).toBe(fn("two"));
other = "new";
expect(fn("one")).toEqual({ arg: "one", val: "new", count: 6 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "new", count: 7 });
expect(fn("two")).toBe(fn("two"));
});
it("should allow invalidation with .using and .invalidate", () => {
let count = 0;
let other = "default";
let another = "another";
const fn = makeStrongCache((arg, cache) => {
const val = cache.using(() => other);
const val2 = cache.invalidate(() => another);
return { arg, val, val2, count: count++ };
});
expect(fn("one")).toEqual({
arg: "one",
val: "default",
val2: "another",
count: 0,
});
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({
arg: "two",
val: "default",
val2: "another",
count: 1,
});
expect(fn("two")).toBe(fn("two"));
other = "new";
expect(fn("one")).toEqual({
arg: "one",
val: "new",
val2: "another",
count: 2,
});
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({
arg: "two",
val: "new",
val2: "another",
count: 3,
});
expect(fn("two")).toBe(fn("two"));
other = "default";
expect(fn("one")).toEqual({
arg: "one",
val: "default",
val2: "another",
count: 4,
});
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({
arg: "two",
val: "default",
val2: "another",
count: 5,
});
expect(fn("two")).toBe(fn("two"));
other = "new";
expect(fn("one")).toEqual({
arg: "one",
val: "new",
val2: "another",
count: 6,
});
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({
arg: "two",
val: "new",
val2: "another",
count: 7,
});
expect(fn("two")).toBe(fn("two"));
another = "second";
expect(fn("one")).toEqual({
arg: "one",
val: "new",
val2: "second",
count: 8,
});
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({
arg: "two",
val: "new",
val2: "second",
count: 9,
});
expect(fn("two")).toBe(fn("two"));
});
it("should auto-permacache by default", () => {
let count = 0;
const fn = makeStrongCache(arg => ({ arg, count: count++ }));
expect(fn("one")).toEqual({ arg: "one", count: 0 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", count: 1 });
expect(fn("two")).toBe(fn("two"));
expect(fn("one")).not.toEqual(fn("two"));
});
it("should throw if you set permacaching and use .using", () => {
const fn = makeStrongCache((arg, cache) => {
cache.forever();
cache.using(() => null);
});
expect(() => fn()).toThrow(/Caching has already been configured/);
});
it("should throw if you set permacaching and use .invalidate", () => {
const fn = makeStrongCache((arg, cache) => {
cache.forever();
cache.invalidate(() => null);
});
expect(() => fn()).toThrow(/Caching has already been configured/);
});
it("should throw if you set permacaching and use .never", () => {
const fn = makeStrongCache((arg, cache) => {
cache.forever();
cache.never();
});
expect(() => fn()).toThrow(/Caching has already been configured/);
});
it("should throw if you set no caching and use .using", () => {
const fn = makeStrongCache((arg, cache) => {
cache.never();
cache.using(() => null);
});
expect(() => fn()).toThrow(/Caching has already been configured/);
});
it("should throw if you set no caching and use .invalidate", () => {
const fn = makeStrongCache((arg, cache) => {
cache.never();
cache.invalidate(() => null);
});
expect(() => fn()).toThrow(/Caching has already been configured/);
});
it("should throw if you set no caching and use .never", () => {
const fn = makeStrongCache((arg, cache) => {
cache.never();
cache.using(() => null);
});
expect(() => fn()).toThrow(/Caching has already been configured/);
});
it("should throw if you configure .forever after exiting", () => {
const fn = makeStrongCache((arg, cache) => cache);
expect(() => fn().forever()).toThrow(
/Cannot change caching after evaluation/,
);
});
it("should throw if you configure .never after exiting", () => {
const fn = makeStrongCache((arg, cache) => cache);
expect(() => fn().never()).toThrow(
/Cannot change caching after evaluation/,
);
});
it("should throw if you configure .using after exiting", () => {
const fn = makeStrongCache((arg, cache) => cache);
expect(() => fn().using(() => null)).toThrow(
/Cannot change caching after evaluation/,
);
});
it("should throw if you configure .invalidate after exiting", () => {
const fn = makeStrongCache((arg, cache) => cache);
expect(() => fn().invalidate(() => null)).toThrow(
/Cannot change caching after evaluation/,
);
});
describe("simple", () => {
it("should allow permacaching with cache(true)", () => {
let count = 0;
const fn = makeStrongCache((arg, cache) => {
cache = cache.simple();
cache(true);
return { arg, count: count++ };
});
expect(fn("one")).toEqual({ arg: "one", count: 0 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", count: 1 });
expect(fn("two")).toBe(fn("two"));
expect(fn("one")).not.toEqual(fn("two"));
});
it("should allow disabling caching with cache(false)", () => {
let count = 0;
const fn = makeStrongCache((arg, cache) => {
cache = cache.simple();
cache(false);
return { arg, count: count++ };
});
expect(fn("one")).toEqual({ arg: "one", count: 0 });
expect(fn("one")).toEqual({ arg: "one", count: 1 });
expect(fn("one")).not.toEqual(fn("one"));
expect(fn("two")).toEqual({ arg: "two", count: 4 });
expect(fn("two")).toEqual({ arg: "two", count: 5 });
expect(fn("two")).not.toEqual(fn("two"));
expect(fn("one")).not.toEqual(fn("two"));
});
it("should allow caching based on a value with cache(fn)", () => {
let count = 0;
let other = "default";
const fn = makeStrongCache((arg, cache) => {
cache = cache.simple();
const val = cache(() => other);
return { arg, val, count: count++ };
});
expect(fn("one")).toEqual({ arg: "one", val: "default", count: 0 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "default", count: 1 });
expect(fn("two")).toBe(fn("two"));
other = "new";
expect(fn("one")).toEqual({ arg: "one", val: "new", count: 2 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "new", count: 3 });
expect(fn("two")).toBe(fn("two"));
other = "default";
expect(fn("one")).toEqual({ arg: "one", val: "default", count: 0 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "default", count: 1 });
expect(fn("two")).toBe(fn("two"));
other = "new";
expect(fn("one")).toEqual({ arg: "one", val: "new", count: 2 });
expect(fn("one")).toBe(fn("one"));
expect(fn("two")).toEqual({ arg: "two", val: "new", count: 3 });
expect(fn("two")).toBe(fn("two"));
});
});
});