Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
kachick opened this issue Jun 2, 2024 · 6 comments
Labels
help wanted Extra attention is needed

Comments

@kachick
Copy link
Owner

kachick commented Jun 2, 2024

俗に言う 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 を生やすようにしだしたけどやなのでなんとかしたい

文脈: kachick/wait-other-jobs#821

@kachick kachick added the help wanted Extra attention is needed label Jun 2, 2024
@kachick
Copy link
Owner Author

kachick commented Jun 3, 2024

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

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

@kachick
Copy link
Owner Author

kachick commented Jun 4, 2024

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

@kachick kachick closed this as completed Jun 4, 2024
@kachick
Copy link
Owner Author

kachick commented Aug 26, 2024

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

@kachick
Copy link
Owner Author

kachick commented Aug 26, 2024

Ruby に関して

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

@kachick
Copy link
Owner Author

kachick commented Sep 11, 2024

割と長期に仕様検討が続いているからほんまに入るんかいなとちょっと不安にもなってたけど、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
Copy link
Owner Author

kachick commented Sep 11, 2024

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
Archived in project
Development

No branches or pull requests

1 participant