2015-01-30 6 views
0

생성 테스트는 흥미로운 것 같지만 테스트의 일부로 임의의 UUID를 생성해야했습니다. java.util.UUID/newRandom은 test.check 축소와 함께 훌륭하게 재생되지 않습니다. 그것은 보이는 것보다 Clojure의에 번역 까다 롭습니다Clojure에서 test.check와 함께 작동 할 수있는 UUID를 생성하는 방법

public static UUID randomUUID() 
{ 
    long lsb = r.nextLong(); 
    long msb = r.nextLong(); 

    lsb &= 0x3FFFFFFFFFFFFFFFL; 
    lsb |= 0x8000000000000000L; // set top two bits to variant 2 

    msb &= 0xFFFFFFFFFFFF0FFFL; 
    msb |= 0x4000; // Version 4; 

    return new UUID(msb, lsb); 
} 

:

자바 코드처럼 보인다.

Clojure에서 성공적으로 수축 할 수있는 임의의 UUID 함수를 작성하려면 어떻게해야합니까? 적절한 유형 4 UUID를 두 갈망을 받아 생성

답변

1

FN은 다음과 같습니다

(defn make-uuid [[msb lsb]] 
    (java.util.UUID. (-> msb 
        (bit-clear 15) 
        (bit-set 14) 
        (bit-clear 13) 
        (bit-clear 12)) 
       (-> lsb 
        (bit-set 63) 
        (bit-clear 62)))) 

당신은 (먼저 문자열로 변환해야합니다), 결과를 확인하기 위해 정규 표현식을 사용할 수 있습니다.

(def uuids (gen/fmap make-uuid (gen/tuple (gen/choose 0 Long/MAX_VALUE) 
              (gen/choose 0 Long/MAX_VALUE)))) 

(defspec check-random-uuid 100000 
    (for-all [uuid uuids] 
     (re-find uuid-v4-regex (str uuid)))) 

을 그리고 테스트의 모양 :

(def uuid-v4-regex 
    #"(?i)[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[98ab][a-f0-9]{3}-[a-f0-9]{12}") 

그런 다음 다음과 같이 테스트 할 수 있습니다 그냥 재미를 위해

(check-random-uuid) 
=> {:result true, :num-tests 100000, :seed 1422050154338} 

, 나는 유효한 문자 (9)에 대한 중 하나를 제거 두 번째 필드는 실패한 테스트의 모습입니다. 따라서 축소 : 실패 : 작음이 어떻게 도움이되는지 확인할 수 있습니다.

(pp/pprint (check-random-uuid)) 
{:result nil, 
:seed 1422050276824, 
:failing-size 2, 
:num-tests 3, 
:fail [#uuid "2c6d1442-eec3-4800-972e-02905c1b3c00"], 
:shrunk 
{:total-nodes-visited 932, 
    :depth 29, 
    :result nil, 
    :smallest [#uuid "00000000-0000-4000-9000-000000000000"]}} 

잡음 감소가 테스트 케이스에서 제거 할 수있는 정도를 보여주는 것입니다. test.check 버전 0.9.0의로

0

는이 내장 를 축소하지 않는 것이 랜덤 UUID를 생성 gen/uuid.

UUID 축소를 실제로 원하면 new gen/large-integer은 균일 분포가 아닌 전체 long 범위를 생성하기 때문에 generate-two-longs 메서드가 더 쉽습니다.

모두 longs 이상의 균일 한 분포를 생성 할 수있는 내장 생성기가 아직 없지만 향후 추가해야 할 사항입니다.