Clojure 函数先决条件不接受验证映射是否包含密钥

Clojure 函数先决条件不接受验证映射是否包含密钥,clojure,Clojure,我试图定义一个函数,它接收一对x-y坐标和机器人所面对的方向(:北、:东、:南和:西) 我定义了一个名为“方向”的地图,其中包含有效值(稍后将用于移动) 出于验证目的,我创建了一个:pre子句来防止这些参数的无效值: (defn create-robot "Creates a Robot representation, containing its position (x,y) and directions which it is facing" [x y direction] {

我试图定义一个函数,它接收一对x-y坐标和机器人所面对的方向(:北、:东、:南和:西)

我定义了一个名为“方向”的地图,其中包含有效值(稍后将用于移动)

出于验证目的,我创建了一个:pre子句来防止这些参数的无效值:

(defn create-robot 
  "Creates a Robot representation, containing its position (x,y) and directions which it is facing"
  [x y direction]
  {:pre [(int? x) (>= x 0)
         (int? y) (>= y 0)
         (contains? directions direction)]}
  (Robot. x y direction))
现在,问题来了:当我运行我的测试时,它失败了,是因为这个原因吗?验证。问题是,我正在为我的测试使用一个有效的值,但它仍然失败了

(let [robot (create-robot 1 2 :north)]
  (expect 1 (:x robot))
  (expect 2 (:y robot))
  (expect :north (:direction robot)))
它给了我以下错误:

Error refreshing environment: java.lang.AssertionError: Assert failed: (contains? directions direction)
有人能告诉我怎么了吗?我对先决条件的期望是否过高

谢谢,干杯

更新 根据@Alan Thompson的要求,我添加了一个println

结果如预期所示(这次测试通过除外):


我不明白它现在是如何工作的。

我从不使用
期望值
库。相反,我喜欢更方便一点的
clojure.test
。这是您的代码,它按预期工作:

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test) )

(defrecord Robot [x y direction])

(def directions {:north {:x 0 :y 1}
                 :east {:x 1 :y 0}
                 :south {:x 0 :y -1}
                 :west {:x -1 :y 0}})

(defn create-robot
  "Creates a Robot representation, containing its position (x,y) and directions which it is facing"
  [x y direction]
  {:pre [(int? x) (>= x 0)
         (int? y) (>= y 0)
         (contains? directions direction)]}
  (Robot. x y direction))

; Now, here's the problem: when I run my test, it fails because of this contains? validation. The thing is, I'm using a valid value for my test, still, it is failing.
(dotest
  (let [robot (create-robot 1 2 :north)]
    (is= 1 (spyx (:x robot)))
    (is= 2 (spyx (:y robot)))
    (is= :north (spyx (:direction robot)))))
spyx
仅打印到控制台,以直观地验证正在发生的情况:

-----------------------------------
   Clojure 1.10.1    Java 12.0.1
-----------------------------------

Testing tst.demo.core
(:x robot) => 1
(:y robot) => 2
(:direction robot) => :north

Ran 2 tests containing 3 assertions.
0 failures, 0 errors.

Passed all tests
Finished at 16:52:59.262 (run time: 0.054s)
不确定你第一次尝试时出了什么问题。请重试或尝试我的版本以获取更多信息


另外,您从未说过机器人类做什么。那是Java类吗?如果是这样,它可能是相关的。

您使用的
expect
是什么?另外,添加一些
println
语句将极大地澄清输入值。基本上,该测试仅证明使用正确的数据(x、y和方向)创建了记录。我会加上一些印刷品。但我不确定它是否有时间评估任何指令,因为它可能在进入函数之前抛出AssertionError。这可能是由于IDE问题。如果删除打印,它是否继续工作?另请注意,您可以只编写
(方向)
,而不是
包含?
。嗯@AlanThompson,不确定这是否是IDE问题。可能不会,因为我正在使用VSCode并在控制台上运行测试。但唯一重要的是它现在正在发挥作用。谢谢。我不确定是什么导致了这个问题。也许还有另外一个微妙的问题,我在打印时无意中纠正了,但没有注意到。Robot就是你在你的版本中所做的记录。
*************** Running tests ***************
:reloading (jaegers.domain jaegers.core jaegers.core-test)
:north
{:x 0, :y 1}
Contains? true
:north
{:x 0, :y 1}
Contains? true

Ran 18 tests containing 18 assertions in 5 msecs
0 failures, 0 errors.
Tests completed at 19:17:38.593
(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test) )

(defrecord Robot [x y direction])

(def directions {:north {:x 0 :y 1}
                 :east {:x 1 :y 0}
                 :south {:x 0 :y -1}
                 :west {:x -1 :y 0}})

(defn create-robot
  "Creates a Robot representation, containing its position (x,y) and directions which it is facing"
  [x y direction]
  {:pre [(int? x) (>= x 0)
         (int? y) (>= y 0)
         (contains? directions direction)]}
  (Robot. x y direction))

; Now, here's the problem: when I run my test, it fails because of this contains? validation. The thing is, I'm using a valid value for my test, still, it is failing.
(dotest
  (let [robot (create-robot 1 2 :north)]
    (is= 1 (spyx (:x robot)))
    (is= 2 (spyx (:y robot)))
    (is= :north (spyx (:direction robot)))))
-----------------------------------
   Clojure 1.10.1    Java 12.0.1
-----------------------------------

Testing tst.demo.core
(:x robot) => 1
(:y robot) => 2
(:direction robot) => :north

Ran 2 tests containing 3 assertions.
0 failures, 0 errors.

Passed all tests
Finished at 16:52:59.262 (run time: 0.054s)