2015-02-19 3 views
1

Я не могу поймать броски со второго рекурсивного вызова от map. По некоторым причинам исключения пузыри от (call-rec (first node)), но не от (map call-rec node).Тестирование бросков из рекурсии

Рассмотрим следующий пример:

(deftest recursion-test 
     (testing "Testing recursion throws" ;; => OK 
     (is (thrown? Exception 
        (map #(throw (Exception. "e") [:a :b]))))) 

     (testing "Testing throws from recursion lvl 1" ;; => OK 
     (is (thrown? 
      Exception 
      (letfn [(call-rec [node] 
         (cond 
         (vector? node) 
         (do 
          (throw (Exception. "e")) 
          (map call-rec node)) 
         :else 
         node))] 
       (call-rec [:one :two]))))) 

     (testing "Testing throws from map recursion lvl 2" ;; => FAILURE 
     (is (thrown? Exception 
        (letfn [(call-rec [node] 
           (cond 
           (vector? node) 
           (map call-rec node) 

           :else 
           (throw (Exception. "e")) 
           ))] 
         (call-rec [:one :two]))))) 

     (testing "Testing throws from first recursion lvl 2" ;; => OK 
     (is (thrown? Exception 
        (letfn [(call-rec [node] 
           (cond 
           (vector? node) 
           (call-rec (first node)) 

           :else 
           (throw (Exception. "e")) 
           ))] 
         (call-rec [:one :two])))))) 

ответ

3

Лень. Форма

(map call-rec node) 

создает ленивую последовательность, которая никогда не реализуется, поэтому никогда не будет возможности выбросить исключение. Попробуйте нетерпеливый вариант:

(mapv call-rec node) 

Или реализовать последовательность вне call-rec с помощью:

(doall (call-rec [:one :two])) 
+3

Также стоит отметить, что есть и другие ошибки в коде. Например: '(map # (throw (Exception." E ") [: a: b]))' должно быть '(map (fn [_] (throw (Исключение." E "))) [: a: b ]) '. 'map' с одним аргументом создаст преобразующий преобразователь в Clojure 1.7. – Jarlax

Смежные вопросы