测试“进入”是不是成功的函数

Posted

技术标签:

【中文标题】测试“进入”是不是成功的函数【英文标题】:A Function to Test if `get-in` will Succeed测试“进入”是否成功的函数 【发布时间】:2020-12-25 06:46:25 【问题描述】:

在 Clojure/Script 中,contains? 函数可用于检查后续 get 是否会成功。我相信 Clojure 版本会在不检索值的情况下进行测试。 ClojureScript 版本使用get 并且确实检索该值。

是否有一个等效的函数可以测试get-in 使用的通过地图的路径是否会成功?那是在不检索值的情况下进行测试吗?

例如,这里有一个简单的 contains-in? 实现,类似于在进行测试时检索值的 ClojureScript 版本的 contains?。:

(def attrs :attrs :volume :default "loud"
                    :bass   nil
                    :treble :default nil)

(defn contains-in? [m ks]
  (let [sentinel (js-obj)]
    (if (identical? (get-in m ks sentinel) sentinel)
      false
      true)))

(defn needs-input? [attr-key]
  (not (contains-in? attrs [:attrs attr-key :default])))

(println "volume: needs-input?: " (needs-input? :volume))
(println "  bass: needs-input?: " (needs-input? :bass))
(println "treble: needs-input?: " (needs-input? :treble))

;=>volume: needs-input?:  false
;=>  bass: needs-input?:  true
;=>treble: needs-input?:  false

“属性”映射中不包含默认值的任何内容都需要用户输入。 (nil 是可接受的默认值,但缺失值不是。)

【问题讨论】:

你为什么要求“在没有检索值的情况下进行测试”?昂贵的部分是进行密钥查找;一旦你这样做了,就可以免费获得价值。 @amalloy:好奇。 Clojures 的实现似乎很麻烦,我只是想知道为什么。 用例是什么?如果只是为了防止丢失数据或键入错误的密钥,请在此处查看 grabfetchfetch-in 函数:cljdoc.org/d/tupelo/tupelo/20.08.27b/api/tupelo.core#fetch-in @Alan:用例与示例非常相似,但映射更深。一个人定义了一种文档类型,包括它必须具有、应该具有、不应该具有的特征等。其他人的任务是编写这些类型的文档。此处说明的步骤是创建一组可应用于第二组编写的文档的规则。除了验证之外,它还应该提供有用的错误消息和指导。 在这一点上感觉就像你正在重新发明 clojure.spec ......? 【参考方案1】:
(defn contains-in? [m ks]
  (let [ks (seq ks)]
    (or (nil? ks)
        (loop [m m, [k & ks] ks]
          (and (try
                 (contains? m k)
                 (catch IllegalArgumentException _ false))
               (or (nil? ks)
                   (recur (get m k) ks)))))))

顺便说一句,查看the source of clojure.lang.RT 中的相关函数,我注意到contains?get 在它们的第一个参数是字符串或Java 数组时的行为可能有点错误,如下图所示:

user=> (contains? "a" :a)
IllegalArgumentException contains? not supported on type: java.lang.String
user=> (contains? "a" 0.5)
true
user=> (get "a" 0.5)
\a
user=> (contains? (to-array [0]) :a)
IllegalArgumentException contains? not supported on type: [Ljava.lang.Object;
user=> (contains? (to-array [0]) 0.5)
true
user=> (get (to-array [0]) 0.5)
0
user=> (contains? [0] :a)
false
user=> (contains? [0] 0.5)
false
user=> (get [0] 0.5)
nil

【讨论】:

以上是关于测试“进入”是不是成功的函数的主要内容,如果未能解决你的问题,请参考以下文章

在 XCTest 中:如何测试函数是不是强制执行到主线程

Ajax 成功函数被忽略 - 代码仍在运行

PHP foreach循环里面调用函数,需要等函数返回成功才能进入下一次循环,怎么弄呢?

PHP判断sql语句是不是执行成功

qt测试线程是不是创建成功

如何测试我的 MySQL 更新查询在 CodeIgniter 中是不是成功? [复制]