0

I've implemented my own version of index-of. It takes two strings and returns the index where the second string is found in the first. In use, it seems to work fine, but it's failing the test.check property test. The weird thing is test.check says it fails at values like "0bU", but I have it set so the smallest input is 100 characters. Why is it using inputs smaller than what I've told it to use?

I wrote my own generator using gen/fmap and it looks correct when I call it using gen/sample.

The code:

(defn gen-alphanumeric   "A generator that accepts a minimum and maximum string length" [min max]   
    (gen/fmap str/join (gen/vector gen/char-alphanumeric min max)))

(defspec indexof-functionality-test   
  (prop/for-all [s1 (gen-alphanumeric 100 200)
                 begin gen/nat 80]
    (let [end (+ begin 10)
          s2 (subs s1 begin end)]
      (= (str/index-of s1 s2) (cp-str/indexof s1 s2)))))

The output from lein test

FAIL in (indexof-functionality-test) (string_test.clj:57) expected: {:result true} actual: {:shrunk {:total-nodes-visited 11, :depth 4, :pass? false, :result false, :result-data nil, :time-shrinking-ms 2, :smallest ["240"]}, :failed-after-ms 0, :num-tests 4, :seed 1676231835751, :fail ["n5n0"], :result false, :result-data nil, :failing-size 3, :pass? false, :test-var "indexof-functionality-test"}

EDIT:

My cp-str/indexof

(defn indexof
  "given two strings, returns the index where sb begins in sa. Nil if not found"
  ([sa sb]
   (indexof sa sb 0))
  ([sa sb i]
   (let [sa-len (count sa)
         sb-len (count sb)]
     (cond
       (>= 0 sa-len) nil
       (>= 0 sb-len) nil
       ; this is hit when element not found
       (> (+ i sb-len) sa-len) nil
       (= (subs sa i (+ i sb-len)) sb) i
       :else (indexof sa sb (inc i))))))

EDIT2: It fails on one computer and passes on another. Those three methods are identical on the two computers.

triplej
  • 269
  • 4
  • 9
  • I can't completely run your code because you haven't provided `cp-str/index-of`, and when I run a degenerate version (that obviously won't fail on the exact same examples that yours does), I don't see it generating small strings. – gfredericks Feb 12 '23 at 22:05
  • @gfredericks - I added in `cp-str/indexof` – triplej Feb 13 '23 at 02:11
  • I also wasn't able to reproduce generating short strings (even with the same seed). Instead, I run into some StringIndexOutOfBoundsException, when I increased the number of the tests (200+). I guess `begin gen/nat 80` (80 is discarded) is generating too high numbers and you should use something like `gen/such-that`. – Martin Půda Feb 13 '23 at 08:18
  • or `(gen/resize 80 gen/nat)` – Martin Půda Feb 13 '23 at 08:33
  • @gfredericks I played around with this and test passes on one computer and fails on another. Ideas? – triplej Feb 13 '23 at 17:20
  • I have tried to make it more specific here: https://github.com/gfredericks/stack-overflow-75429881 When you run that `go.sh` script, do you get different results on two different computers? If so, I think you could report that as a general clojure issue, and/or debug it further to isolate it to a much smaller piece of code that has inconsistent behavior. – gfredericks Feb 19 '23 at 16:06
  • @gfredericks Thanks a lot! For some reason the tests now pass on both computers. I am perplexed, but I guess that is good enough. – triplej Feb 22 '23 at 17:22

0 Answers0