1 | # -*- coding: utf-8 -*- |
2 | # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
3 | # See https://llvm.org/LICENSE.txt for license information. |
4 | # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
5 | |
6 | import libscanbuild.compilation as sut |
7 | import unittest |
8 | |
9 | |
10 | class CompilerTest(unittest.TestCase): |
11 | |
12 | def test_is_compiler_call(self): |
13 | self.assertIsNotNone(sut.compiler_language(['clang'])) |
14 | self.assertIsNotNone(sut.compiler_language(['clang-3.6'])) |
15 | self.assertIsNotNone(sut.compiler_language(['clang++'])) |
16 | self.assertIsNotNone(sut.compiler_language(['clang++-3.5.1'])) |
17 | self.assertIsNotNone(sut.compiler_language(['cc'])) |
18 | self.assertIsNotNone(sut.compiler_language(['c++'])) |
19 | self.assertIsNotNone(sut.compiler_language(['gcc'])) |
20 | self.assertIsNotNone(sut.compiler_language(['g++'])) |
21 | self.assertIsNotNone(sut.compiler_language(['/usr/local/bin/gcc'])) |
22 | self.assertIsNotNone(sut.compiler_language(['/usr/local/bin/g++'])) |
23 | self.assertIsNotNone(sut.compiler_language(['/usr/local/bin/clang'])) |
24 | self.assertIsNotNone( |
25 | sut.compiler_language(['armv7_neno-linux-gnueabi-g++'])) |
26 | |
27 | self.assertIsNone(sut.compiler_language([])) |
28 | self.assertIsNone(sut.compiler_language([''])) |
29 | self.assertIsNone(sut.compiler_language(['ld'])) |
30 | self.assertIsNone(sut.compiler_language(['as'])) |
31 | self.assertIsNone(sut.compiler_language(['/usr/local/bin/compiler'])) |
32 | |
33 | |
34 | class SplitTest(unittest.TestCase): |
35 | |
36 | def test_detect_cxx_from_compiler_name(self): |
37 | def test(cmd): |
38 | result = sut.split_command([cmd, '-c', 'src.c']) |
39 | self.assertIsNotNone(result, "wrong input for test") |
40 | return result.compiler == 'c++' |
41 | |
42 | self.assertFalse(test('cc')) |
43 | self.assertFalse(test('gcc')) |
44 | self.assertFalse(test('clang')) |
45 | |
46 | self.assertTrue(test('c++')) |
47 | self.assertTrue(test('g++')) |
48 | self.assertTrue(test('g++-5.3.1')) |
49 | self.assertTrue(test('clang++')) |
50 | self.assertTrue(test('clang++-3.7.1')) |
51 | self.assertTrue(test('armv7_neno-linux-gnueabi-g++')) |
52 | |
53 | def test_action(self): |
54 | self.assertIsNotNone(sut.split_command(['clang', 'source.c'])) |
55 | self.assertIsNotNone(sut.split_command(['clang', '-c', 'source.c'])) |
56 | self.assertIsNotNone(sut.split_command(['clang', '-c', 'source.c', |
57 | '-MF', 'a.d'])) |
58 | |
59 | self.assertIsNone(sut.split_command(['clang', '-E', 'source.c'])) |
60 | self.assertIsNone(sut.split_command(['clang', '-c', '-E', 'source.c'])) |
61 | self.assertIsNone(sut.split_command(['clang', '-c', '-M', 'source.c'])) |
62 | self.assertIsNone( |
63 | sut.split_command(['clang', '-c', '-MM', 'source.c'])) |
64 | |
65 | def test_source_file(self): |
66 | def test(expected, cmd): |
67 | self.assertEqual(expected, sut.split_command(cmd).files) |
68 | |
69 | test(['src.c'], ['clang', 'src.c']) |
70 | test(['src.c'], ['clang', '-c', 'src.c']) |
71 | test(['src.C'], ['clang', '-x', 'c', 'src.C']) |
72 | test(['src.cpp'], ['clang++', '-c', 'src.cpp']) |
73 | test(['s1.c', 's2.c'], ['clang', '-c', 's1.c', 's2.c']) |
74 | test(['s1.c', 's2.c'], ['cc', 's1.c', 's2.c', '-ldep', '-o', 'a.out']) |
75 | test(['src.c'], ['clang', '-c', '-I', './include', 'src.c']) |
76 | test(['src.c'], ['clang', '-c', '-I', '/opt/me/include', 'src.c']) |
77 | test(['src.c'], ['clang', '-c', '-D', 'config=file.c', 'src.c']) |
78 | |
79 | self.assertIsNone( |
80 | sut.split_command(['cc', 'this.o', 'that.o', '-o', 'a.out'])) |
81 | self.assertIsNone( |
82 | sut.split_command(['cc', 'this.o', '-lthat', '-o', 'a.out'])) |
83 | |
84 | def test_filter_flags(self): |
85 | def test(expected, flags): |
86 | command = ['clang', '-c', 'src.c'] + flags |
87 | self.assertEqual(expected, sut.split_command(command).flags) |
88 | |
89 | def same(expected): |
90 | test(expected, expected) |
91 | |
92 | def filtered(flags): |
93 | test([], flags) |
94 | |
95 | same([]) |
96 | same(['-I', '/opt/me/include', '-DNDEBUG', '-ULIMITS']) |
97 | same(['-O', '-O2']) |
98 | same(['-m32', '-mmms']) |
99 | same(['-Wall', '-Wno-unused', '-g', '-funroll-loops']) |
100 | |
101 | filtered([]) |
102 | filtered(['-lclien', '-L/opt/me/lib', '-L', '/opt/you/lib']) |
103 | filtered(['-static']) |
104 | filtered(['-MD', '-MT', 'something']) |
105 | filtered(['-MMD', '-MF', 'something']) |
106 | |
107 | |
108 | class SourceClassifierTest(unittest.TestCase): |
109 | |
110 | def test_sources(self): |
111 | self.assertIsNone(sut.classify_source('file.o')) |
112 | self.assertIsNone(sut.classify_source('file.exe')) |
113 | self.assertIsNone(sut.classify_source('/path/file.o')) |
114 | self.assertIsNone(sut.classify_source('clang')) |
115 | |
116 | self.assertEqual('c', sut.classify_source('file.c')) |
117 | self.assertEqual('c', sut.classify_source('./file.c')) |
118 | self.assertEqual('c', sut.classify_source('/path/file.c')) |
119 | self.assertEqual('c++', sut.classify_source('file.c', False)) |
120 | self.assertEqual('c++', sut.classify_source('./file.c', False)) |
121 | self.assertEqual('c++', sut.classify_source('/path/file.c', False)) |
122 | |