← Lua Academy

Capstones · 69 / 69

Build a resilient cached lookup

YOUR TASK

Make this happen

3 steps
  1. Implement lookup(key, fallback). Try the cache once. On success return its value. On failure call fallback(key), write that result to the cache, and return it. Test the behaviour without accessing any real platform services.

  2. Read the cases in lesson.test.lua, then choose Check solution to see what needs to change.

  3. Update subject.lua until every test passes. Keep the supplied tests unchanged.

Read the starter and tests

subject.lua

exports.lookup = function(key: string, fallback: (string) -> string)
  return fallback(key)
end

lesson.test.lua

local t = require("test")
local subject = require("cococo.subject")
t.it("hit avoids fallback and write", function()
  local s = subject.load()
  t.mock.host("ctx.cache.get"):returns(true, "cached")
  t.expect(s.lookup("job", function(key)
    error("unexpected fallback")
  end)):eq("cached")
  t.expect(t.mock.spy("ctx.cache.set")):never_called()
end)
t.it("failure computes and stores", function()
  local s = subject.load()
  t.mock.host("ctx.cache.get"):returns(false, "offline")
  t.mock.host("ctx.cache.set"):returns(true, nil)
  t.expect(s.lookup("job", function(key)
    return "fresh:" .. key
  end)):eq("fresh:job")
  t.expect(t.mock.spy("ctx.cache.set"))
    :called_with({ key = "job", value = "fresh:job" })
  t.expect(t.mock.spy("ctx.cache.get")):called_once()
end)