kachick / times_kachick

`#times_kachick channel in chat` as a public repository. Personal Note and TODOs
https://github.com/kachick/times_kachick/issues?q=is%3Aissue+is%3Aclosed
6 stars 0 forks source link

2024-06-02 - 期間を表せる TC39 の Temporal.Duration を含むオブジェクトを unit test で deepStrictEqual するのが面倒 #294

Closed kachick closed 5 months ago

kachick commented 6 months ago

俗に言う duration を正確に表現出来るようにするための https://github.com/tc39/proposal-temporal というのがある これはこれで助かるというか便利なので是非なんらかの成果物が組み込みで使えるようになってほしいんだけど、現状だと値の比較が厄介

まずこいつは class で、そのままの比較というか Object.is は 全く同じ値から作成されていても false を返す。 なるほどそれはわかった。じゃあどうすれば良いのかというと Temporal.Duration.compare() を使う。 -1, 0, 1 で返されるのでそれごとに対応するわけだ それはそれで良いと思うんだけど、Object.is 時点だとなんでも false のくせに nodejs の assert だとどっちも空 property だからか今度はどの値同士を比較しても true になってしまうhttps://github.com/nodejs/node/blob/667191119fa3d3b5721a4a434e78200dff776197/lib/internal/util/comparisons.js#L139-L288 よーし、じゃあ文字列比較だと言いたいところだけれど、今度はどの値から作成されたかによって同じ値でも違う文字列表現を返してくる。 {minutes: 5, seconds: 42}{seconds: 342} は compare だと勿論 0 になるが、シリアライズされる時に PT5M42SPT300S で分かれるので toString() とか toJSON() みたいなの経由して文字列比較が出来ない

公式から紹介されている Polyfill 2つ共試したけどこのあたりは同じ感じだった。 issue あたってみたけれど、特に困ってそうな質問とかに出くわさない。 deepEqual/deepStrictEqual みたいな assertion は test runner 側の実装の話と言えるかとは思うけれど、これさくっとユニットテスト書くの難しくないか・・・? とりあえず total('nanoseconds') みたいなの使って比べるような 独自 assert を生やすようにしだしたけどやなのでなんとかしたい

文脈: https://github.com/kachick/wait-other-jobs/pull/821

kachick commented 6 months ago

nodejs の assert だとどっちも空 property だからか今度はどの値同士を比較しても true になってしまう

property としては years とか minutes が生えてるから理由としては違うんだろうけど、deepEqual の実装長くて目が滑る

kachick commented 5 months ago

とりあえず json 比較をするようにした。 同じ値でも初期化時のパラメータで文字列表記が異なるようになるのは balancing という名前で取り扱われている。 round() でこれを解消できるということになっているが、結果不定でうーむという感じもあったし、そもそもこっちでテスト用に毎回返り値をnormalizeするよう意識するのか?という ただそもそもポリフィル段階だしこの辺は仕方無いというか変わりそうな気もする。今後使う時に気をつけるようにしよう

kachick commented 3 months ago

duration 系は使用頻度が高いのと統一された記法が欲しいから言語組み込みになってて欲しいなーと思う。 go だと time.Duration rust にも std::time::Duration があるみたいなんだけど JavaScript はこんな感じで Temporal を待っている。 Ruby に関しては ActiveSupport::Duration が先にあるせいで逆に標準添付ライブラリとか中々難しいのかなー

kachick commented 3 months ago

Ruby に関して

一番自然な Time#- が今更別のクラス返すわけにもいかないみたいな感じなのかもしんない。 difference とかまだ生えてないし良いのでは

kachick commented 2 months ago

割と長期に仕様検討が続いているからほんまに入るんかいなとちょっと不安にもなってたけど、Deno先生は既に組み込みで使えるようにしているから本気度高いとみているんだろうな・・・

https://deno.com/blog/v1.40#temporal-api

> deno --unstable-temporal
Deno 1.44.3
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.
> Temporal.Duration.from('PT105S').round({ largestUnit: 'minutes' })
PT1M45S
kachick commented 2 months ago

自分は今のところ Temporal.Duration にしか興味がないんだけれど、とりあえずこいつが Ruby 感覚で ><= を使って比較できないのがすごい残念感・・・ しかしこれは仕方ないんだろうなぁ。

https://github.com/tc39/proposal-temporal/blob/4799a4f6271013055fc8529b888d02d915922010/docs/duration.md#L703