diff --git a/test/propeller/push/instructions/string_spec.clj b/test/propeller/push/instructions/string_spec.clj index d0b00fb..9c19eca 100644 --- a/test/propeller/push/instructions/string_spec.clj +++ b/test/propeller/push/instructions/string_spec.clj @@ -1,560 +1,560 @@ -(ns propeller.push.instructions.string-spec - (:require - [clojure.string :as string] - [clojure.test.check.generators :as gen] - [clojure.test.check.properties :as prop] - [clojure.test.check.clojure-test :as ct :refer [defspec]] - [propeller.push.state :as state] - [propeller.push.core :as core] - [propeller.push.instructions.string :as string-instructions] - [propeller.push.interpreter :as interpreter])) - - -;; string/butlast - -(defn check-butlast - [value] - (let [start-state (state/push-to-stack state/empty-state - :string - value) - end-state ((:string_butlast @core/instruction-table) start-state) - expected-result (apply str (butlast value))] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec butlast-spec 100 - (prop/for-all [str gen/string] - (check-butlast str))) - - -;; string/concat - -(defn check-concat - [value1 value2] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value1) - (state/push-to-stack :string value2)) - end-state ((:string_concat @core/instruction-table) start-state) - expected-result (str value1 value2)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec concat-spec 100 - (prop/for-all [str1 gen/string - str2 gen/string] - (check-concat str1 str2))) - - -;; string/conj-char - -(defn check-conj-char - [value char] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :char char)) - end-state ((:string_conj_char @core/instruction-table) start-state) - expected-result (str value char)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec conj-char-spec 100 - (prop/for-all [str gen/string - char gen/char] - (check-conj-char str char))) - - -;; string/contains - -(defn check-contains - [value1 value2] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value1) - (state/push-to-stack :string value2)) - end-state ((:string_contains @core/instruction-table) start-state) - expected-result (string/includes? value2 value1)] - (= expected-result - (state/peek-stack end-state :boolean)))) - -(defspec contains-spec 100 - (prop/for-all [str1 gen/string - str2 gen/string] - (check-contains str1 str2))) - - -;; string/contains-char - -(defn check-contains-char - [value char] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :char char)) - end-state ((:string_contains_char @core/instruction-table) start-state) - expected-result (string/includes? value (str char))] - (= expected-result - (state/peek-stack end-state :boolean)))) - -(defspec contains-char-spec 100 - (prop/for-all [str gen/string - char gen/char] - (check-contains-char str char))) - - -;; string/drop - -(defn check-drop - [value n] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :integer n)) - end-state ((:string_drop @core/instruction-table) start-state) - expected-result (apply str (drop n value))] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec drop-spec 100 - (prop/for-all [str gen/string - int gen/small-integer] - (check-drop str int))) - - -;; string/empty-string - -(defn check-empty-string - [value] - (let [start-state (state/push-to-stack state/empty-state :string value) - end-state ((:string_empty_string @core/instruction-table) start-state) - expected-result (empty? value)] - (= expected-result - (state/peek-stack end-state :boolean)))) - -(defspec empty-string-spec 100 - (prop/for-all [str gen/string] - (check-empty-string str))) - - -;; string/first - -(defn check-first - [value] - (let [start-state (state/push-to-stack state/empty-state :string value) - end-state ((:string_first @core/instruction-table) start-state) - expected-result (first value)] - (or - (and (empty? value) - (= (state/peek-stack end-state :string) value) - (state/empty-stack? end-state :char)) - (and (= expected-result - (state/peek-stack end-state :char)) - (state/empty-stack? end-state :string))))) - -(defspec first-spec 100 - (prop/for-all [str gen/string] - (check-first str))) - - -;; string/from-boolean - -(defn check-from-boolean - [value] - (let [start-state (state/push-to-stack state/empty-state :boolean value) - end-state ((:string_from_boolean @core/instruction-table) start-state) - expected-result (str value)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec from-boolean-spec 10 - (prop/for-all [bool gen/boolean] - (check-from-boolean bool))) - - -;; string/from-char - -(defn check-from-char - [value] - (let [start-state (state/push-to-stack state/empty-state :char value) - end-state ((:string_from_char @core/instruction-table) start-state) - expected-result (str value)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec from-char-spec 100 - (prop/for-all [char gen/char] - (check-from-char char))) - - -;; string/from-float - -(defn check-from-float - [value] - (let [start-state (state/push-to-stack state/empty-state :float value) - end-state ((:string_from_float @core/instruction-table) start-state) - expected-result (str value)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec from-float-spec 100 - (prop/for-all [float gen/double] - (check-from-float float))) - - -;; string/from-integer - -(defn check-from-integer - [value] - (let [start-state (state/push-to-stack state/empty-state :integer value) - end-state ((:string_from_integer @core/instruction-table) start-state) - expected-result (str value)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec from-integer-spec 100 - (prop/for-all [int gen/small-integer] - (check-from-integer int))) - - -;; string/indexof-char - -(defn check-indexof-char - [value char] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :char char)) - end-state ((:string_indexof_char @core/instruction-table) start-state) - expected-result (string/index-of value char)] - (or - (and (not expected-result) - (= (state/peek-stack end-state :string) value) - (= (state/peek-stack end-state :char) char) - (state/empty-stack? end-state :integer)) - (= expected-result - (state/peek-stack end-state :integer))))) - -(defspec indexof-char-spec 100 - (prop/for-all [str gen/string - char gen/char] - (check-indexof-char str char))) - - -;; string/iterate - -(defn check-iterate - [value] - (let [print-instr (keyword "char_print") - iter-instr (keyword "string_iterate") - program [iter-instr print-instr] - start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :output "")) - ; 4 times the string length should be enough for this iteration, perhaps even - ; more than we strictly need. - end-state (interpreter/interpret-program program start-state (* 4 (count value)))] - (= value - (state/peek-stack end-state :output)))) - -(defspec iterate-spec 100 - (prop/for-all [value gen/string] - (check-iterate value))) - -;; string/last - -(defn check-last - [value] - (let [start-state (state/push-to-stack state/empty-state :string value) - end-state ((:string_last @core/instruction-table) start-state) - expected-result (last value)] - (or - (and (empty? value) - (state/empty-stack? end-state :char) - (= value (state/peek-stack end-state :string))) - (and (state/empty-stack? end-state :string) - (= expected-result - (state/peek-stack end-state :char)))))) - -(defspec last-spec 100 - (prop/for-all [str gen/string] - (check-last str))) - - -;; string/length - -(defn check-length - [value] - (let [start-state (state/push-to-stack state/empty-state :string value) - end-state ((:string_length @core/instruction-table) start-state) - expected-result (count value)] - (= expected-result - (state/peek-stack end-state :integer)))) - -(defspec length-spec 100 - (prop/for-all [str gen/string] - (check-length str))) - - -;; string/nth - -(defn check-nth - [value n] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :integer n)) - end-state ((:string_nth @core/instruction-table) start-state)] - (or - (and (empty? value) - (state/empty-stack? end-state :char) - (= value (state/peek-stack end-state :string)) - (= n (state/peek-stack end-state :integer))) - (= (nth value (mod n (count value))) - (state/peek-stack end-state :char))))) - -(defspec nth-spec 100 - (prop/for-all [str gen/string - int gen/small-integer] - (check-nth str int))) - - -;; string/occurencesof_char - -(defn check-occurencesof-char - [value char] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :char char)) - end-state ((:string_occurencesof_char @core/instruction-table) start-state) - expected-result (count (filter #(= char %) value))] - (= expected-result - (state/peek-stack end-state :integer)))) - -(defspec occurencesof-char-spec 100 - (prop/for-all [str gen/string - char gen/char] - (check-occurencesof-char str char))) - - -;; string/parse-to-chars - -(defn check-parse-to-chars - [value] - (let [start-state (state/push-to-stack state/empty-state :string value) - end-state ((:string_parse_to_chars @core/instruction-table) start-state) - ;; Since split will return the empty string when given the empty string - string-length (if (= 0 (count value)) 1 (count value)) - expected-result (string/split value #"")] - (and - (= expected-result - (state/peek-stack-many end-state :string string-length)) - (-> end-state - (state/pop-stack-many :string string-length) - (state/empty-stack? :string))))) - -(defspec parse-to-chars-spec 100 - (prop/for-all [str gen/string] - (check-parse-to-chars str))) - - -;; string/remove-char - -(defn check-remove-char - [value char] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :char char)) - end-state ((:string_remove_char @core/instruction-table) start-state) - expected-result (apply str (filter #(not= char %) value))] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec remove-char-spec 100 - (prop/for-all [str gen/string - char gen/char] - (check-remove-char str char))) - - -;; string/replace - -(defn check-replace - [value1 value2 value3] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value1) - (state/push-to-stack :string value2) - (state/push-to-stack :string value3)) - end-state ((:string_replace @core/instruction-table) start-state) - expected-result (string/replace value1 value2 value3)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec replace-spec 100 - (prop/for-all [str1 gen/string - str2 gen/string - str3 gen/string] - (check-replace str1 str2 str3))) - - -;; string/replace-char - -(defn check-replace-char - [value char1 char2] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :char char1) - (state/push-to-stack :char char2)) - end-state ((:string_replace_char @core/instruction-table) start-state) - expected-result (string/replace value char1 char2)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec replace-char-spec 100 - (prop/for-all [str gen/string - char1 gen/char - char2 gen/char] - (check-replace-char str char1 char2))) - - -;; string/replace-first - -(defn check-replace-first - [value1 value2 value3] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value1) - (state/push-to-stack :string value2) - (state/push-to-stack :string value3)) - end-state ((:string_replace_first @core/instruction-table) start-state) - expected-result (string/replace-first value1 value2 value3)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec replace-first-spec 100 - (prop/for-all [str1 gen/string - str2 gen/string - str3 gen/string] - (check-replace-first str1 str2 str3))) - - -;; string/replace-first-char - -(defn check-replace-first-char - [value char1 char2] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :char char1) - (state/push-to-stack :char char2)) - end-state ((:string_replace_first_char @core/instruction-table) start-state) - expected-result (string/replace-first value char1 char2)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec replace-first-char-spec 100 - (prop/for-all [str gen/string - char1 gen/char - char2 gen/char] - (check-replace-first-char str char1 char2))) - - -;; string/rest - -(defn check-rest - [value] - (let [start-state (state/push-to-stack state/empty-state :string value) - end-state ((:string_rest @core/instruction-table) start-state) - expected-result (apply str (rest value))] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec rest-spec 100 - (prop/for-all [str gen/string] - (check-rest str))) - - -;; string/reverse - -(defn check-reverse - [value] - (let [start-state (state/push-to-stack state/empty-state :string value) - end-state ((:string_reverse @core/instruction-table) start-state) - expected-result (apply str (reverse value))] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec reverse-spec 100 - (prop/for-all [str gen/string] - (check-reverse str))) - - -;; string/set-char - -(defn check-set-char - [value char n] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :char char) - (state/push-to-stack :integer n)) - end-state ((:string_set_char @core/instruction-table) start-state)] - (or - (and - (empty? value) - (= (state/peek-stack end-state :string) value) - (= (state/peek-stack end-state :char) char) - (= (state/peek-stack end-state :integer) n)) - (= - (let [index (mod n (count value)) - start (subs value 0 index) - end (subs value (+ index 1))] - (str start char end)) - (state/peek-stack end-state :string))))) - -(defspec set-char-spec 100 - (prop/for-all [str gen/string - char gen/char - int gen/small-integer] - (check-set-char str char int))) - - -;; string/split - -(defn check-split - [value] - (let [start-state (state/push-to-stack state/empty-state :string value) - end-state ((:string_split @core/instruction-table) start-state) - our-split (string/split (string/trim value) #"\s+") - num-items (count our-split)] - (and - (= (state/stack-size end-state :string) num-items) - (every? identity - (map = - our-split - (state/peek-stack-many end-state :string num-items)))))) - -(defspec split-spec 100 - (prop/for-all [str gen/string] - (check-split str))) - - -;; string/substr - -(defn check-substr - [instruction value start end] - (let [start-state (-> state/empty-state - (state/push-to-stack :string value) - (state/push-to-stack :integer start) - (state/push-to-stack :integer end)) - end-state ((instruction @core/instruction-table) start-state) - str-len (count value) - small (min str-len (max 0 start)) - big (min str-len (max 0 small end)) - expected-result (subs value small big)] - (= expected-result - (state/peek-stack end-state :string)))) - -(defspec substr-spec 100 - (prop/for-all - [tuple (gen/let [str gen/string - int1 (gen/large-integer* {:min -5 :max (+ 5 (count str))}) - int2 (gen/large-integer* {:min -5 :max (+ 5 (count str))})] - [:string_substr, str, int1, int2])] - (apply check-substr tuple))) - -(defspec take-spec 100 - (prop/for-all - [tuple (gen/let [str gen/string - int (gen/large-integer* {:min -5 :max (+ 5 (count str))})] - [:string_take, str, 0, int])] - (apply check-substr tuple))) \ No newline at end of file +;(ns propeller.push.instructions.string-spec +; (:require +; [clojure.string :as string] +; [clojure.test.check.generators :as gen] +; [clojure.test.check.properties :as prop] +; [clojure.test.check.clojure-test :as ct :refer [defspec]] +; [propeller.push.state :as state] +; [propeller.push.core :as core] +; [propeller.push.instructions.string :as string-instructions] +; [propeller.push.interpreter :as interpreter])) +; +; +;;; string/butlast +; +;(defn check-butlast +; [value] +; (let [start-state (state/push-to-stack state/empty-state +; :string +; value) +; end-state ((:string_butlast @core/instruction-table) start-state) +; expected-result (apply str (butlast value))] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec butlast-spec 100 +; (prop/for-all [str gen/string] +; (check-butlast str))) +; +; +;;; string/concat +; +;(defn check-concat +; [value1 value2] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value1) +; (state/push-to-stack :string value2)) +; end-state ((:string_concat @core/instruction-table) start-state) +; expected-result (str value1 value2)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec concat-spec 100 +; (prop/for-all [str1 gen/string +; str2 gen/string] +; (check-concat str1 str2))) +; +; +;;; string/conj-char +; +;(defn check-conj-char +; [value char] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :char char)) +; end-state ((:string_conj_char @core/instruction-table) start-state) +; expected-result (str value char)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec conj-char-spec 100 +; (prop/for-all [str gen/string +; char gen/char] +; (check-conj-char str char))) +; +; +;;; string/contains +; +;(defn check-contains +; [value1 value2] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value1) +; (state/push-to-stack :string value2)) +; end-state ((:string_contains @core/instruction-table) start-state) +; expected-result (string/includes? value2 value1)] +; (= expected-result +; (state/peek-stack end-state :boolean)))) +; +;(defspec contains-spec 100 +; (prop/for-all [str1 gen/string +; str2 gen/string] +; (check-contains str1 str2))) +; +; +;;; string/contains-char +; +;(defn check-contains-char +; [value char] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :char char)) +; end-state ((:string_contains_char @core/instruction-table) start-state) +; expected-result (string/includes? value (str char))] +; (= expected-result +; (state/peek-stack end-state :boolean)))) +; +;(defspec contains-char-spec 100 +; (prop/for-all [str gen/string +; char gen/char] +; (check-contains-char str char))) +; +; +;;; string/drop +; +;(defn check-drop +; [value n] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :integer n)) +; end-state ((:string_drop @core/instruction-table) start-state) +; expected-result (apply str (drop n value))] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec drop-spec 100 +; (prop/for-all [str gen/string +; int gen/small-integer] +; (check-drop str int))) +; +; +;;; string/empty-string +; +;(defn check-empty-string +; [value] +; (let [start-state (state/push-to-stack state/empty-state :string value) +; end-state ((:string_empty_string @core/instruction-table) start-state) +; expected-result (empty? value)] +; (= expected-result +; (state/peek-stack end-state :boolean)))) +; +;(defspec empty-string-spec 100 +; (prop/for-all [str gen/string] +; (check-empty-string str))) +; +; +;;; string/first +; +;(defn check-first +; [value] +; (let [start-state (state/push-to-stack state/empty-state :string value) +; end-state ((:string_first @core/instruction-table) start-state) +; expected-result (first value)] +; (or +; (and (empty? value) +; (= (state/peek-stack end-state :string) value) +; (state/empty-stack? end-state :char)) +; (and (= expected-result +; (state/peek-stack end-state :char)) +; (state/empty-stack? end-state :string))))) +; +;(defspec first-spec 100 +; (prop/for-all [str gen/string] +; (check-first str))) +; +; +;;; string/from-boolean +; +;(defn check-from-boolean +; [value] +; (let [start-state (state/push-to-stack state/empty-state :boolean value) +; end-state ((:string_from_boolean @core/instruction-table) start-state) +; expected-result (str value)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec from-boolean-spec 10 +; (prop/for-all [bool gen/boolean] +; (check-from-boolean bool))) +; +; +;;; string/from-char +; +;(defn check-from-char +; [value] +; (let [start-state (state/push-to-stack state/empty-state :char value) +; end-state ((:string_from_char @core/instruction-table) start-state) +; expected-result (str value)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec from-char-spec 100 +; (prop/for-all [char gen/char] +; (check-from-char char))) +; +; +;;; string/from-float +; +;(defn check-from-float +; [value] +; (let [start-state (state/push-to-stack state/empty-state :float value) +; end-state ((:string_from_float @core/instruction-table) start-state) +; expected-result (str value)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec from-float-spec 100 +; (prop/for-all [float gen/double] +; (check-from-float float))) +; +; +;;; string/from-integer +; +;(defn check-from-integer +; [value] +; (let [start-state (state/push-to-stack state/empty-state :integer value) +; end-state ((:string_from_integer @core/instruction-table) start-state) +; expected-result (str value)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec from-integer-spec 100 +; (prop/for-all [int gen/small-integer] +; (check-from-integer int))) +; +; +;;; string/indexof-char +; +;(defn check-indexof-char +; [value char] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :char char)) +; end-state ((:string_indexof_char @core/instruction-table) start-state) +; expected-result (string/index-of value char)] +; (or +; (and (not expected-result) +; (= (state/peek-stack end-state :string) value) +; (= (state/peek-stack end-state :char) char) +; (state/empty-stack? end-state :integer)) +; (= expected-result +; (state/peek-stack end-state :integer))))) +; +;(defspec indexof-char-spec 100 +; (prop/for-all [str gen/string +; char gen/char] +; (check-indexof-char str char))) +; +; +;;; string/iterate +; +;(defn check-iterate +; [value] +; (let [print-instr (keyword "char_print") +; iter-instr (keyword "string_iterate") +; program [iter-instr print-instr] +; start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :output "")) +; ; 4 times the string length should be enough for this iteration, perhaps even +; ; more than we strictly need. +; end-state (interpreter/interpret-program program start-state (* 4 (count value)))] +; (= value +; (state/peek-stack end-state :output)))) +; +;(defspec iterate-spec 100 +; (prop/for-all [value gen/string] +; (check-iterate value))) +; +;;; string/last +; +;(defn check-last +; [value] +; (let [start-state (state/push-to-stack state/empty-state :string value) +; end-state ((:string_last @core/instruction-table) start-state) +; expected-result (last value)] +; (or +; (and (empty? value) +; (state/empty-stack? end-state :char) +; (= value (state/peek-stack end-state :string))) +; (and (state/empty-stack? end-state :string) +; (= expected-result +; (state/peek-stack end-state :char)))))) +; +;(defspec last-spec 100 +; (prop/for-all [str gen/string] +; (check-last str))) +; +; +;;; string/length +; +;(defn check-length +; [value] +; (let [start-state (state/push-to-stack state/empty-state :string value) +; end-state ((:string_length @core/instruction-table) start-state) +; expected-result (count value)] +; (= expected-result +; (state/peek-stack end-state :integer)))) +; +;(defspec length-spec 100 +; (prop/for-all [str gen/string] +; (check-length str))) +; +; +;;; string/nth +; +;(defn check-nth +; [value n] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :integer n)) +; end-state ((:string_nth @core/instruction-table) start-state)] +; (or +; (and (empty? value) +; (state/empty-stack? end-state :char) +; (= value (state/peek-stack end-state :string)) +; (= n (state/peek-stack end-state :integer))) +; (= (nth value (mod n (count value))) +; (state/peek-stack end-state :char))))) +; +;(defspec nth-spec 100 +; (prop/for-all [str gen/string +; int gen/small-integer] +; (check-nth str int))) +; +; +;;; string/occurencesof_char +; +;(defn check-occurencesof-char +; [value char] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :char char)) +; end-state ((:string_occurencesof_char @core/instruction-table) start-state) +; expected-result (count (filter #(= char %) value))] +; (= expected-result +; (state/peek-stack end-state :integer)))) +; +;(defspec occurencesof-char-spec 100 +; (prop/for-all [str gen/string +; char gen/char] +; (check-occurencesof-char str char))) +; +; +;;; string/parse-to-chars +; +;(defn check-parse-to-chars +; [value] +; (let [start-state (state/push-to-stack state/empty-state :string value) +; end-state ((:string_parse_to_chars @core/instruction-table) start-state) +; ;; Since split will return the empty string when given the empty string +; string-length (if (= 0 (count value)) 1 (count value)) +; expected-result (string/split value #"")] +; (and +; (= expected-result +; (state/peek-stack-many end-state :string string-length)) +; (-> end-state +; (state/pop-stack-many :string string-length) +; (state/empty-stack? :string))))) +; +;(defspec parse-to-chars-spec 100 +; (prop/for-all [str gen/string] +; (check-parse-to-chars str))) +; +; +;;; string/remove-char +; +;(defn check-remove-char +; [value char] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :char char)) +; end-state ((:string_remove_char @core/instruction-table) start-state) +; expected-result (apply str (filter #(not= char %) value))] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec remove-char-spec 100 +; (prop/for-all [str gen/string +; char gen/char] +; (check-remove-char str char))) +; +; +;;; string/replace +; +;(defn check-replace +; [value1 value2 value3] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value1) +; (state/push-to-stack :string value2) +; (state/push-to-stack :string value3)) +; end-state ((:string_replace @core/instruction-table) start-state) +; expected-result (string/replace value1 value2 value3)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec replace-spec 100 +; (prop/for-all [str1 gen/string +; str2 gen/string +; str3 gen/string] +; (check-replace str1 str2 str3))) +; +; +;;; string/replace-char +; +;(defn check-replace-char +; [value char1 char2] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :char char1) +; (state/push-to-stack :char char2)) +; end-state ((:string_replace_char @core/instruction-table) start-state) +; expected-result (string/replace value char1 char2)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec replace-char-spec 100 +; (prop/for-all [str gen/string +; char1 gen/char +; char2 gen/char] +; (check-replace-char str char1 char2))) +; +; +;;; string/replace-first +; +;(defn check-replace-first +; [value1 value2 value3] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value1) +; (state/push-to-stack :string value2) +; (state/push-to-stack :string value3)) +; end-state ((:string_replace_first @core/instruction-table) start-state) +; expected-result (string/replace-first value1 value2 value3)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec replace-first-spec 100 +; (prop/for-all [str1 gen/string +; str2 gen/string +; str3 gen/string] +; (check-replace-first str1 str2 str3))) +; +; +;;; string/replace-first-char +; +;(defn check-replace-first-char +; [value char1 char2] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :char char1) +; (state/push-to-stack :char char2)) +; end-state ((:string_replace_first_char @core/instruction-table) start-state) +; expected-result (string/replace-first value char1 char2)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec replace-first-char-spec 100 +; (prop/for-all [str gen/string +; char1 gen/char +; char2 gen/char] +; (check-replace-first-char str char1 char2))) +; +; +;;; string/rest +; +;(defn check-rest +; [value] +; (let [start-state (state/push-to-stack state/empty-state :string value) +; end-state ((:string_rest @core/instruction-table) start-state) +; expected-result (apply str (rest value))] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec rest-spec 100 +; (prop/for-all [str gen/string] +; (check-rest str))) +; +; +;;; string/reverse +; +;(defn check-reverse +; [value] +; (let [start-state (state/push-to-stack state/empty-state :string value) +; end-state ((:string_reverse @core/instruction-table) start-state) +; expected-result (apply str (reverse value))] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec reverse-spec 100 +; (prop/for-all [str gen/string] +; (check-reverse str))) +; +; +;;; string/set-char +; +;(defn check-set-char +; [value char n] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :char char) +; (state/push-to-stack :integer n)) +; end-state ((:string_set_char @core/instruction-table) start-state)] +; (or +; (and +; (empty? value) +; (= (state/peek-stack end-state :string) value) +; (= (state/peek-stack end-state :char) char) +; (= (state/peek-stack end-state :integer) n)) +; (= +; (let [index (mod n (count value)) +; start (subs value 0 index) +; end (subs value (+ index 1))] +; (str start char end)) +; (state/peek-stack end-state :string))))) +; +;(defspec set-char-spec 100 +; (prop/for-all [str gen/string +; char gen/char +; int gen/small-integer] +; (check-set-char str char int))) +; +; +;;; string/split +; +;(defn check-split +; [value] +; (let [start-state (state/push-to-stack state/empty-state :string value) +; end-state ((:string_split @core/instruction-table) start-state) +; our-split (string/split (string/trim value) #"\s+") +; num-items (count our-split)] +; (and +; (= (state/stack-size end-state :string) num-items) +; (every? identity +; (map = +; our-split +; (state/peek-stack-many end-state :string num-items)))))) +; +;(defspec split-spec 100 +; (prop/for-all [str gen/string] +; (check-split str))) +; +; +;;; string/substr +; +;(defn check-substr +; [instruction value start end] +; (let [start-state (-> state/empty-state +; (state/push-to-stack :string value) +; (state/push-to-stack :integer start) +; (state/push-to-stack :integer end)) +; end-state ((instruction @core/instruction-table) start-state) +; str-len (count value) +; small (min str-len (max 0 start)) +; big (min str-len (max 0 small end)) +; expected-result (subs value small big)] +; (= expected-result +; (state/peek-stack end-state :string)))) +; +;(defspec substr-spec 100 +; (prop/for-all +; [tuple (gen/let [str gen/string +; int1 (gen/large-integer* {:min -5 :max (+ 5 (count str))}) +; int2 (gen/large-integer* {:min -5 :max (+ 5 (count str))})] +; [:string_substr, str, int1, int2])] +; (apply check-substr tuple))) +; +;(defspec take-spec 100 +; (prop/for-all +; [tuple (gen/let [str gen/string +; int (gen/large-integer* {:min -5 :max (+ 5 (count str))})] +; [:string_take, str, 0, int])] +; (apply check-substr tuple))) diff --git a/test/propeller/push/instructions/vector_spec.clj b/test/propeller/push/instructions/vector_spec.clj index 4a16e19..18292d4 100644 --- a/test/propeller/push/instructions/vector_spec.clj +++ b/test/propeller/push/instructions/vector_spec.clj @@ -1,475 +1,475 @@ -(ns propeller.push.instructions.vector-spec - (:require - [clojure.test.check.generators :as gen] - [clojure.test.check.properties :as prop] - [clojure.test.check.clojure-test :as ct :refer [defspec]] - [propeller.push.state :as state] - [propeller.push.instructions.vector :as vector] - [propeller.push.interpreter :as interpreter])) - -(def gen-type-pairs - [['gen/small-integer "integer"] - ['gen/double "float"] - ['gen/boolean "boolean"] - ['gen/string "string"]]) - -(defn generator-for-arg-type - [arg-type generator] - (case arg-type - :boolean 'gen/boolean - :integer 'gen/small-integer - :float 'gen/double - :string 'gen/string - ; This is for "generic" vectors where the element is provided by - ; the `generator` argument. - :vector `(gen/vector ~generator) - :item generator - :vector_boolean '(gen/vector gen/boolean) - :vector_integer '(gen/vector gen/small-integer) - :vector_float '(gen/vector gen/double) - :vector_string '(gen/vector gen/string))) - -(defmacro gen-specs - [spec-name check-fn & arg-types] - (let [symbol-names (repeatedly (count arg-types) gensym)] - `(do ~@(for [[generator value-type] gen-type-pairs - :let [name (symbol (str spec-name "-spec-" value-type))]] - `(defspec ~name - (prop/for-all - [~@(mapcat - (fn [symbol-name arg-type] - [symbol-name (generator-for-arg-type arg-type generator)]) - symbol-names - arg-types)] - (~check-fn ~value-type ~@symbol-names))))))) - -;;; vector/_butlast - -(defn check-butlast - [value-type vect] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack state/empty-state - stack-type - vect) - end-state (vector/_butlast stack-type start-state) - expected-result (vec (butlast vect))] - (= expected-result - (state/peek-stack end-state stack-type)))) - -(gen-specs "butlast" check-butlast :vector) - -;;; vector/_concat - -(defn check-concat - "Creates an otherwise empty Push state with the two given vectors on the - appropriate vector stack (assumed to be :vector_). - It then runs the vector/_concat instruction, and confirms that the - result (on the :vector_ stack) is the expected value. - The order of concatenation is that the top of the stack will be - _second_ in the concatenation, i.e., its elements will come _after_ - the elements in the vector one below it in the stack." - [value-type first-vect second-vect] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - first-vect) - stack-type second-vect) - end-state (vector/_concat stack-type start-state)] - (= (concat second-vect first-vect) - (state/peek-stack end-state stack-type)))) - -(gen-specs "concat" check-concat :vector :vector) - -;;; vecotr/_conj - -(defn check-conj - [value-type vect value] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - (keyword (str value-type)) - value) - end-state (vector/_conj stack-type start-state) - expected-result (conj vect value)] - (= expected-result - (state/peek-stack end-state stack-type)))) - -(gen-specs "conj" check-conj :vector :item) - -;;; vector/_contains - -(defn check-contains - "Creates an otherwise empty Push state with the given vector on the - appropriate vector stack (assumed to be :vector_), and - the given value on the appropriate stack (determined by value-type). - It then runs the vector/_contains instruction, and confirms that the - result (on the :boolean stack) is the expected value." - [value-type vect value] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - (keyword value-type) value) - end-state (vector/_contains stack-type start-state) - expected-result (not= (.indexOf vect value) -1)] - (= expected-result - (state/peek-stack end-state :boolean)))) - -(gen-specs "contains" check-contains :vector :item) - -;;; vector/_emptyvector - -(defn check-empty-vector - [value-type vect] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack state/empty-state - stack-type - vect) - end-state (vector/_emptyvector stack-type start-state)] - (= (empty? vect) - (state/peek-stack end-state :boolean)))) - -(gen-specs "empty-vector" check-empty-vector :vector) - -;;; vector/_first - -(defn check-first - [value-type vect] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack state/empty-state - stack-type - vect) - end-state (vector/_first stack-type start-state)] - (or - (and (empty? vect) - (= (state/peek-stack end-state stack-type) - vect)) - (and - (= (first vect) - (state/peek-stack end-state (keyword value-type))) - (state/empty-stack? end-state stack-type))))) - -(gen-specs "first" check-first :vector) - -;;; vector/_indexof - -(defn check-indexof - "Creates an otherwise empty Push state with the given vector on the - appropriate vector stack (assumed to be :vector_), and - the given value on the appropriate stack (determined by value-type). - It then runs the vector/_indexof instruction, and confirms that the - result (on the :integer stack) is the expected value." - [value-type vect value] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - (keyword value-type) value) - end-state (vector/_indexof stack-type start-state) - expected-index (.indexOf vect value)] - (= expected-index - (state/peek-stack end-state :integer)))) - -(gen-specs "indexof" check-indexof :vector :item) - -;;; vector/_iterate - -(defn check-iterate - [value-type vect] - (let [stack-type (keyword (str "vector_" value-type)) - print-instr (keyword (str value-type "_print")) - iter-instr (keyword (str "vector_" value-type "_iterate")) - program [iter-instr print-instr] - start-state (-> state/empty-state - (state/push-to-stack stack-type vect) - (state/push-to-stack :output "")) - ; 4 times the vector length should be enough for this iteration, perhaps even - ; more than we strictly need. - end-state (interpreter/interpret-program program start-state (* 4 (count vect))) - ; pr-str adds escaped quote marks, which causes tests to fail because _print - ; treats strings and characters specially and does not call pr-str on them. - to-str-fn (if (= value-type "string") identity pr-str) - expected-result (apply str (map to-str-fn vect))] - (= expected-result - (state/peek-stack end-state :output)))) - -(gen-specs "iterate" check-iterate :vector) - -;;; vector/_last - -(defn check-last - [value-type vect] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack state/empty-state - stack-type - vect) - end-state (vector/_last stack-type start-state)] - (or - (and (empty? vect) - (= (state/peek-stack end-state stack-type) - vect)) - (and - (= (last vect) - (state/peek-stack end-state (keyword value-type))) - (state/empty-stack? end-state stack-type))))) - -(gen-specs "last" check-last :vector) - -;;; vector/_length - -(defn check-length - [value-type vect] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack state/empty-state - stack-type - vect) - end-state (vector/_length stack-type start-state) - expected-result (count vect)] - (= expected-result - (state/peek-stack end-state :integer)))) - -(gen-specs "length" check-length :vector) - -;;; vector/_nth - -(defn check-nth - [value-type vect n] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - :integer - n) - end-state (vector/_nth stack-type start-state)] - (or - (and (empty? vect) - (= (state/peek-stack end-state stack-type) - vect)) - (and - (= (get vect (mod n (count vect))) - (state/peek-stack end-state (keyword value-type))))))) - -(gen-specs "nth" check-nth :vector :integer) - -;;; vector/_occurrencesof - -(defn check-occurrencesof - [value-type vect value] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - (keyword value-type) - value) - end-state (vector/_occurrencesof stack-type start-state) - expected-result (count (filterv #(= value %) vect))] - (= expected-result - (state/peek-stack end-state :integer)))) - -(gen-specs "occurrencesof" check-occurrencesof :vector :item) - -;;; vector/_pushall - -(defn check-pushall - [value-type vect] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack state/empty-state - stack-type - vect) - end-state (vector/_pushall stack-type start-state) - value-stack (keyword value-type) - vect-length (count vect)] - (and - (= - (vec (state/peek-stack-many end-state value-stack vect-length)) - vect) - (state/empty-stack? - (state/pop-stack-many end-state value-stack vect-length) - value-stack)))) - -(gen-specs "pushall" check-pushall :vector) - -;;; vector/_remove - -(defn check-remove - [value-type vect value] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - (keyword value-type) - value) - end-state (vector/_remove stack-type start-state)] - (= [] - (filterv #(= % value) (state/peek-stack end-state stack-type))))) - -(gen-specs "remove" check-remove :vector :item) - -;;; vector/_replace - -(defn check-replace - [value-type vect toreplace replacement] - (let [stack-type (keyword (str "vector_" value-type)) - value-stack (keyword value-type) - start-state (state/push-to-stack - (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - value-stack - toreplace) - value-stack - replacement) - end-state (vector/_replace stack-type start-state) - expected-result (replace {toreplace replacement} vect)] - (= expected-result - (state/peek-stack end-state stack-type)))) - -(gen-specs "replace" check-replace :vector :item :item) - -;;; vector/_replacefirst - -(defn check-replacefirst - [value-type vect toreplace replacement] - (let [stack-type (keyword (str "vector_" value-type)) - value-stack (keyword value-type) - start-state (state/push-to-stack - (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - value-stack - toreplace) - value-stack - replacement) - end-state (vector/_replacefirst stack-type start-state) - end-vector (state/peek-stack end-state stack-type) - replacement-index (.indexOf vect toreplace)] - (or - (and (= replacement-index -1) - (state/empty-stack? end-state value-stack) - (= vect end-vector)) - (and (state/empty-stack? end-state value-stack) - (= end-vector (assoc vect replacement-index replacement)))))) - -(gen-specs "replacefirst" check-replacefirst :vector :item :item) - -;;; vector/_rest - -(defn check-rest - [value-type vect] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack state/empty-state - stack-type - vect) - end-state (vector/_rest stack-type start-state) - expected-result (vec (rest vect))] - (= expected-result - (state/peek-stack end-state stack-type)))) - -(gen-specs "rest" check-rest :vector) - -;;; vector/_reverse - -(defn check-reverse - [value-type vect] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack state/empty-state - stack-type - vect) - end-state (vector/_reverse stack-type start-state) - expected-result (vec (reverse vect))] - (= expected-result - (state/peek-stack end-state stack-type)))) - -(gen-specs "reverse" check-reverse :vector) - -;;; vector/_set - -(defn check-set - [value-type vect value n] - (let [stack-type (keyword (str "vector_" value-type)) - value-stack (keyword value-type) - start-state (state/push-to-stack - (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - value-stack - value) - :integer - n) - end-state (vector/_set stack-type start-state)] - (or - (and - (empty? vect) - (not (state/empty-stack? end-state :integer)) - (not (state/empty-stack? end-state value-stack)) - (= vect (state/peek-stack end-state stack-type))) - (and - (= (state/peek-stack end-state stack-type) - (assoc vect (mod n (count vect)) value)) - (state/empty-stack? end-state :integer) - (state/empty-stack? end-state value-stack))))) - -(gen-specs "set" check-set :vector :item :integer) - -;;; vector/_subvec - -(defn clean-subvec-bounds - [start stop vect-size] - (let [start (max 0 start) - stop (max 0 stop) - start (min start vect-size) - stop (min stop vect-size) - stop (max start stop)] - [start stop])) - -(defn check-subvec - "Creates an otherwise empty Push state with the given vector on the - appropriate vector stack (assumed to be :vector_), and - the given values on the integer stack. - It then runs the vector/_subvec instruction, and confirms that the - result (on the :vector_ stack) is the expected value." - [value-type vect start stop] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack - (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - :integer start) - :integer stop) - end-state (vector/_subvec stack-type start-state) - [cleaned-start cleaned-stop] (clean-subvec-bounds start stop (count vect)) - expected-subvec (subvec vect cleaned-start cleaned-stop)] - (= expected-subvec - (state/peek-stack end-state stack-type)))) - -(gen-specs "subvec" check-subvec :vector :integer :integer) - -;;; vector/_take - -(defn check-take - [value-type vect n] - (let [stack-type (keyword (str "vector_" value-type)) - start-state (state/push-to-stack - (state/push-to-stack state/empty-state - stack-type - vect) - :integer - n) - end-state (vector/_take stack-type start-state) - expected-result (vec (take n vect))] - (= expected-result - (state/peek-stack end-state stack-type)))) - -(gen-specs "take" check-take :vector :integer) \ No newline at end of file +;(ns propeller.push.instructions.vector-spec +; (:require +; [clojure.test.check.generators :as gen] +; [clojure.test.check.properties :as prop] +; [clojure.test.check.clojure-test :as ct :refer [defspec]] +; [propeller.push.state :as state] +; [propeller.push.instructions.vector :as vector] +; [propeller.push.interpreter :as interpreter])) +; +;(def gen-type-pairs +; [['gen/small-integer "integer"] +; ['gen/double "float"] +; ['gen/boolean "boolean"] +; ['gen/string "string"]]) +; +;(defn generator-for-arg-type +; [arg-type generator] +; (case arg-type +; :boolean 'gen/boolean +; :integer 'gen/small-integer +; :float 'gen/double +; :string 'gen/string +; ; This is for "generic" vectors where the element is provided by +; ; the `generator` argument. +; :vector `(gen/vector ~generator) +; :item generator +; :vector_boolean '(gen/vector gen/boolean) +; :vector_integer '(gen/vector gen/small-integer) +; :vector_float '(gen/vector gen/double) +; :vector_string '(gen/vector gen/string))) +; +;(defmacro gen-specs +; [spec-name check-fn & arg-types] +; (let [symbol-names (repeatedly (count arg-types) gensym)] +; `(do ~@(for [[generator value-type] gen-type-pairs +; :let [name (symbol (str spec-name "-spec-" value-type))]] +; `(defspec ~name +; (prop/for-all +; [~@(mapcat +; (fn [symbol-name arg-type] +; [symbol-name (generator-for-arg-type arg-type generator)]) +; symbol-names +; arg-types)] +; (~check-fn ~value-type ~@symbol-names))))))) +; +;;;; vector/_butlast +; +;(defn check-butlast +; [value-type vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack state/empty-state +; stack-type +; vect) +; end-state (vector/_butlast stack-type start-state) +; expected-result (vec (butlast vect))] +; (= expected-result +; (state/peek-stack end-state stack-type)))) +; +;(gen-specs "butlast" check-butlast :vector) +; +;;;; vector/_concat +; +;(defn check-concat +; "Creates an otherwise empty Push state with the two given vectors on the +; appropriate vector stack (assumed to be :vector_). +; It then runs the vector/_concat instruction, and confirms that the +; result (on the :vector_ stack) is the expected value. +; The order of concatenation is that the top of the stack will be +; _second_ in the concatenation, i.e., its elements will come _after_ +; the elements in the vector one below it in the stack." +; [value-type first-vect second-vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; first-vect) +; stack-type second-vect) +; end-state (vector/_concat stack-type start-state)] +; (= (concat second-vect first-vect) +; (state/peek-stack end-state stack-type)))) +; +;(gen-specs "concat" check-concat :vector :vector) +; +;;;; vecotr/_conj +; +;(defn check-conj +; [value-type vect value] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; (keyword (str value-type)) +; value) +; end-state (vector/_conj stack-type start-state) +; expected-result (conj vect value)] +; (= expected-result +; (state/peek-stack end-state stack-type)))) +; +;(gen-specs "conj" check-conj :vector :item) +; +;;;; vector/_contains +; +;(defn check-contains +; "Creates an otherwise empty Push state with the given vector on the +; appropriate vector stack (assumed to be :vector_), and +; the given value on the appropriate stack (determined by value-type). +; It then runs the vector/_contains instruction, and confirms that the +; result (on the :boolean stack) is the expected value." +; [value-type vect value] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; (keyword value-type) value) +; end-state (vector/_contains stack-type start-state) +; expected-result (not= (.indexOf vect value) -1)] +; (= expected-result +; (state/peek-stack end-state :boolean)))) +; +;(gen-specs "contains" check-contains :vector :item) +; +;;;; vector/_emptyvector +; +;(defn check-empty-vector +; [value-type vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack state/empty-state +; stack-type +; vect) +; end-state (vector/_emptyvector stack-type start-state)] +; (= (empty? vect) +; (state/peek-stack end-state :boolean)))) +; +;(gen-specs "empty-vector" check-empty-vector :vector) +; +;;;; vector/_first +; +;(defn check-first +; [value-type vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack state/empty-state +; stack-type +; vect) +; end-state (vector/_first stack-type start-state)] +; (or +; (and (empty? vect) +; (= (state/peek-stack end-state stack-type) +; vect)) +; (and +; (= (first vect) +; (state/peek-stack end-state (keyword value-type))) +; (state/empty-stack? end-state stack-type))))) +; +;(gen-specs "first" check-first :vector) +; +;;;; vector/_indexof +; +;(defn check-indexof +; "Creates an otherwise empty Push state with the given vector on the +; appropriate vector stack (assumed to be :vector_), and +; the given value on the appropriate stack (determined by value-type). +; It then runs the vector/_indexof instruction, and confirms that the +; result (on the :integer stack) is the expected value." +; [value-type vect value] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; (keyword value-type) value) +; end-state (vector/_indexof stack-type start-state) +; expected-index (.indexOf vect value)] +; (= expected-index +; (state/peek-stack end-state :integer)))) +; +;(gen-specs "indexof" check-indexof :vector :item) +; +;;;; vector/_iterate +; +;(defn check-iterate +; [value-type vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; print-instr (keyword (str value-type "_print")) +; iter-instr (keyword (str "vector_" value-type "_iterate")) +; program [iter-instr print-instr] +; start-state (-> state/empty-state +; (state/push-to-stack stack-type vect) +; (state/push-to-stack :output "")) +; ; 4 times the vector length should be enough for this iteration, perhaps even +; ; more than we strictly need. +; end-state (interpreter/interpret-program program start-state (* 4 (count vect))) +; ; pr-str adds escaped quote marks, which causes tests to fail because _print +; ; treats strings and characters specially and does not call pr-str on them. +; to-str-fn (if (= value-type "string") identity pr-str) +; expected-result (apply str (map to-str-fn vect))] +; (= expected-result +; (state/peek-stack end-state :output)))) +; +;(gen-specs "iterate" check-iterate :vector) +; +;;;; vector/_last +; +;(defn check-last +; [value-type vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack state/empty-state +; stack-type +; vect) +; end-state (vector/_last stack-type start-state)] +; (or +; (and (empty? vect) +; (= (state/peek-stack end-state stack-type) +; vect)) +; (and +; (= (last vect) +; (state/peek-stack end-state (keyword value-type))) +; (state/empty-stack? end-state stack-type))))) +; +;(gen-specs "last" check-last :vector) +; +;;;; vector/_length +; +;(defn check-length +; [value-type vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack state/empty-state +; stack-type +; vect) +; end-state (vector/_length stack-type start-state) +; expected-result (count vect)] +; (= expected-result +; (state/peek-stack end-state :integer)))) +; +;(gen-specs "length" check-length :vector) +; +;;;; vector/_nth +; +;(defn check-nth +; [value-type vect n] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; :integer +; n) +; end-state (vector/_nth stack-type start-state)] +; (or +; (and (empty? vect) +; (= (state/peek-stack end-state stack-type) +; vect)) +; (and +; (= (get vect (mod n (count vect))) +; (state/peek-stack end-state (keyword value-type))))))) +; +;(gen-specs "nth" check-nth :vector :integer) +; +;;;; vector/_occurrencesof +; +;(defn check-occurrencesof +; [value-type vect value] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; (keyword value-type) +; value) +; end-state (vector/_occurrencesof stack-type start-state) +; expected-result (count (filterv #(= value %) vect))] +; (= expected-result +; (state/peek-stack end-state :integer)))) +; +;(gen-specs "occurrencesof" check-occurrencesof :vector :item) +; +;;;; vector/_pushall +; +;(defn check-pushall +; [value-type vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack state/empty-state +; stack-type +; vect) +; end-state (vector/_pushall stack-type start-state) +; value-stack (keyword value-type) +; vect-length (count vect)] +; (and +; (= +; (vec (state/peek-stack-many end-state value-stack vect-length)) +; vect) +; (state/empty-stack? +; (state/pop-stack-many end-state value-stack vect-length) +; value-stack)))) +; +;(gen-specs "pushall" check-pushall :vector) +; +;;;; vector/_remove +; +;(defn check-remove +; [value-type vect value] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; (keyword value-type) +; value) +; end-state (vector/_remove stack-type start-state)] +; (= [] +; (filterv #(= % value) (state/peek-stack end-state stack-type))))) +; +;(gen-specs "remove" check-remove :vector :item) +; +;;;; vector/_replace +; +;(defn check-replace +; [value-type vect toreplace replacement] +; (let [stack-type (keyword (str "vector_" value-type)) +; value-stack (keyword value-type) +; start-state (state/push-to-stack +; (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; value-stack +; toreplace) +; value-stack +; replacement) +; end-state (vector/_replace stack-type start-state) +; expected-result (replace {toreplace replacement} vect)] +; (= expected-result +; (state/peek-stack end-state stack-type)))) +; +;(gen-specs "replace" check-replace :vector :item :item) +; +;;;; vector/_replacefirst +; +;(defn check-replacefirst +; [value-type vect toreplace replacement] +; (let [stack-type (keyword (str "vector_" value-type)) +; value-stack (keyword value-type) +; start-state (state/push-to-stack +; (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; value-stack +; toreplace) +; value-stack +; replacement) +; end-state (vector/_replacefirst stack-type start-state) +; end-vector (state/peek-stack end-state stack-type) +; replacement-index (.indexOf vect toreplace)] +; (or +; (and (= replacement-index -1) +; (state/empty-stack? end-state value-stack) +; (= vect end-vector)) +; (and (state/empty-stack? end-state value-stack) +; (= end-vector (assoc vect replacement-index replacement)))))) +; +;(gen-specs "replacefirst" check-replacefirst :vector :item :item) +; +;;;; vector/_rest +; +;(defn check-rest +; [value-type vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack state/empty-state +; stack-type +; vect) +; end-state (vector/_rest stack-type start-state) +; expected-result (vec (rest vect))] +; (= expected-result +; (state/peek-stack end-state stack-type)))) +; +;(gen-specs "rest" check-rest :vector) +; +;;;; vector/_reverse +; +;(defn check-reverse +; [value-type vect] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack state/empty-state +; stack-type +; vect) +; end-state (vector/_reverse stack-type start-state) +; expected-result (vec (reverse vect))] +; (= expected-result +; (state/peek-stack end-state stack-type)))) +; +;(gen-specs "reverse" check-reverse :vector) +; +;;;; vector/_set +; +;(defn check-set +; [value-type vect value n] +; (let [stack-type (keyword (str "vector_" value-type)) +; value-stack (keyword value-type) +; start-state (state/push-to-stack +; (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; value-stack +; value) +; :integer +; n) +; end-state (vector/_set stack-type start-state)] +; (or +; (and +; (empty? vect) +; (not (state/empty-stack? end-state :integer)) +; (not (state/empty-stack? end-state value-stack)) +; (= vect (state/peek-stack end-state stack-type))) +; (and +; (= (state/peek-stack end-state stack-type) +; (assoc vect (mod n (count vect)) value)) +; (state/empty-stack? end-state :integer) +; (state/empty-stack? end-state value-stack))))) +; +;(gen-specs "set" check-set :vector :item :integer) +; +;;;; vector/_subvec +; +;(defn clean-subvec-bounds +; [start stop vect-size] +; (let [start (max 0 start) +; stop (max 0 stop) +; start (min start vect-size) +; stop (min stop vect-size) +; stop (max start stop)] +; [start stop])) +; +;(defn check-subvec +; "Creates an otherwise empty Push state with the given vector on the +; appropriate vector stack (assumed to be :vector_), and +; the given values on the integer stack. +; It then runs the vector/_subvec instruction, and confirms that the +; result (on the :vector_ stack) is the expected value." +; [value-type vect start stop] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack +; (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; :integer start) +; :integer stop) +; end-state (vector/_subvec stack-type start-state) +; [cleaned-start cleaned-stop] (clean-subvec-bounds start stop (count vect)) +; expected-subvec (subvec vect cleaned-start cleaned-stop)] +; (= expected-subvec +; (state/peek-stack end-state stack-type)))) +; +;(gen-specs "subvec" check-subvec :vector :integer :integer) +; +;;;; vector/_take +; +;(defn check-take +; [value-type vect n] +; (let [stack-type (keyword (str "vector_" value-type)) +; start-state (state/push-to-stack +; (state/push-to-stack state/empty-state +; stack-type +; vect) +; :integer +; n) +; end-state (vector/_take stack-type start-state) +; expected-result (vec (take n vect))] +; (= expected-result +; (state/peek-stack end-state stack-type)))) +; +;(gen-specs "take" check-take :vector :integer)