Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions private/file-group.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@

(module+ test
(require (submod "..")
racket/file
racket/list
racket/system
rackunit))


Expand Down Expand Up @@ -136,6 +139,167 @@


(module+ test

(test-case "file-portion"
(test-case "constructor normalizes paths"
(define portion (file-portion "/tmp/test.rkt" (range-set (closed-open-range 1 10 #:comparator natural<=>))))
(check-true (file-portion? portion))
(check-equal? (file-portion-path portion) (simple-form-path "/tmp/test.rkt"))
(check-equal? (file-portion-lines portion) (range-set (closed-open-range 1 10 #:comparator natural<=>)))))

(test-case "single-file-group"
(test-case "constructor and predicates"
(define group (single-file-group "/tmp/test.rkt" (range-set (closed-open-range 1 10 #:comparator natural<=>))))
(check-true (single-file-group? group))
(check-true (file-group? group))
(check-equal? (single-file-group-path group) (simple-form-path "/tmp/test.rkt"))
(check-equal? (single-file-group-ranges group) (range-set (closed-open-range 1 10 #:comparator natural<=>))))

(test-case "file-group-resolve returns single file"
(define test-dir (make-temporary-file "resyntax-test-~a" 'directory))
(define test-file (build-path test-dir "test.rkt"))
(call-with-output-file test-file
(λ (out) (displayln "#lang racket/base" out)))
(define group (single-file-group test-file (range-set (closed-open-range 1 5 #:comparator natural<=>))))
(define portions (file-group-resolve group))
(check-equal? (length portions) 1)
(check-equal? (file-portion-path (first portions)) (simple-form-path test-file))
(check-equal? (file-portion-lines (first portions)) (range-set (closed-open-range 1 5 #:comparator natural<=>)))
(delete-directory/files test-dir)))

(test-case "directory-file-group"
(test-case "constructor and predicates"
(define group (directory-file-group "/tmp"))
(check-true (directory-file-group? group))
(check-true (file-group? group))
(check-equal? (directory-file-group-path group) (simple-form-path "/tmp")))

(test-case "file-group-resolve returns only .rkt files"
(define test-dir (make-temporary-file "resyntax-test-~a" 'directory))
(define rkt-file1 (build-path test-dir "test1.rkt"))
(define rkt-file2 (build-path test-dir "test2.rkt"))
(define txt-file (build-path test-dir "test.txt"))
(call-with-output-file rkt-file1
(λ (out) (displayln "#lang racket/base" out)))
(call-with-output-file rkt-file2
(λ (out) (displayln "#lang racket" out)))
(call-with-output-file txt-file
(λ (out) (displayln "not racket" out)))
(define group (directory-file-group test-dir))
(define portions (file-group-resolve group))
(check-equal? (length portions) 2)
(check-true (andmap (λ (p) (path-has-extension? (file-portion-path p) #".rkt")) portions))
(delete-directory/files test-dir)))

(test-case "package-file-group"
(test-case "constructor and predicates"
(define group (package-file-group "rackunit"))
(check-true (package-file-group? group))
(check-true (file-group? group))
(check-equal? (package-file-group-package-name group) "rackunit"))

(test-case "file-group-resolve returns files from installed package"
(define group (package-file-group "rackunit"))
(define portions (file-group-resolve group))
(check-true (list? portions))
(check-true (andmap file-portion? portions))
(check-true (andmap (λ (p) (path-has-extension? (file-portion-path p) #".rkt")) portions))
(check-true (> (length portions) 0)))

(test-case "file-group-resolve raises error for non-existent package"
(define group (package-file-group "this-package-does-not-exist-xyz"))
(check-exn exn:fail:user?
(λ () (file-group-resolve group)))))

(test-case "git-repository-file-group"
(test-case "constructor and predicates"
(define group (git-repository-file-group "/tmp" "HEAD"))
(check-true (git-repository-file-group? group))
(check-true (file-group? group))
(check-equal? (git-repository-file-group-repository-path group) (simple-form-path "/tmp"))
(check-equal? (git-repository-file-group-ref group) "HEAD"))

(test-case "file-group-resolve with git repository"
(define test-dir (make-temporary-file "resyntax-test-git-~a" 'directory))
(parameterize ([current-directory test-dir])
(unless (system "git init -q")
(fail "git init failed"))
(unless (system "git config user.email 'test@example.com'")
(fail "git config email failed"))
(unless (system "git config user.name 'Test User'")
(fail "git config name failed"))
(define test-file (build-path test-dir "test.rkt"))
(call-with-output-file test-file
(λ (out) (displayln "#lang racket/base\n(void)" out)))
(unless (system "git add test.rkt")
(fail "git add failed"))
(unless (system "git commit -q -m 'Initial commit'")
(fail "git commit failed"))
(call-with-output-file test-file #:exists 'append
(λ (out) (displayln "(define x 1)" out)))
(define group (git-repository-file-group test-dir "HEAD"))
(define portions (file-group-resolve group))
(check-true (list? portions))
(check-true (> (length portions) 0))
(check-true (andmap file-portion? portions)))
(delete-directory/files test-dir)))

(test-case "file-groups-resolve"
(test-case "resolves multiple groups into hash"
(define test-dir (make-temporary-file "resyntax-test-~a" 'directory))
(define test-file1 (build-path test-dir "test1.rkt"))
(define test-file2 (build-path test-dir "test2.rkt"))
(call-with-output-file test-file1
(λ (out) (displayln "#lang racket/base" out)))
(call-with-output-file test-file2
(λ (out) (displayln "#lang racket" out)))
(define group1 (single-file-group test-file1 (range-set (closed-open-range 1 5 #:comparator natural<=>))))
(define group2 (single-file-group test-file2 (range-set (closed-open-range 3 8 #:comparator natural<=>))))
(define result (file-groups-resolve (list group1 group2)))
(check-true (hash? result))
(check-equal? (hash-count result) 2)
(check-true (hash-has-key? result (file-source test-file1)))
(check-true (hash-has-key? result (file-source test-file2)))
(delete-directory/files test-dir))

(test-case "combines ranges for same file"
(define test-dir (make-temporary-file "resyntax-test-~a" 'directory))
(define test-file (build-path test-dir "test.rkt"))
(call-with-output-file test-file
(λ (out) (displayln "#lang racket/base" out)))
(define group1 (single-file-group test-file (range-set (closed-open-range 1 3 #:comparator natural<=>))))
(define group2 (single-file-group test-file (range-set (closed-open-range 5 7 #:comparator natural<=>))))
(define result (file-groups-resolve (list group1 group2)))
(check-equal? (hash-count result) 1)
(define combined-ranges (hash-ref result (file-source test-file)))
(check-true (range-set-contains? combined-ranges 1))
(check-true (range-set-contains? combined-ranges 2))
(check-true (range-set-contains? combined-ranges 5))
(check-true (range-set-contains? combined-ranges 6))
(delete-directory/files test-dir)))

(test-case "rkt-file?"
(test-case "returns true for .rkt files"
(define portion (file-portion "/tmp/test.rkt" (range-set #:comparator natural<=>)))
(check-true (rkt-file? portion)))

(test-case "returns false for non-.rkt files"
(define portion1 (file-portion "/tmp/test.txt" (range-set #:comparator natural<=>)))
(define portion2 (file-portion "/tmp/test.scm" (range-set #:comparator natural<=>)))
(check-false (rkt-file? portion1))
(check-false (rkt-file? portion2))))

(test-case "range-bound-map"
(test-case "maps bounded endpoints"
(define bound (range-bound 5 inclusive))
(define result (range-bound-map bound (λ (x) (* x 2))))
(check-equal? (range-bound-endpoint result) 10)
(check-equal? (range-bound-type result) inclusive))

(test-case "preserves unbounded"
(define result (range-bound-map unbounded (λ (x) (* x 2))))
(check-equal? result unbounded)))

(test-case "expand-modified-line-set"
(define ranges (range-set (closed-open-range 4 6) (greater-than-range 15)))
(define expected (range-set (closed-open-range 1 9) (greater-than-range 12)))
Expand Down