ClojureScript

For non-seqable types, seq evals to object info when running tests

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Patch:
    Code and Test
  • Approval:
    Accepted

Description

Observing on master and 1.9.946, and as far back as 1.7.28:

(require '[clojure.test :refer [deftest]])

(deftype FooSeq [])

(deftype BarSeq []
  ASeq)

(deftype BazSeq []
  ICounted (-count [_] 0)
  ISequential)

(defprotocol IFooSeq)

(deftype QuuxSeq []
  IFooSeq)

(deftest test-seq
  (prn (seqable? (->FooSeq)))
  (prn (seq (->FooSeq)))
  (prn (seqable? (->BarSeq)))
  (prn (seq (->BarSeq)))
  (prn (seqable? (->BazSeq)))
  (prn (seq (->BazSeq)))
  (prn (seqable? (->QuuxSeq)))
  (prn (seq (->QuuxSeq))))

If you do this in a REPL and call (test-seq) you will get the second test form throwing as expected:

cljs.user=> (test-seq)
false

ERROR in (test-seq) (Error:NaN:NaN)
Uncaught exception, not in assertion.
expected: nil
  actual: #object[Error Error: [object Object] is not ISeqable]
nil

Note that this also behaves properly if you are in a REPL and put this code in a namespace and load it via require while in the REPL:

Have src/foo/core.cljs containing

(ns foo.core
 (:require [clojure.test :refer [deftest]]))

(deftype FooSeq [])

(deftype BarSeq []
  ASeq)

(deftype BazSeq []
  ICounted (-count [_] 0)
  ISequential)

(defprotocol IFooSeq)

(deftype QuuxSeq []
  IFooSeq)

(deftest test-seq
  (prn (seqable? (->FooSeq)))
  (prn (seq (->FooSeq)))
  (prn (seqable? (->BarSeq)))
  (prn (seq (->BarSeq)))
  (prn (seqable? (->BazSeq)))
  (prn (seq (->BazSeq)))
  (prn (seqable? (->QuuxSeq)))
  (prn (seq (->QuuxSeq))))

and then try it at the REPL:

$ java -cp cljs.jar:src clojure.main -m cljs.repl.node
ClojureScript Node.js REPL server listening on 51614
To quit, type: :cljs/quit
cljs.user=> (require 'foo.core)
nil
cljs.user=> (foo.core/test-seq)
false

ERROR in (test-seq) (Error:NaN:NaN)
Uncaught exception, not in assertion.
expected: nil
  actual: #object[Error Error: [object Object] is not ISeqable]
nil

If instead you drop the code (apart from the require form) into the bottom of the cljs.core-test namespace (or, the top of cljs.primitives-test) and run script/test-simple or script/test-self-parity you will see some concerning output. Also note the odd true and false return values.

true
()
false
(["cljs$lang$protocol_mask$partition0$" 32] ["cljs$lang$protocol_mask$partition1$" 0])
false
(["cljs$lang$protocol_mask$partition0$" 16777218] ["cljs$lang$protocol_mask$partition1$" 0] ["cljs$core$ICounted$_count$arity$1" #object[Function]])
true
(["cljs$core_test$IFooSeq$" #js {}])

A simpler case is (prn (seq #js {:a 1 :b 2})) which will print

(["a" 1] ["b" 2])
.

Activity

Hide
Mike Fikes added a comment -

Root cause is this test intermixing with other things https://github.com/clojure/clojurescript/commit/009db3c7dc45d2a99afd5d89720bca7d2047219d

The reason I wrote this ticket was a result of one assertion in CLJS-2455 failing.

Show
Mike Fikes added a comment - Root cause is this test intermixing with other things https://github.com/clojure/clojurescript/commit/009db3c7dc45d2a99afd5d89720bca7d2047219d The reason I wrote this ticket was a result of one assertion in CLJS-2455 failing.
Hide
Mike Fikes added a comment -

Attached patch moves the manipulation of object to a separate namespace that is loaded last, and makes the manipulation occur at runtime.

Show
Mike Fikes added a comment - Attached patch moves the manipulation of object to a separate namespace that is loaded last, and makes the manipulation occur at runtime.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: