HOME/diary/

2021-11-12

Article Outline
TOC
Collection Outline

今日から頑張って日記を書く。
頑張らないを心情にできるだけ継続させることだけを考えながら書く。
その日感じたこと、考えたこと、調べたこと
そんな感じのことをだらっと書いていければという感じ。

RSpecで引数によってモックにしたりしなかったりみたいなコードを書いた

I18nのファイルが多言語と設定を兼ねてたのでそもそもが闇深いのですが、その中の特定のものをモックにしたいみたいなことがありまして...。

original_translate = I18n.method(:translate)
allow(I18n).to receive(:translate) do |key, **option|
  if key == 'count_per_pages.values'
    { :'1' => '1件', :'2' => '2件', :'3' => '3件' }
  else
    original_translate.call(key, **option)
  end
end

当然こんなコード取り込みたくないので、これを必要としているクラスにメソッドを設けて、そこを経由することでそのクラスのメソッドをモックするだけで済みました。

# こんな感じで書けるようにプロダクトコードを変更した
allow(SearchKeys).to receive(:count_per_pages).and_return({ '1件' => 1, '2件' => 2, '3件' => 3 })

レビューするのがつらくなった

同じところを何度も指摘しても全然見当違いな修正をされて再レビュー依頼される。
これは自分の指摘の仕方が悪いのか伝え方が下手なんだろうなと考えるようになり、レビューするのがしんどくなった。

RSpecでletの評価タイミングでちょいハマった

気づけば簡単なことだけど...

class Parent < ApplicationRecord; has_many :children; end
class Child < ApplicationRecord; belongs_to :parent; end
let(:parent) { Parent.create }
let!(:child) { Child.create(parent: parent) }

# こんな検証することはないけど、観点を明確にするため...
specify { expect(parent.children).eq [child] }

みたいな関連付いたレコードを作成したつもりになっていたが、実はこれ

parent.child
#=> #<ActiveRecord::Associations::CollectionProxy []>

parentが評価されるタイミングはchildが作られている途中(作られる前)なので、そのタイミングで用意されたparentcildrenを持っていない。

let(:child) { Child.new }
let!(:parent) { Parent.create(children: [child]) }

specify { expect(parent.children).eq [child] }

検証するものが何かによって用意する順序を考えないといけない。もしくは

let(:parent) { Parent.create }
let!(:child) { Child.create(parent: parent) }

# こんな検証することはないけど、観点を明確にするため...
specify { expect(parent.reload.children).eq [child] }

一旦reload挟んで最新のデータを再取得しよう。 急にこれ起きると頭が混乱して無駄な時間を過ごしてしまうので気をつけようねって話。

CircleCIに問い合わせしてたやつの返答があった

[circle skip]的なやつをやりたいんだが、実装する予定はあるのか?という質問をしていた。

[circle skip] の提供の予定は未定になっております。Feature Request があるので下記のリンクのリクエストから Upvote をしてもらえると実装する可能性が上がります。

https://ideas.circleci.com/cloud-feature-requests/p/support-skip-circleci-in-commit-messages

ワークアラウンドとして、スクリプトの処理を書くことで、[circle skip] を行う事ができます。 処理としては下記のような流れになります。

コミットメッセージの内容に [circle skip] がないか確認を行います。

条件に該当する場合に circleci-agent step halt で build を止めるコマンドを実行します。

下記の処理を参考にしてください。

- run:
  name: Skip if [circle skip]
  command: |
    MESSAGE=$(git log -1 HEAD --pretty=format:%s)
    CIRCLESKIP="*[circle skip]*"
    if [[ ${COMMIT_MESSAGE} =~ ${CIRCLESKIP} ]]; then
      circleci-agent step halt
    fi

circleci-agent step halt について: https://circleci.com/docs/2.0/configuration-reference/#ending-a-job-from-within-a-step

動作確認: https://app.circleci.com/pipelines/github/nanophate/sample_site/43/workflows/f82ce7ec-7f4c-457c-9dce-f259690e5a4a/jobs/61?invite=true#step-102-1

circleci-agent step haltを使うとなんやいい感じになるみたいやわ。(唐突な関西弁)
この質問をするにあたって「早く実装しろ、してないのはCircleCIくらいやぞ」的なちょっと強い言い方をしてしまったので気をつけたい...。
いつも後から後悔する。対応してくれた方へは感謝のメールを送った。