Welcome! Please see the About page for a little more info on how this works.

+1 vote
in ClojureCLR by

I noticed a few behavioral differences between the CLR and JVM implementations of tools.namespace.

As an example, the following tests will pass in the JVM implementation and fail in the CLR implementation. In CLR, files-2 is empty and ::dir/time is an instant.

(ns clojure.tools.namespace.repl-test
  (:require [clojure.test :refer [deftest is]]
            [clojure.tools.namespace.dir :as dir]
            [clojure.tools.namespace.find :as find]
            [clojure.tools.namespace.repl :as repl]
            [clojure.tools.namespace.test-helpers :as help]))

(deftest t-repl-scan
  (let [dir        (help/create-temp-dir "t-repl-scan")
        _main-clj  (help/create-source dir 'example.main :clj '[example.one])
        _one-cljc  (help/create-source dir 'example.one :clj)
        _other-dir (help/create-temp-dir "t-repl-scan-other")
        files-1    (::dir/files (repl/scan {:platform find/clj}))
        files-2    (::dir/files (repl/scan {:platform find/clj}))]
    (is (not-empty files-1))
    (is (not-empty files-2))
    (is (= files-1 files-2))))

(deftest t-repl-scan-time
  (let [scan (repl/scan {:platform find/clj})]
    (is (integer? (::dir/time scan)))))

After discussing with other contributors, the question of intent came up and this test was proposed as something that correctly captures the intent of repl/scan. However, if this is the intended behavior, then a new problem arises as this test fails in the JVM implementation.

(deftest t-repl-scan
  (try
    (let [dir       (help/create-temp-dir "t-repl-scan")
          _main-clj (help/create-source dir 'example.main :clj '[example.one])
          _one-cljc (help/create-source dir 'example.one :clj)
          other-dir (help/create-temp-dir "t-repl-scan-other")
          _         (repl/set-refresh-dirs dir other-dir)
          scan1     (repl/scan {:platform find/clj})
          scan2     (repl/scan {:platform find/clj})
          files-1   (::dir/files scan1)
          files-2   (::dir/files scan2)]
      (is (= (count files-1) 2))
      (is (= (count files-2) 0)))
    (finally (repl/clear))))

A couple things I think would help here:
1. Flesh out the tools.namespace (JVM) test suite to capture all the intended behavior.
2. Realign clr.tools.namespace with tools.namespace.

Point 1 will provide a good baseline for point 2, as well as any other existing/future ports of tools.namespace and help prevent things from diverging in the future as changes are made.

Note

As of writing, repl/scan will throw an InvalidCastException on CLR. To fix this, replace clojure.tools.namespace.dir/modified-files with this:

(defn- modified-files [tracker files]
  (filter #(DateTime/op_LessThan ^DateTime (::time tracker System.DateTime/UnixEpoch) (.get_LastWriteTimeUtc ^FileSystemInfo %)) files))
by
After digging around in this, the majority of the discrepancies I'm seeing is due to the fact that FileInfo.Equals does not return true for objects that point to the same path. File objects on the JVM, however, will return true if they have the same path.

Because of this difference, FileInfo sets, maps, etc must be searched using FileInfo.FullName to edit these collections. dissoc, disj, conj, get won't always work when comparing two FileInfos.

Empirically based tests have been added on my tools.namespace fork: https://github.com/brandoncorrea/tools.namespace/tree/behavioral-tests

The tests above have been copied over and passed on my clr.tools.namespace fork:
https://github.com/brandoncorrea/clr.tools.namespace/tree/behavioral-tests
by
Didn't know that about FileInfo.Equals.  I'll work through the code with that in mind.  And I'll take a look at your behavorial tests.  It will take a day or two.
by
I went through the changes in your fork of clr.tools.namespace.   I've edited them into my local repo.  The tests are green.   That is some non-trivial sleuthing to find all that implicit equality checking.

What is the status of the tests on the JVM?
by
I wrote a passing test on the JVM first before porting it over to the CLR. So the tests on the JVM are all passing.
by
edited by
Is there more you think needs to be done?
I was about to announce a new release of clr.tools.namespace, just before you pointed out the problems you were seeing.  I could wrap your changes into the  release before I announce it.
by
I don't think anything more needs to be done. If there are any other discrepancies between CLR/JVM, they haven't surfaced themselves yet.

Please log in or register to answer this question.

...