# `Storehouse.Memory`
[🔗](https://github.com/hattoriai/storehouse/blob/v0.2.0/lib/storehouse/memory.ex#L1)

A `Storehouse.Adapter` that keeps files in memory, for tests: every
callback, the optional ones too, with no disk, no bucket and no
container, and each test's files its own, as Ecto's sandbox keeps each
test's rows.

    # test/test_helper.exs
    {:ok, _pid} = Storehouse.Memory.start_link()
    ExUnit.start()

    # config/test.exs
    config :storehouse, adapter: Storehouse.Memory

    # in a test, or a case template's setup
    setup do
      Storehouse.Memory.checkout()
    end

## Whose files

A process that has called `checkout/0` owns the files it stores, and
sees only those: two tests run with `async: true` never see each other's
files, even under the same key. The processes it starts with `Task` see
them too (they carry it in `$callers`), and any other process once
`allow/2` lets it. A file a process stores before any checkout goes to a
space every such process shares. An owner's files go when it exits.

## Uploads straight to the store

`presign_upload/3` gives an upload whose URL no server takes: in a test,
make the browser's part of it with `put_upload/2`, which takes the bytes
as the store would, of the signed type and size only.

## Failures

`fail_next/2` makes the next call of a callback give an error, for the
tests of an app's error paths:

    Storehouse.Memory.fail_next(:delete, :unavailable)
    assert {:error, :unavailable} = Storehouse.delete(key)

See `Storehouse.Test` for assertions on what was stored.

# `allow`

```elixir
@spec allow(pid(), pid()) :: :ok
```

Lets `pid` see and store the files of `owner` (a process that checked out).

# `checkout`

```elixir
@spec checkout() :: :ok
```

Makes the calling process the owner of the files it stores from now on,
and of no others. Its files go when it exits. Gives `:ok`, for a
`setup` block.

# `fail_next`

```elixir
@spec fail_next(atom(), term()) :: :ok
```

The next call of `callback` (`:put`, `:delete`, `:read_range`, …) by the
calling process's owner gives `{:error, reason}`, or raises for the
callbacks that do not return errors (`url/1`).

# `get`

```elixir
@spec get(Storehouse.Adapter.key()) :: map() | nil
```

The file stored under `key`: its `:body`, its `:content_type` and its
`:modified_at`, or `nil`.

# `keys`

```elixir
@spec keys() :: [Storehouse.Adapter.key()]
```

The keys of the files the calling process's owner has, in order.

# `put_upload`

```elixir
@spec put_upload(Storehouse.Adapter.upload(), binary()) :: 200 | 403
```

The browser's part of an upload `presign_upload/3` signed: stores
`body` under its key when it is of the signed size, and gives the
status a bucket would (`200`, or `403` for another size, other bytes
than the checksum signed, or an upload that expired).

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts the store (its tables), once, in `test_helper.exs`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
