The Meson Build System
http://mesonbuild.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
9.4 KiB
221 lines
9.4 KiB
# SPDX-License-Identifier: Apache-2.0 |
|
# Copyright © 2022-2023 Intel Corporation |
|
|
|
from __future__ import annotations |
|
import unittest |
|
import os |
|
import tempfile |
|
import textwrap |
|
import typing as T |
|
|
|
from mesonbuild.cargo import builder, cfg, load_wraps |
|
from mesonbuild.cargo.cfg import TokenType |
|
from mesonbuild.cargo.version import convert |
|
|
|
|
|
class CargoVersionTest(unittest.TestCase): |
|
|
|
def test_cargo_to_meson(self) -> None: |
|
cases: T.List[T.Tuple[str, T.List[str]]] = [ |
|
# Basic requirements |
|
('>= 1', ['>= 1']), |
|
('> 1', ['> 1']), |
|
('= 1', ['= 1']), |
|
('< 1', ['< 1']), |
|
('<= 1', ['<= 1']), |
|
|
|
# tilde tests |
|
('~1', ['>= 1', '< 2']), |
|
('~1.1', ['>= 1.1', '< 1.2']), |
|
('~1.1.2', ['>= 1.1.2', '< 1.2.0']), |
|
|
|
# Wildcards |
|
('*', []), |
|
('1.*', ['>= 1', '< 2']), |
|
('2.3.*', ['>= 2.3', '< 2.4']), |
|
|
|
# Unqualified |
|
('2', ['>= 2', '< 3']), |
|
('2.4', ['>= 2.4', '< 3']), |
|
('2.4.5', ['>= 2.4.5', '< 3']), |
|
('0.0.0', ['< 1']), |
|
('0.0', ['< 1']), |
|
('0', ['< 1']), |
|
('0.0.5', ['>= 0.0.5', '< 0.0.6']), |
|
('0.5.0', ['>= 0.5.0', '< 0.6']), |
|
('0.5', ['>= 0.5', '< 0.6']), |
|
('1.0.45', ['>= 1.0.45', '< 2']), |
|
|
|
# Caret (Which is the same as unqualified) |
|
('^2', ['>= 2', '< 3']), |
|
('^2.4', ['>= 2.4', '< 3']), |
|
('^2.4.5', ['>= 2.4.5', '< 3']), |
|
('^0.0.0', ['< 1']), |
|
('^0.0', ['< 1']), |
|
('^0', ['< 1']), |
|
('^0.0.5', ['>= 0.0.5', '< 0.0.6']), |
|
('^0.5.0', ['>= 0.5.0', '< 0.6']), |
|
('^0.5', ['>= 0.5', '< 0.6']), |
|
|
|
# Multiple requirements |
|
('>= 1.2.3, < 1.4.7', ['>= 1.2.3', '< 1.4.7']), |
|
] |
|
|
|
for (data, expected) in cases: |
|
with self.subTest(): |
|
self.assertListEqual(convert(data), expected) |
|
|
|
|
|
class CargoCfgTest(unittest.TestCase): |
|
|
|
def test_lex(self) -> None: |
|
cases: T.List[T.Tuple[str, T.List[T.Tuple[TokenType, T.Optional[str]]]]] = [ |
|
('"unix"', [(TokenType.STRING, 'unix')]), |
|
('unix', [(TokenType.IDENTIFIER, 'unix')]), |
|
('not(unix)', [ |
|
(TokenType.NOT, None), |
|
(TokenType.LPAREN, None), |
|
(TokenType.IDENTIFIER, 'unix'), |
|
(TokenType.RPAREN, None), |
|
]), |
|
('any(unix, windows)', [ |
|
(TokenType.ANY, None), |
|
(TokenType.LPAREN, None), |
|
(TokenType.IDENTIFIER, 'unix'), |
|
(TokenType.COMMA, None), |
|
(TokenType.IDENTIFIER, 'windows'), |
|
(TokenType.RPAREN, None), |
|
]), |
|
('target_arch = "x86_64"', [ |
|
(TokenType.IDENTIFIER, 'target_arch'), |
|
(TokenType.EQUAL, None), |
|
(TokenType.STRING, 'x86_64'), |
|
]), |
|
('all(target_arch = "x86_64", unix)', [ |
|
(TokenType.ALL, None), |
|
(TokenType.LPAREN, None), |
|
(TokenType.IDENTIFIER, 'target_arch'), |
|
(TokenType.EQUAL, None), |
|
(TokenType.STRING, 'x86_64'), |
|
(TokenType.COMMA, None), |
|
(TokenType.IDENTIFIER, 'unix'), |
|
(TokenType.RPAREN, None), |
|
]), |
|
] |
|
for data, expected in cases: |
|
with self.subTest(): |
|
self.assertListEqual(list(cfg.lexer(data)), expected) |
|
|
|
def test_parse(self) -> None: |
|
cases = [ |
|
('target_os = "windows"', cfg.Equal(cfg.Identifier("target_os"), cfg.String("windows"))), |
|
('target_arch = "x86"', cfg.Equal(cfg.Identifier("target_arch"), cfg.String("x86"))), |
|
('target_family = "unix"', cfg.Equal(cfg.Identifier("target_family"), cfg.String("unix"))), |
|
('any(target_arch = "x86", target_arch = "x86_64")', |
|
cfg.Any( |
|
[ |
|
cfg.Equal(cfg.Identifier("target_arch"), cfg.String("x86")), |
|
cfg.Equal(cfg.Identifier("target_arch"), cfg.String("x86_64")), |
|
])), |
|
('all(target_arch = "x86", target_os = "linux")', |
|
cfg.All( |
|
[ |
|
cfg.Equal(cfg.Identifier("target_arch"), cfg.String("x86")), |
|
cfg.Equal(cfg.Identifier("target_os"), cfg.String("linux")), |
|
])), |
|
('not(all(target_arch = "x86", target_os = "linux"))', |
|
cfg.Not( |
|
cfg.All( |
|
[ |
|
cfg.Equal(cfg.Identifier("target_arch"), cfg.String("x86")), |
|
cfg.Equal(cfg.Identifier("target_os"), cfg.String("linux")), |
|
]))), |
|
] |
|
for data, expected in cases: |
|
with self.subTest(): |
|
self.assertEqual(cfg.parse(iter(cfg.lexer(data))), expected) |
|
|
|
def test_ir_to_meson(self) -> None: |
|
build = builder.Builder('') |
|
HOST_MACHINE = build.identifier('host_machine') |
|
|
|
cases = [ |
|
('target_os = "windows"', |
|
build.equal(build.method('system', HOST_MACHINE), |
|
build.string('windows'))), |
|
('target_arch = "x86"', |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86'))), |
|
('target_family = "unix"', |
|
build.equal(build.method('system', HOST_MACHINE), |
|
build.string('unix'))), |
|
('not(target_arch = "x86")', |
|
build.not_(build.equal( |
|
build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86')))), |
|
('any(target_arch = "x86", target_arch = "x86_64")', |
|
build.or_( |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86')), |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86_64')))), |
|
('any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")', |
|
build.or_( |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86')), |
|
build.or_( |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86_64')), |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('aarch64'))))), |
|
('all(target_arch = "x86", target_arch = "x86_64")', |
|
build.and_( |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86')), |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86_64')))), |
|
('all(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64")', |
|
build.and_( |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86')), |
|
build.and_( |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('x86_64')), |
|
build.equal(build.method('cpu_family', HOST_MACHINE), |
|
build.string('aarch64'))))), |
|
] |
|
for data, expected in cases: |
|
with self.subTest(): |
|
value = cfg.ir_to_meson(cfg.parse(iter(cfg.lexer(data))), build) |
|
self.assertEqual(value, expected) |
|
|
|
class CargoLockTest(unittest.TestCase): |
|
def test_cargo_lock(self) -> None: |
|
with tempfile.TemporaryDirectory() as tmpdir: |
|
with open(os.path.join(tmpdir, 'Cargo.lock'), 'w', encoding='utf-8') as f: |
|
f.write(textwrap.dedent('''\ |
|
version = 3 |
|
[[package]] |
|
name = "foo" |
|
version = "0.1" |
|
source = "registry+https://github.com/rust-lang/crates.io-index" |
|
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" |
|
[[package]] |
|
name = "bar" |
|
version = "0.1" |
|
source = "git+https://github.com/gtk-rs/gtk-rs-core?branch=0.19#23c5599424cc75ec66618891c915d9f490f6e4c2" |
|
''')) |
|
wraps = load_wraps(tmpdir, 'subprojects') |
|
self.assertEqual(len(wraps), 2) |
|
self.assertEqual(wraps[0].name, 'foo-0.1-rs') |
|
self.assertEqual(wraps[0].directory, 'foo-0.1') |
|
self.assertEqual(wraps[0].type, 'file') |
|
self.assertEqual(wraps[0].get('method'), 'cargo') |
|
self.assertEqual(wraps[0].get('source_url'), 'https://crates.io/api/v1/crates/foo/0.1/download') |
|
self.assertEqual(wraps[0].get('source_hash'), '8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb') |
|
self.assertEqual(wraps[1].name, 'bar-0.1-rs') |
|
self.assertEqual(wraps[1].directory, 'bar') |
|
self.assertEqual(wraps[1].type, 'git') |
|
self.assertEqual(wraps[1].get('method'), 'cargo') |
|
self.assertEqual(wraps[1].get('url'), 'https://github.com/gtk-rs/gtk-rs-core') |
|
self.assertEqual(wraps[1].get('revision'), '23c5599424cc75ec66618891c915d9f490f6e4c2')
|
|
|