Describe the bug
wheels.tests.specs.model.bulkOperationsSpec asserts that the values returned from insertAll() / updateAll() / friends are of type "component". On BoxLang the assertion fails with:
The actual is of type [wheels.tests._assets.models.BulkItem] which is not the expected type of [component]
BoxLang reports the FQN of the class, not the generic component type that Lucee/Adobe use.
Evidence
Compat-matrix run #25837380625 (2026-05-13).
- 8 occurrences on BoxLang across
cockroachdb, mysql, postgres, sqlite.
- Plus a sibling cluster of 4 occurrences with
[wheels.tests._assets.models.Author] instead of BulkItem — same root cause.
- Lucee/Adobe pass cleanly.
- Affected suites (all in
bulkOperationsSpec): insertAll, updateAll, related — wherever expect(record).toBeTypeOf("component") appears.
To Reproduce
- Hit
/wheels/core/tests?db=sqlite&format=json&directory=tests.specs.model.bulkOperationsSpec on BoxLang.
- Any spec containing
toBeTypeOf("component") (or equivalent) on a model instance errors with the message above.
Expected behavior
The assertion should accept any Wheels model instance as "a Wheels component" regardless of how the underlying engine reflects the class metadata.
Root cause
CFML engines differ on how getMetadata(obj).type / WheelsTest's toBeTypeOf resolve class identity:
- Lucee / Adobe → returns
"component" for any CFC instance.
- BoxLang → returns the fully-qualified class name (e.g.
wheels.tests._assets.models.BulkItem).
The spec is using the wrong assertion shape for cross-engine work. There's no portable way to assert "this is a CFC" via the literal "component" string.
Suggested fix shape
Replace toBeTypeOf("component") with one of:
toBeInstanceOf("Model") — most semantically correct; checks against the Wheels Model base class.
expect(IsObject(record)).toBeTrue() — most permissive; just confirms it's an object.
expect(IsInstanceOf(record, "Model")).toBeTrue() — alternative shape.
Pure test edit — no framework changes. Estimated <10 minutes for one experienced contributor.
Additional context
Related: #2649
Describe the bug
wheels.tests.specs.model.bulkOperationsSpecasserts that the values returned frominsertAll()/updateAll()/ friends are of type"component". On BoxLang the assertion fails with:BoxLang reports the FQN of the class, not the generic
componenttype that Lucee/Adobe use.Evidence
Compat-matrix run #25837380625 (2026-05-13).
cockroachdb,mysql,postgres,sqlite.[wheels.tests._assets.models.Author]instead ofBulkItem— same root cause.bulkOperationsSpec):insertAll,updateAll, related — whereverexpect(record).toBeTypeOf("component")appears.To Reproduce
/wheels/core/tests?db=sqlite&format=json&directory=tests.specs.model.bulkOperationsSpecon BoxLang.toBeTypeOf("component")(or equivalent) on a model instance errors with the message above.Expected behavior
The assertion should accept any Wheels model instance as "a Wheels component" regardless of how the underlying engine reflects the class metadata.
Root cause
CFML engines differ on how
getMetadata(obj).type/ WheelsTest'stoBeTypeOfresolve class identity:"component"for any CFC instance.wheels.tests._assets.models.BulkItem).The spec is using the wrong assertion shape for cross-engine work. There's no portable way to assert "this is a CFC" via the literal
"component"string.Suggested fix shape
Replace
toBeTypeOf("component")with one of:toBeInstanceOf("Model")— most semantically correct; checks against the Wheels Model base class.expect(IsObject(record)).toBeTrue()— most permissive; just confirms it's an object.expect(IsInstanceOf(record, "Model")).toBeTrue()— alternative shape.Pure test edit — no framework changes. Estimated <10 minutes for one experienced contributor.
Additional context
getResponse()adapter issue in BoxLang: getStatusCode() throws — adapter getResponse() override breaks Base.cfc lookup #2659: engine-introspection APIs are not portable. Avoid assertions that depend on whatgetMetadata()returns; assert on behavior or useIsInstanceOfagainst the framework's base classes.IsInstanceOf(x, 'BaseClass')rather thangetMetadata(x).type == 'component'; the latter returns the FQN on BoxLang."Related: #2649