Uploaded image for project: 'ClojureScript'
  1. CLJS-2457

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

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Completed
    • Affects versions: None
    • Fix versions: None
    • Labels:
      None
    • Approval:
      Accepted
    • Patch:
      Code and Test

      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])

      .

        Attachments

          Activity

            People

            • Assignee:
              dnolen David Nolen
              Reporter:
              mfikes Mike Fikes
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: