mmag

ハマったことメモなど

Custom Propertyが定義されていればそれを使い、定義されていなければデフォルト値を使うSassの変数

$main-color: var(--main-color, #345);

ただ単に使えば#345にフォールバックするし、どこかで--main-colorを定義しておくと上書きできるっていう一発ネタ。おやすみなさい。

pre-commitが便利

https://pre-commit.com/

git commitする前にあれこれやってくれるやつ。Nodeのプロジェクトだとhuskyとか使うことがあるけど、monorepoで言語が混在してるときに便利。ルートにこんな感じの.pre-commit-config.yamlを置きます。

- repo: git://github.com/pre-commit/pre-commit-hooks
  rev: v2.4.0
  hooks:
    - id: trailing-whitespace
    - id: check-merge-conflict
    - id: check-yaml
    - id: end-of-file-fixer

- repo: local
  hooks:
    - id: format-app1
      name: Format app1
      entry: bash -c 'cd app1 && mix format'
      language: system
      files: ^app1/.+\.exs*$
    - id: format-app2
      name: Format app2
      entry: bash -c 'cd app2 && npm run lint:staged'
      language: system
      files: ^app2/.+\.(js|scss|svelte)$
    - id: format-app3
      name: Format app3
      entry: bash -c 'cd app3 && npm run lint:staged'
      language: system
      files: ^app3/.+\.(js|scss|svelte)$

あらかじめ用意されたhookも使えるし、filesで条件を指定するとマッチするファイルをcommitするときだけ走ってくれて賢い。あとサブディレクトリで何かするときはbash -c 'cd sub && ...'するとよいです。

Svelteコンポーネントをテストするときはテスト用コンポーネントを書くといい気がした

気がしているという程度なので話半分で。

前提

Svelteのコンポーネントをテストしたい。テストにはjest@testing-library/svelteを使用。

本題

発端としては「Buttonコンポーネントをrenderするとslotの中身が表示される」というはじめの一歩的なものを書こうとしたらslotを指定できなくてハマったのでした。Svelte 2の頃はComponent APIslotsオプションを受け付けていてくれたので、testing-library経由で

import { render } from '@testing-library/svelte'
import Button from '../my/Button.svelte'

render(
  Button,
  { props: { ... } },
  { slots: { default: OtherComponent } }
)

みたいなことができたのですが、3になって出来なくなった模様。参考はこちら

で、slotがこちらの自由にできないとなると、他のいろんなテストも不自由な感じになってくるわけで、この不自由の中でテストなんか書きたくないわけです。つーわけでもうテスト用にコンポーネント書いちゃえばいいんじゃないのっていう話。

<!-- ButtonTest.svelte -->

<script>
  import Button from '../../my/Button.svelte'

  let count = 0

  function handleClick() {
    count++
  }
</script>

<Button on:click="{handleClick}">Push</Button>
<span>count == {count}</span>
// Button.test.js

import '@testing-library/jest-dom/extend-expect'
import { render, fireEvent } from '@testing-library/svelte'
import ButtonTest from './ButtonTest.svelte'

test('shows slot text', () => {
  const { getByText } = render(ButtonTest, {})

  expect(getByText('Push')).toBeInTheDocument()
})

test('handles click', async () => {
  const { getByText } = render(ButtonTest, {})
  const button = getByText('Push')

  await fireEvent.click(button)

  expect(getByText('count == 1')).toBeInTheDocument()
})

テストライブラリのAPI何回調べても必ず忘れるので、テストコード側は簡単なことだけやってればいいようにしてます。

もうちょっと整理して、テスト用のコンポーネントにするんじゃなくて、Storybookから読んでもいいようにするのもアリなのかなと思ったり思ってなかったり。

あと関係ないんですが、開発者のフルスタックフレームワーク離れが進んで小さなパッケージを選んで組み合わせる流れがあるのに、テストはこれまでのお茶会が終わってjest入れとけばええんやみたいな空気が出てきてるの、不思議な感じがしています。