aboutsummaryrefslogtreecommitdiff
path: root/tests/opam.scm
blob: 832fea1d9bf721dcb1b8514a123b4ac15320a07f (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2018 Julien Lepiller <julien@lepiller.eu>
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (test-opam)
  #:use-module (guix import opam)
  #:use-module (guix base32)
  #:use-module (gcrypt hash)
  #:use-module (guix tests)
  #:use-module ((guix build syscalls) #:select (mkdtemp!))
  #:use-module ((guix build utils) #:select (delete-file-recursively mkdir-p which))
  #:use-module ((guix utils) #:select (call-with-temporary-output-file))
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-64)
  #:use-module (web uri)
  #:use-module (ice-9 match)
  #:use-module (ice-9 peg))

(define test-opam-file
"opam-version: \"2.0\"
  version: \"1.0.0\"
maintainer: \"Alice Doe\"
authors: [
  \"Alice Doe\"
  \"John Doe\"
]
homepage: \"https://example.org/\"
bug-reports: \"https://example.org/bugs\"
dev-repo: \"https://example.org/git\"
build: [
  [\"ocaml\" \"pkg/pkg.ml\" \"build\" \"--pinned\" \"%{pinned}%\"]
]
build-test: [
  [\"ocaml\" \"pkg/pkg.ml\" \"build\" \"--pinned\" \"%{pinned}%\" \"--tests\" \"true\"]
]
depends: [
  \"alcotest\" {test & >= \"0.7.2\"}
  \"ocamlbuild\" {build & >= \"0.9.2\"}
  \"zarith\" {>= \"0.7\"}
]
synopsis: \"Some example package\"
description: \"\"\"
This package is just an example.\"\"\"
license: \"BSD-3-Clause\"
url {
  src: \"https://example.org/foo-1.0.0.tar.gz\"
  checksum: \"md5=74c6e897658e820006106f45f736381f\"
}")

(define test-source-hash
  "")

(define test-repo
  (mkdtemp! "/tmp/opam-repo.XXXXXX"))

(test-begin "opam")

(test-assert "opam->guix-package"
  (mock ((guix import opam) get-opam-repository
         (const test-repo))
        (mock ((guix import utils) url-fetch
               (lambda (url file-name)
                 (match url
                   ("https://example.org/foo-1.0.0.tar.gz"
                    (begin
                      (mkdir-p "foo-1.0.0")
                      (system* "tar" "czvf" file-name "foo-1.0.0/")
                      (delete-file-recursively "foo-1.0.0")
                      (set! test-source-hash
                            (call-with-input-file file-name port-sha256))))
                   (_ (error "Unexpected URL: " url)))))
              (let ((my-package (string-append test-repo
                                               "/packages/foo/foo.1.0.0")))
                (mkdir-p my-package)
                (with-output-to-file (string-append my-package "/opam")
                  (lambda _
                    (format #t "~a" test-opam-file))))
              (match (opam->guix-package "foo" #:repo (list test-repo))
                (`(package
                    (name "ocaml-foo")
                    (version "1.0.0")
                    (source (origin
                              (method url-fetch)
                              (uri "https://example.org/foo-1.0.0.tar.gz")
                              (sha256
                               (base32 ,(? string? hash)))))
                    (build-system ocaml-build-system)
                    (propagated-inputs (list ocaml-zarith))
                    (native-inputs
                     (list ocaml-alcotest ocamlbuild))
                    (home-page "https://example.org/")
                    (synopsis "Some example package")
                    (description "This package is just an example.")
                    (license license:bsd-3))
                 (string=? (bytevector->nix-base32-string
                            test-source-hash)
                           hash))
                (x
                 (pk 'fail x #f))))))

;; Test the opam file parser
;; We fold over some test cases. Each case is a pair of the string to parse and the
;; expected result.
(define (test-opam-syntax name pattern test-cases)
  (test-assert name
    (fold (lambda (test acc)
            (display test) (newline)
            (match test
              ((str . expected)
               (and acc
                    (let ((result (peg:tree (match-pattern pattern str))))
                      (if (equal? result expected)
                          #t
                          (pk 'fail (list str result expected) #f)))))))
          #t test-cases)))

(test-opam-syntax
  "parse-strings" string-pat
  '(("" . #f)
    ("\"hello\"" . (string-pat "hello"))
    ("\"hello world\"" . (string-pat "hello world"))
    ("\"The dreaded \\\"é\\\"\"" . (string-pat "The dreaded \"é\""))
    ("\"Have some \\\\\\\\ :)\"" . (string-pat "Have some \\\\ :)"))
    ("\"今日は\"" . (string-pat "今日は"))))

(test-opam-syntax
  "parse-multiline-strings" multiline-string
  '(("" . #f)
    ("\"\"\"hello\"\"\"" . (multiline-string "hello"))
    ("\"\"\"hello \"world\"!\"\"\"" . (multiline-string "hello \"world\"!"))
    ("\"\"\"hello \"\"world\"\"!\"\"\"" . (multiline-string "hello \"\"world\"\"!"))))

(test-opam-syntax
  "parse-lists" list-pat
  '(("" . #f)
    ("[]" . list-pat)
    ("[make]" . (list-pat (var "make")))
    ("[\"make\"]" . (list-pat (string-pat "make")))
    ("[\n  a\n  b\n  c]" . (list-pat (var "a") (var "b") (var "c")))
    ("[a   b     \"c\"]" . (list-pat (var "a") (var "b") (string-pat "c")))
    ;; complex lists
    ("[(a & b)]" . (list-pat (choice-pat (group-pat (var "a") (var "b")))))
    ("[(a | b & c)]" . (list-pat (choice-pat (var "a") (group-pat (var "b") (var "c")))))
    ("[a (b | c) d]" . (list-pat (var "a") (choice-pat (var "b") (var "c")) (var "d")))))

(test-opam-syntax
  "parse-dicts" dict
  '(("" . #f)
    ("{}" . dict)
    ("{a: \"b\"}" . (dict (record "a" (string-pat "b"))))
    ("{a: \"b\"\nc: \"d\"}" . (dict (record "a" (string-pat "b")) (record "c" (string-pat "d"))))))

(test-opam-syntax
  "parse-conditions" condition
  '(("" . #f)
    ("{}" . #f)
    ("{build}" . (condition-var "build"))
    ("{>= \"0.2.0\"}" . (condition-greater-or-equal
                          (condition-string "0.2.0")))
    ("{>= \"0.2.0\" & test}" . (condition-and
                                 (condition-greater-or-equal
                                   (condition-string "0.2.0"))
                                 (condition-var "test")))
    ("{>= \"0.2.0\" | build}" . (condition-or
                                 (condition-greater-or-equal
                                   (condition-string "0.2.0"))
                                 (condition-var "build")))
    ("{ = \"1.0+beta19\" }" . (condition-eq
                                (condition-string "1.0+beta19")))))

(test-opam-syntax
  "parse-comment" list-pat
  '(("" . #f)
    ("[#comment\n]" . list-pat)))

(test-end "opam")
tc...) in Python projects.") (license license:expat))) (define-public python-vcrpy (package (name "python-vcrpy") (version "2.0.1") (source (origin (method url-fetch) (uri (pypi-uri "vcrpy" version)) (sha256 (base32 "0kws7l3hci1dvjv01nxw3805q9v2mwldw58bgl8s90wqism69gjp")))) (build-system python-build-system) (arguments `(#:tests? #f)) ; tests require more packages for python-pytest-httpbin (propagated-inputs `(("python-pyyaml" ,python-pyyaml) ("python-six" ,python-six) ("python-wrapt" ,python-wrapt) ("python-yarl" ,python-yarl))) (native-inputs `(("python-mock" ,python-mock) ("python-pytest" ,python-pytest) ("python-pytest-httpbin" ,python-pytest-httpbin))) (home-page "https://github.com/kevin1024/vcrpy") (synopsis "Automatically mock your HTTP interactions") (description "VCR.py simplifies and speeds up tests that make HTTP requests. The first time you run code that is inside a VCR.py context manager or decorated function, VCR.py records all HTTP interactions that take place through the libraries it supports and serializes and writes them to a flat file (in yaml format by default). This flat file is called a cassette. When the relevant piece of code is executed again, VCR.py will read the serialized requests and responses from the aforementioned cassette file, and intercept any HTTP requests that it recognizes from the original test run and return the responses that corresponded to those requests. This means that the requests will not actually result in HTTP traffic, which confers several benefits including: @enumerate @item The ability to work offline @item Completely deterministic tests @item Increased test execution speed @end enumerate If the server you are testing against ever changes its API, all you need to do is delete your existing cassette files, and run your tests again. VCR.py will detect the absence of a cassette file and once again record all HTTP interactions, which will update them to correspond to the new API.") (license license:expat))) (define-public python-pytest-checkdocs (package (name "python-pytest-checkdocs") (version "1.2.2") (source (origin (method url-fetch) (uri (pypi-uri "pytest-checkdocs" version)) (sha256 (base32 "0j6j1gvj6x451y3qsx4xbaq9p1w9gg3mwk7n0w80cy8vdyjkngb0")))) (build-system python-build-system) (propagated-inputs `(("python-docutils" ,python-docutils) ("python-importlib-metadata" ,python-importlib-metadata) ("python-more-itertools" ,python-more-itertools))) (native-inputs `(("python-setuptools-scm" ,python-setuptools-scm))) (home-page "https://github.com/jaraco/pytest-checkdocs") (synopsis "Check the README when running tests") (description "This package provides a pytest plugin that checks the long description of the project to ensure it renders properly.") (license license:expat))) (define-public python-pytest-flake8 (package (name "python-pytest-flake8") (version "1.0.4") (source (origin (method url-fetch) (uri (pypi-uri "pytest-flake8" version)) (sha256 (base32 "1h30gd21fjsafqxwclf25sdh89vrdz7rsh4lzw11aiw7ww9mq8jd")))) (build-system python-build-system) (propagated-inputs `(("python-flake8" ,python-flake8))) (native-inputs `(("python-pytest" ,python-pytest))) (home-page "https://github.com/tholo/pytest-flake8") (synopsis "Pytest plugin to check FLAKE8 requirements") (description "This package provides a pytest plugin for efficiently checking PEP8 compliance.") (license license:bsd-3))) (define-public python-pytest-isort (package (name "python-pytest-isort") (version "0.3.1") (source (origin (method url-fetch) (uri (pypi-uri "pytest-isort" version)) (sha256 (base32 "06myn5hhxs5yp8dqr1yjsgcnnxnsrvsqannm00bvaw0qml6ydzjb")))) (build-system python-build-system) (arguments `(#:phases (modify-phases %standard-phases (replace 'check (lambda _ (setenv "PYTHONPATH" (string-append (getcwd) ":" (getenv "PYTHONPATH"))) (invoke "pytest")))))) (propagated-inputs `(("python-isort" ,python-isort) ("python-pytest" ,python-pytest))) (home-page "https://github.com/moccu/pytest-isort/") (synopsis "Pytest plugin to check import ordering using isort") (description "This package provides a pytest plugin to check import ordering using isort.") (license license:bsd-3))) (define-public python-pytest-shutil (package (name "python-pytest-shutil") (version "1.7.0") (source (origin (method url-fetch) (uri (pypi-uri "pytest-shutil" version)) (sha256 (base32 "0q8j0ayzmnvlraml6i977ybdq4xi096djhf30n2m1rvnvrhm45nq")))) (build-system python-build-system) (arguments `(#:phases (modify-phases %standard-phases (add-after 'unpack 'patch-tests (lambda _ (mkdir "/tmp/bin") (substitute* "tests/integration/test_cmdline_integration.py" (("dirname = '/bin'") "dirname = '/tmp/bin'") (("bindir = os.path.realpath\\('/bin'\\)") "bindir = os.path.realpath('/tmp/bin')")) #t))))) (propagated-inputs `(("python-contextlib2" ,python-contextlib2) ("python-execnet" ,python-execnet) ("python-pathpy" ,python-pathpy) ("python-termcolor" ,python-termcolor))) (native-inputs `(("python-mock" ,python-mock) ("python-pytest" ,python-pytest) ("python-setuptools-git" ,python-setuptools-git))) (home-page "https://github.com/manahl/pytest-plugins") (synopsis "Assorted shell and environment tools for py.test") (description "This package provides assorted shell and environment tools for the py.test testing framework.") (license license:expat))) (define-public python-pytest-fixture-config (package (name "python-pytest-fixture-config") (version "1.7.0") (source (origin (method url-fetch) (uri (pypi-uri "pytest-fixture-config" version)) (sha256 (base32 "13i1qpz22w3x4dmw8vih5jdnbqfqvl7jiqs0dg764s0zf8bp98a1")))) (build-system python-build-system) (native-inputs `(("python-pytest" ,python-pytest) ("python-setuptools-git" ,python-setuptools-git))) (home-page "https://github.com/manahl/pytest-plugins") (synopsis "Fixture configuration utils for py.test") (description "This package provides fixture configuration utilities for the py.test testing framework.") (license license:expat))) (define-public python-pytest-virtualenv (package (name "python-pytest-virtualenv") (version "1.7.0") (source (origin (method url-fetch) (uri (pypi-uri "pytest-virtualenv" version)) (sha256 (base32 "03w2zz3crblj1p6i8nq17946hbn3zqp9z7cfnifw47hi4a4fww12")))) (build-system python-build-system) (arguments `(#:phases (modify-phases %standard-phases ;; Reference the virtualenv executable directly, to avoid the need ;; for PYTHONPATH, which gets cleared when instantiating a new ;; virtualenv with pytest-virtualenv. (add-after 'unpack 'patch-virtualenv-executable (lambda* (#:key inputs #:allow-other-keys) (let* ((virtualenv (assoc-ref inputs "python-virtualenv")) (virtualenv-bin (string-append virtualenv "/bin/virtualenv"))) (substitute* "pytest_virtualenv.py" (("^DEFAULT_VIRTUALENV_FIXTURE_EXECUTABLE.*$") (format #f "DEFAULT_VIRTUALENV_FIXTURE_EXECUTABLE = '~a'" virtualenv-bin))) #t)))))) (propagated-inputs `(("python-pytest-shutil" ,python-pytest-shutil) ("python-pytest-fixture-config" ,python-pytest-fixture-config))) (inputs `(("python-virtualenv" ,python-virtualenv))) (native-inputs `(("python-mock" ,python-mock) ("python-pytest" ,python-pytest) ("python-setuptools-git" ,python-setuptools-git))) (home-page "https://github.com/manahl/pytest-plugins") (synopsis "Virtualenv fixture for py.test") (description "This package provides a virtualenv fixture for the py.test framework.") (license license:expat))) (define-public python-codacy-coverage (package (name "python-codacy-coverage") (version "1.3.11") (source (origin (method url-fetch) (uri (pypi-uri "codacy-coverage" version)) (sha256 (base32 "1g0c0w56xdkmqb8slacyw5qhzrkp814ng3ddh2lkiij58y9m2imr")))) (build-system python-build-system) (arguments `(#:tests? #f)); no tests (propagated-inputs `(("python-check-manifest" ,python-check-manifest))) (home-page "https://github.com/codacy/python-codacy-coverage") (synopsis "Codacy coverage reporter for Python") (description "This package analyses Python test suites and reports how much of the code is covered by them. This tool is part of the Codacy suite for analysing code quality.") (license license:expat))) (define-public python-httmock (package (name "python-httmock") (version "1.3.0") (source (origin (method url-fetch) (uri (pypi-uri "httmock" version)) (sha256 (base32 "1zj1fcm0n6f0wr9mr0hmlqz9430fnr5cdwd5jkcvq9j44bnsrfz0")))) (build-system python-build-system) (arguments `(#:tests? #f)); no tests (propagated-inputs `(("python-requests" ,python-requests))) (home-page "https://github.com/patrys/httmock") (synopsis "Mocking library for requests.") (description "This package provides a library for replying fake data to Python software under test, when they make an HTTP query.") (license license:asl2.0)))