use super::super::{parse_invocation, ParsedInvocation};
use super::args;
use crate::core::NormalizedPath;
#[test]
fn pch_default_output_clang() {
let result = parse_invocation("clang++", &args(&["-x", "c++-header", "src/pch.h"]));
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.source_file, NormalizedPath::new("src/pch.h"));
assert_eq!(c.output_file, NormalizedPath::new("pch.h.pch"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn pch_default_output_gcc() {
let result = parse_invocation("gcc", &args(&["-x", "c-header", "src/pch.h"]));
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.source_file, NormalizedPath::new("src/pch.h"));
assert_eq!(c.output_file, NormalizedPath::new("pch.h.gch"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn pch_default_output_strips_directory() {
let result = parse_invocation(
"clang++",
&args(&["-x", "c++-header", "src/fl/audio/fft/fft.h"]),
);
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.source_file, NormalizedPath::new("src/fl/audio/fft/fft.h"));
assert_eq!(c.output_file, NormalizedPath::new("fft.h.pch"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn pch_default_output_absolute_path_strips_to_filename() {
let result = parse_invocation(
"clang++",
&args(&["-x", "c++-header", "/abs/path/src/pch.h"]),
);
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.source_file, NormalizedPath::new("/abs/path/src/pch.h"));
assert_eq!(c.output_file, NormalizedPath::new("pch.h.pch"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn pch_default_output_explicit_o_unchanged() {
let result = parse_invocation(
"clang++",
&args(&["-x", "c++-header", "pch.h", "-o", "build/pch.h.pch"]),
);
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.source_file, NormalizedPath::new("pch.h"));
assert_eq!(c.output_file, NormalizedPath::new("build/pch.h.pch"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn normal_compile_default_output_unchanged() {
let result = parse_invocation("gcc", &args(&["-c", "foo.cpp"]));
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.output_file, NormalizedPath::new("foo.o"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn concatenated_o_flag_parsed() {
let result = parse_invocation("clang", &args(&["-c", "foo.cpp", "-obuild/foo.o"]));
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.output_file, NormalizedPath::new("build/foo.o"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn concatenated_o_flag_pch() {
let result = parse_invocation(
"clang++",
&args(&["-x", "c++-header", "pch.h", "-obuild/pch.h.pch"]),
);
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.output_file, NormalizedPath::new("build/pch.h.pch"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn all_flags_preserved() {
let input = args(&[
"-c",
"foo.cpp",
"-o",
"foo.o",
"-Wall",
"-Wextra",
"-O2",
"-Xclang",
"-fno-spell-checking",
"-std=c++17",
"-DFOO=bar",
"-I/usr/include",
"-isystem",
"/usr/local/include",
"-unknown-future-flag",
]);
let result = parse_invocation("clang++", &input);
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.source_file, NormalizedPath::new("foo.cpp"));
assert_eq!(c.output_file, NormalizedPath::new("foo.o"));
assert!(c.unknown_flags.contains(&"-Wall".to_string()));
assert!(c.unknown_flags.contains(&"-Wextra".to_string()));
assert!(c.unknown_flags.contains(&"-O2".to_string()));
assert!(c
.unknown_flags
.contains(&"-unknown-future-flag".to_string()));
assert!(c.unknown_flags.contains(&"-std=c++17".to_string()));
assert!(c.unknown_flags.contains(&"-DFOO=bar".to_string()));
assert!(c.unknown_flags.contains(&"-I/usr/include".to_string()));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn xclang_value_not_misidentified_as_source() {
let result = parse_invocation(
"clang++",
&args(&[
"-c",
"foo.cpp",
"-Xclang",
"-fno-spell-checking",
"-o",
"foo.o",
]),
);
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.source_file, NormalizedPath::new("foo.cpp"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn mllvm_value_not_misidentified_as_source() {
let result = parse_invocation(
"clang++",
&args(&["-c", "foo.cpp", "-mllvm", "-some-llvm-opt", "-o", "foo.o"]),
);
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.source_file, NormalizedPath::new("foo.cpp"));
}
other => panic!("expected cacheable, got: {other:?}"),
}
}
#[test]
fn pch_output_path_mismatch_repro() {
let result = parse_invocation(
"clang++",
&args(&["-x", "c++-header", "src/fl/fx/2d/flowfield_q31.h"]),
);
match result {
ParsedInvocation::Cacheable(c) => {
assert_eq!(c.output_file, NormalizedPath::new("flowfield_q31.h.pch"));
assert_eq!(
c.source_file,
NormalizedPath::new("src/fl/fx/2d/flowfield_q31.h")
);
}
other => panic!("expected cacheable, got: {other:?}"),
}
}