Beispiel
Show that T::Struct.from_hash bypasses the runtime type enforcement that the .new constructor applies
sha256:49b3a0ec0dc911830c4cf62df5ff6bb54e1006a59d4d7830a843495fc1ee8400
PUBLISHED
L3_CONTRACT_PASS
MIT-0
Fall
- Ziel
- Show that T::Struct.from_hash bypasses the runtime type enforcement that the .new constructor applies HOW
- Pakete
- sorbet-runtime 0.6.13427
- Umgebung
- ruby
- Erstellt
- 2026-08-17T02:49:00Z
Häufige Annahme
Because T::Struct declares prop types and the .new constructor raises TypeError when a value does not match, from_hash — the documented deserialization path — applies the same check and raises on mismatched types.
So hat der Autor des Samples festgehalten, was eine Entwicklerin oder ein Modell hier erwarten würde. Der Vertrag darunter ist das, was tatsächlich lief.
Contract
- T::Struct.from_hash accepts a String value for a prop declared Integer and returns it unchanged without raising TypeError, while T::Struct.new raises TypeError for the identical input — proving that the deserialization path skips the sig-based check the constructor applies
- assert ConnectionRecord.from_hash('port' => '5432').port == '5432'
- assert ConnectionRecord.new(port: '5432') raises TypeError matching /Can't set ConnectionRecord\.port/
- assert from_hash with an unknown string key silently discards it rather than raising
- assert from_hash with symbol keys treats them as absent and raises RuntimeError about nil deserialization
- assert from_hash with Integer elements inside a T::Array[String] prop returns them unchanged — element types are not checked
Dateien
- Gemfile
- Gemfile.lock
- NOTES.md
- csx.json
- src/model.rb
- test/contract.rb
Verifiziertes Artefakt herunterladen (tar.gz) — genau die Bytes, gegen die der Contract lief
Ursprungs-Seeder
Verifizierungsbelege
- ruby 3 · CONTAINER_RUN · compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS · rubygems@1 · 2026-08-17 · ed25519:d91480838ac982c9