1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
3 ;;; Copyright © 2019 Robert Vollmert <rob@vllmrt.net>
4 ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
5 ;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
7 ;;; This file is part of GNU Guix.
9 ;;; GNU Guix is free software; you can redistribute it and/or modify it
10 ;;; under the terms of the GNU General Public License as published by
11 ;;; the Free Software Foundation; either version 3 of the License, or (at
12 ;;; your option) any later version.
14 ;;; GNU Guix is distributed in the hope that it will be useful, but
15 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;;; GNU General Public License for more details.
19 ;;; You should have received a copy of the GNU General Public License
20 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
22 (define-module (test-hackage)
23 #:use-module (guix import cabal)
24 #:use-module (guix import hackage)
25 #:use-module (guix tests)
26 #:use-module (srfi srfi-64)
27 #:use-module (ice-9 match))
32 homepage: http://test.org
34 description: description
38 HTTP >= 4000.2.5 && < 4000.3,
45 homepage: http://test.org
47 description: description
51 HTTP >= 4000.2.5 && < 4000.3,
56 ;; Check compiler implementation test with and without spaces.
60 homepage: http://test.org
62 description: description
65 if impl(ghc >= 7.2 && < 7.6)
67 if impl(ghc>=7.2&&<7.6)
71 HTTP >= 4000.2.5 && < 4000.3,
75 ;; Check "-any", "-none" when name is different.
79 homepage: http://test.org
81 description: description
86 if impl(ghc>=7.2&&<7.6)
90 HTTP >= 4000.2.5 && < 4000.3,
94 ;; Check "-any", "-none".
98 homepage: http://test.org
100 description: description
105 HTTP >= 4000.2.5 && < 4000.3,
107 Build-depends: mtl >= 2.0 && < 3
108 if impl(ghc>=7.2&&<7.6)
112 ;; Check "custom-setup".
117 homepage: http://test.org
119 description: description
122 setup-depends: base >= 4.7 && < 5,
126 if impl(ghc>=7.2&&<7.6)
130 HTTP >= 4000.2.5 && < 4000.3,
134 ;; A fragment of a real Cabal file with minor modification to check precedence
135 ;; of 'and' over 'or', missing final newline, spaces between keywords and
136 ;; parentheses and between key and column.
137 (define test-read-cabal-1
140 -- Choose which library versions to use.
142 Build-depends: base >= 4.8 && < 5
145 Build-depends: base >= 4 && < 4.8
148 Build-depends: base >= 3 && < 4
150 Build-depends: base < 3
151 if flag(base4point8) || flag (base4) && flag(base3)
152 Build-depends: random
153 Build-depends : containers
155 -- Modules that are always built.
157 Test.QuickCheck.Exception")
159 (define test-read-cabal-2
162 if os(foobar) { cc-options: -DBARBAZ }
163 ") ; Intentional newline.
165 ;; Test opening bracket on new line.
166 (define test-read-cabal-brackets-newline
175 ;; Test library with (since Cabal 2.0) and without names.
176 (define test-read-cabal-library-name
179 build-depends: foo, bar
181 build-depends: bar, baz
184 (test-begin "hackage")
186 (define-syntax-rule (define-package-matcher name pattern)
190 (x (pk 'fail x #f)))))
192 (define-package-matcher match-ghc-foo
199 ('uri ('hackage-uri "foo" 'version))
203 ('build-system 'haskell-build-system)
204 ('inputs ('list 'ghc-http))
205 ('home-page "http://test.org")
206 ('synopsis (? string?))
207 ('description (? string?))
208 ('license 'license:bsd-3)))
210 (define* (eval-test-with-cabal test-cabal matcher #:key (cabal-environment '()))
211 (define port (open-input-string test-cabal))
212 (matcher (hackage->guix-package "foo" #:port port #:cabal-environment cabal-environment)))
214 (test-assert "hackage->guix-package test 1"
215 (eval-test-with-cabal test-cabal-1 match-ghc-foo))
217 (test-assert "hackage->guix-package test 2"
218 (eval-test-with-cabal test-cabal-2 match-ghc-foo))
220 (test-assert "hackage->guix-package test 3"
221 (eval-test-with-cabal test-cabal-3 match-ghc-foo
222 #:cabal-environment '(("impl" . "ghc-7.8"))))
224 (test-assert "hackage->guix-package test 4"
225 (eval-test-with-cabal test-cabal-4 match-ghc-foo
226 #:cabal-environment '(("impl" . "ghc-7.8"))))
228 (test-assert "hackage->guix-package test 5"
229 (eval-test-with-cabal test-cabal-5 match-ghc-foo
230 #:cabal-environment '(("impl" . "ghc-7.8"))))
232 (define-package-matcher match-ghc-foo-6
239 ('uri ('hackage-uri "foo" 'version))
243 ('build-system 'haskell-build-system)
244 ('inputs ('list 'ghc-b 'ghc-http))
245 ('native-inputs ('list 'ghc-haskell-gi))
246 ('home-page "http://test.org")
247 ('synopsis (? string?))
248 ('description (? string?))
249 ('license 'license:bsd-3)))
251 (test-assert "hackage->guix-package test 6"
252 (eval-test-with-cabal test-cabal-6 match-ghc-foo-6))
254 ;; Check multi-line layouted description.
255 (define test-cabal-multiline-layout
258 homepage: http://test.org
260 description: first line
265 HTTP >= 4000.2.5 && < 4000.3,
269 (test-assert "hackage->guix-package test multiline desc (layout)"
270 (eval-test-with-cabal test-cabal-multiline-layout match-ghc-foo))
272 ;; Check multi-line braced description.
273 (define test-cabal-multiline-braced
276 homepage: http://test.org
285 HTTP >= 4000.2.5 && < 4000.3,
289 (test-assert "hackage->guix-package test multiline desc (braced)"
290 (eval-test-with-cabal test-cabal-multiline-braced match-ghc-foo))
292 ;; Check mixed layout. Compare e.g. warp.
293 (define test-cabal-mixed-layout
296 homepage: http://test.org
298 description: description
302 HTTP >= 4000.2.5 && < 4000.3,
307 ;; Fails: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=35743
309 (test-assert "hackage->guix-package test mixed layout"
310 (eval-test-with-cabal test-cabal-mixed-layout match-ghc-foo))
312 ;; Check flag executable. Compare e.g. darcs.
313 (define test-cabal-flag-executable
316 homepage: http://test.org
318 description: description
321 description: Build executable
330 HTTP >= 4000.2.5 && < 4000.3,
334 (test-assert "hackage->guix-package test flag executable"
335 (eval-test-with-cabal test-cabal-flag-executable match-ghc-foo))
337 ;; There is no mandatory space between property name and value.
338 (define test-cabal-property-no-space
341 homepage:http://test.org
343 description:description
345 common bench-defaults
349 HTTP >= 4000.2.5 && < 4000.3,
353 (test-assert "hackage->guix-package test properties without space"
354 (eval-test-with-cabal test-cabal-property-no-space match-ghc-foo))
356 ;; There may be no final newline terminating a property.
357 (define test-cabal-no-final-newline
360 homepage: http://test.org
362 description: description
365 build-depends: HTTP >= 4000.2.5 && < 4000.3, mtl >= 2.0 && < 3")
368 (test-assert "hackage->guix-package test without final newline"
369 (eval-test-with-cabal test-cabal-no-final-newline match-ghc-foo))
371 ;; Make sure internal libraries will not be part of the dependencies,
373 (define test-cabal-internal-library-ignored
376 homepage: http://test.org
378 description: description
382 HTTP >= 4000.2.5 && < 4000.3,
385 build-depends: mtl >= 2.0 && < 3
388 (test-assert "hackage->guix-package test internal libraries are ignored"
389 (eval-test-with-cabal test-cabal-internal-library-ignored match-ghc-foo))
391 ;; Check if-elif-else statements
392 (define test-cabal-if
395 homepage: http://test.org
397 description: description
404 (define test-cabal-else
407 homepage: http://test.org
409 description: description
418 (define test-cabal-elif
421 homepage: http://test.org
423 description: description
438 ;; Try the same with different bracket styles
439 (define test-cabal-elif-brackets
442 homepage: http://test.org
444 description: description
452 elif os(guix) { Build-depends: ghc-c }
454 Build-depends: ghc-d }
462 (define-package-matcher match-ghc-elif
469 ('uri ('hackage-uri "foo" 'version))
473 ('build-system 'haskell-build-system)
474 ('inputs ('list 'ghc-c))
475 ('home-page "http://test.org")
476 ('synopsis (? string?))
477 ('description (? string?))
478 ('license 'license:bsd-3)))
480 (test-assert "hackage->guix-package test lonely if statement"
481 (eval-test-with-cabal test-cabal-else match-ghc-elif
482 #:cabal-environment '(("os" . "guix"))))
484 (test-assert "hackage->guix-package test else statement"
485 (eval-test-with-cabal test-cabal-else match-ghc-elif
486 #:cabal-environment '(("os" . "guix"))))
488 (test-assert "hackage->guix-package test elif statement"
489 (eval-test-with-cabal test-cabal-elif match-ghc-elif
490 #:cabal-environment '(("os" . "guix"))))
492 (test-assert "hackage->guix-package test elif statement with brackets"
493 (eval-test-with-cabal test-cabal-elif-brackets match-ghc-elif
494 #:cabal-environment '(("os" . "guix"))))
496 ;; Check Hackage Cabal revisions.
497 (define test-cabal-revision
501 homepage: http://test.org
503 description: description
507 HTTP >= 4000.2.5 && < 4000.3,
511 (define-package-matcher match-ghc-foo-revision
518 ('uri ('hackage-uri "foo" 'version))
522 ('build-system 'haskell-build-system)
523 ('inputs ('list 'ghc-http))
527 ("2" "0xxd88fb659f0krljidbvvmkh9ppjnx83j0nqzx8whcg4n5qbyng"))))
528 ('home-page "http://test.org")
529 ('synopsis (? string?))
530 ('description (? string?))
531 ('license 'license:bsd-3)))
533 (test-assert "hackage->guix-package test cabal revision"
534 (eval-test-with-cabal test-cabal-revision match-ghc-foo-revision))
536 (test-assert "read-cabal test 1"
537 (match (call-with-input-string test-read-cabal-1 read-cabal)
538 ((("name" ("test-me"))
539 ('section 'library #f
540 (('if ('flag "base4point8")
541 (("build-depends" ("base >= 4.8 && < 5")))
542 (('if ('flag "base4")
543 (("build-depends" ("base >= 4 && < 4.8")))
544 (('if ('flag "base3")
545 (("build-depends" ("base >= 3 && < 4")))
546 (("build-depends" ("base < 3"))))))))
547 ('if ('or ('flag "base4point8")
548 ('and ('flag "base4") ('flag "base3")))
549 (("build-depends" ("random")))
551 ("build-depends" ("containers"))
552 ("exposed-modules" ("Test.QuickCheck.Exception")))))
554 (x (pk 'fail x #f))))
556 (test-assert "read-cabal test: if brackets on the same line"
557 (match (call-with-input-string test-read-cabal-2 read-cabal)
558 ((("name" ("test-me"))
559 ('section 'common "defaults"
561 (("cc-options" ("-DBARBAZ ")))
564 (x (pk 'fail x #f))))
567 (test-assert "read-cabal test: property brackets on new line"
568 (match (call-with-input-string test-read-cabal-brackets-newline read-cabal)
569 ((("name" ("test-me"))
570 ('section 'common "defaults"
571 (("build-depends" ("foobar , barbaz")))))
573 (x (pk 'fail x #f))))
575 (test-assert "read-cabal test: library name"
576 (match (call-with-input-string test-read-cabal-library-name read-cabal)
577 ((("name" ("test-me"))
578 ('section 'library "foobar"
579 (("build-depends" ("foo, bar"))))
580 ('section 'library #f
581 (("build-depends" ("bar, baz")))))
583 (x (pk 'fail x #f))))
585 (define test-cabal-import
588 homepage: http://test.org
590 description: description
594 HTTP >= 4000.2.5 && < 4000.3,
601 (define-package-matcher match-ghc-foo-import
608 ('uri ('hackage-uri "foo" 'version))
612 ('build-system 'haskell-build-system)
613 ('inputs ('list 'ghc-http))
614 ('home-page "http://test.org")
615 ('synopsis (? string?))
616 ('description (? string?))
617 ('license 'license:bsd-3)))
619 (test-assert "hackage->guix-package test cabal import"
620 (eval-test-with-cabal test-cabal-import match-ghc-foo-import))