use super::*;

fn filename(sm: &SourceMap, path: &str) -> FileName {
    FileName::Real(sm.path_mapping().to_real_filename(sm.working_dir(), PathBuf::from(path)))
}

fn init_source_map() -> SourceMap {
    let sm = SourceMap::new(FilePathMapping::empty());
    sm.new_source_file(filename(&sm, "blork.rs"), "first line.\nsecond line".to_string());
    sm.new_source_file(filename(&sm, "empty.rs"), String::new());
    sm.new_source_file(filename(&sm, "blork2.rs"), "first line.\nsecond line".to_string());
    sm
}

impl SourceMap {
    /// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If
    /// there are gaps between LHS and RHS, the resulting union will cross these gaps.
    /// For this to work,
    ///
    ///    * the syntax contexts of both spans much match,
    ///    * the LHS span needs to end on the same line the RHS span begins,
    ///    * the LHS span must start at or before the RHS span.
    fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span> {
        // Ensure we're at the same expansion ID.
        if !sp_lhs.eq_ctxt(sp_rhs) {
            return None;
        }

        let lhs_end = match self.lookup_line(sp_lhs.hi()) {
            Ok(x) => x,
            Err(_) => return None,
        };
        let rhs_begin = match self.lookup_line(sp_rhs.lo()) {
            Ok(x) => x,
            Err(_) => return None,
        };

        // If we must cross lines to merge, don't merge.
        if lhs_end.line != rhs_begin.line {
            return None;
        }

        // Ensure these follow the expected order and that we don't overlap.
        if (sp_lhs.lo() <= sp_rhs.lo()) && (sp_lhs.hi() <= sp_rhs.lo()) {
            Some(sp_lhs.to(sp_rhs))
        } else {
            None
        }
    }

    /// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`.
    fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
        let idx = self.lookup_source_file_idx(bpos);
        let sf = &(*self.files.borrow().source_files)[idx];
        let bpos = sf.relative_position(bpos);
        sf.bytepos_to_file_charpos(bpos)
    }
}

/// Tests `lookup_byte_offset`.
#[test]
fn t3() {
    let sm = init_source_map();

    let srcfbp1 = sm.lookup_byte_offset(BytePos(23));
    assert_eq!(srcfbp1.sf.name, filename(&sm, "blork.rs"));
    assert_eq!(srcfbp1.pos, BytePos(23));

    let srcfbp1 = sm.lookup_byte_offset(BytePos(24));
    assert_eq!(srcfbp1.sf.name, filename(&sm, "empty.rs"));
    assert_eq!(srcfbp1.pos, BytePos(0));

    let srcfbp2 = sm.lookup_byte_offset(BytePos(25));
    assert_eq!(srcfbp2.sf.name, filename(&sm, "blork2.rs"));
    assert_eq!(srcfbp2.pos, BytePos(0));
}

/// Tests `bytepos_to_file_charpos`.
#[test]
fn t4() {
    let sm = init_source_map();

    let cp1 = sm.bytepos_to_file_charpos(BytePos(22));
    assert_eq!(cp1, CharPos(22));

    let cp2 = sm.bytepos_to_file_charpos(BytePos(25));
    assert_eq!(cp2, CharPos(0));
}

/// Tests zero-length `SourceFile`s.
#[test]
fn t5() {
    let sm = init_source_map();

    let loc1 = sm.lookup_char_pos(BytePos(22));
    assert_eq!(loc1.file.name, filename(&sm, "blork.rs"));
    assert_eq!(loc1.line, 2);
    assert_eq!(loc1.col, CharPos(10));

    let loc2 = sm.lookup_char_pos(BytePos(25));
    assert_eq!(loc2.file.name, filename(&sm, "blork2.rs"));
    assert_eq!(loc2.line, 1);
    assert_eq!(loc2.col, CharPos(0));
}

fn init_source_map_mbc() -> SourceMap {
    let sm = SourceMap::new(FilePathMapping::empty());
    // "€" is a three-byte UTF8 char.
    sm.new_source_file(filename(&sm, "blork.rs"), "fir€st €€€€ line.\nsecond line".to_string());
    sm.new_source_file(filename(&sm, "blork2.rs"), "first line€€.\n€ second line".to_string());
    sm
}

/// Tests `bytepos_to_file_charpos` in the presence of multi-byte chars.
#[test]
fn t6() {
    let sm = init_source_map_mbc();

    let cp1 = sm.bytepos_to_file_charpos(BytePos(3));
    assert_eq!(cp1, CharPos(3));

    let cp2 = sm.bytepos_to_file_charpos(BytePos(6));
    assert_eq!(cp2, CharPos(4));

    let cp3 = sm.bytepos_to_file_charpos(BytePos(56));
    assert_eq!(cp3, CharPos(12));

    let cp4 = sm.bytepos_to_file_charpos(BytePos(61));
    assert_eq!(cp4, CharPos(15));
}

/// Test `span_to_lines` for a span ending at the end of a `SourceFile`.
#[test]
fn t7() {
    let sm = init_source_map();
    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
    let file_lines = sm.span_to_lines(span).unwrap();

    assert_eq!(file_lines.file.name, filename(&sm, "blork.rs"));
    assert_eq!(file_lines.lines.len(), 1);
    assert_eq!(file_lines.lines[0].line_index, 1);
}

/// Given a string like " ~~~~~~~~~~~~ ", produces a span
/// converting that range. The idea is that the string has the same
/// length as the input, and we uncover the byte positions. Note
/// that this can span lines and so on.
fn span_from_selection(input: &str, selection: &str) -> Span {
    assert_eq!(input.len(), selection.len());
    let left_index = selection.find('~').unwrap() as u32;
    let right_index = selection.rfind('~').map_or(left_index, |x| x as u32);
    Span::with_root_ctxt(BytePos(left_index), BytePos(right_index + 1))
}

/// Tests `span_to_snippet` and `span_to_lines` for a span converting 3
/// lines in the middle of a file.
#[test]
fn span_to_snippet_and_lines_spanning_multiple_lines() {
    let sm = SourceMap::new(FilePathMapping::empty());
    let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
    let selection = "     \n    ~~\n~~~\n~~~~~     \n   \n";
    sm.new_source_file(filename(&sm, "blork.rs"), inputtext.to_string());
    let span = span_from_selection(inputtext, selection);

    // Check that we are extracting the text we thought we were extracting.
    assert_eq!(&sm.span_to_snippet(span).unwrap(), "BB\nCCC\nDDDDD");

    // Check that span_to_lines gives us the complete result with the lines/cols we expected.
    let lines = sm.span_to_lines(span).unwrap();
    let expected = vec![
        LineInfo { line_index: 1, start_col: CharPos(4), end_col: CharPos(6) },
        LineInfo { line_index: 2, start_col: CharPos(0), end_col: CharPos(3) },
        LineInfo { line_index: 3, start_col: CharPos(0), end_col: CharPos(5) },
    ];
    assert_eq!(lines.lines, expected);
}

/// Test span_to_snippet for a span ending at the end of a `SourceFile`.
#[test]
fn t8() {
    let sm = init_source_map();
    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
    let snippet = sm.span_to_snippet(span);

    assert_eq!(snippet, Ok("second line".to_string()));
}

/// Test `span_to_str` for a span ending at the end of a `SourceFile`.
#[test]
fn t9() {
    let sm = init_source_map();
    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
    let sstr = sm.span_to_diagnostic_string(span);

    assert_eq!(sstr, "blork.rs:2:1: 2:12");
}

/// Tests failing to merge two spans on different lines.
#[test]
fn span_merging_fail() {
    let sm = SourceMap::new(FilePathMapping::empty());
    let inputtext = "bbbb BB\ncc CCC\n";
    let selection1 = "     ~~\n      \n";
    let selection2 = "       \n   ~~~\n";
    sm.new_source_file(filename(&sm, "blork.rs"), inputtext.to_owned());
    let span1 = span_from_selection(inputtext, selection1);
    let span2 = span_from_selection(inputtext, selection2);

    assert!(sm.merge_spans(span1, span2).is_none());
}

/// Tests loading an external source file that requires normalization.
#[test]
fn t10() {
    let sm = SourceMap::new(FilePathMapping::empty());
    let unnormalized = "first line.\r\nsecond line";
    let normalized = "first line.\nsecond line";

    let src_file = sm.new_source_file(filename(&sm, "blork.rs"), unnormalized.to_string());

    assert_eq!(src_file.src.as_ref().unwrap().as_ref(), normalized);
    assert!(
        src_file.src_hash.matches(unnormalized),
        "src_hash should use the source before normalization"
    );

    let SourceFile {
        name,
        src_hash,
        checksum_hash,
        normalized_source_len,
        unnormalized_source_len,
        lines,
        multibyte_chars,
        normalized_pos,
        stable_id,
        ..
    } = (*src_file).clone();

    let imported_src_file = sm.new_imported_source_file(
        name,
        src_hash,
        checksum_hash,
        stable_id,
        normalized_source_len.to_u32(),
        unnormalized_source_len,
        CrateNum::ZERO,
        FreezeLock::new(lines.read().clone()),
        multibyte_chars,
        normalized_pos,
        0,
    );

    assert!(
        imported_src_file.external_src.borrow().get_source().is_none(),
        "imported source file should not have source yet"
    );
    imported_src_file.add_external_src(|| Some(unnormalized.to_string()));
    assert_eq!(
        imported_src_file.external_src.borrow().get_source().unwrap(),
        normalized,
        "imported source file should be normalized"
    );
}

// Takes a unix-style path and returns a platform specific path.
fn path(p: &str) -> PathBuf {
    path_str(p).into()
}

// Takes a unix-style path and returns a platform specific path.
fn path_str(p: &str) -> String {
    #[cfg(not(windows))]
    {
        return p.into();
    }

    #[cfg(windows)]
    {
        let mut path = p.replace('/', "\\");
        if let Some(rest) = path.strip_prefix('\\') {
            path = ["X:\\", rest].concat();
        }

        path
    }
}

fn map_path_prefix(mapping: &FilePathMapping, p: &str) -> String {
    // It's important that we convert to a string here because that's what
    // later stages do too (e.g. in the backend), and comparing `Path` values
    // won't catch some differences at the string level, e.g. "abc" and "abc/"
    // compare as equal.
    mapping.map_prefix(path(p)).0.to_string_lossy().to_string()
}

fn reverse_map_prefix(mapping: &FilePathMapping, p: &str) -> Option<String> {
    mapping.reverse_map_prefix_heuristically(&path(p)).map(|q| q.to_string_lossy().to_string())
}

#[test]
fn path_prefix_remapping() {
    // Relative to relative
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc/def"), path("foo"))],
            RemapPathScopeComponents::all(),
        );

        assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("foo/src/main.rs"));
        assert_eq!(map_path_prefix(mapping, "abc/def"), path_str("foo"));
    }

    // Relative to absolute
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc/def"), path("/foo"))],
            RemapPathScopeComponents::all(),
        );

        assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("/foo/src/main.rs"));
        assert_eq!(map_path_prefix(mapping, "abc/def"), path_str("/foo"));
    }

    // Absolute to relative
    {
        let mapping = &FilePathMapping::new(
            vec![(path("/abc/def"), path("foo"))],
            RemapPathScopeComponents::all(),
        );

        assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("foo/src/main.rs"));
        assert_eq!(map_path_prefix(mapping, "/abc/def"), path_str("foo"));
    }

    // Absolute to absolute
    {
        let mapping = &FilePathMapping::new(
            vec![(path("/abc/def"), path("/foo"))],
            RemapPathScopeComponents::all(),
        );

        assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("/foo/src/main.rs"));
        assert_eq!(map_path_prefix(mapping, "/abc/def"), path_str("/foo"));
    }
}

#[test]
fn to_real_filename_with_full_scopes() {
    // "virtual" working directory is relative path
    let mapping = &FilePathMapping::new(
        vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))],
        RemapPathScopeComponents::all(),
    );
    let working_directory = path("/foo");
    let working_directory = mapping.to_real_filename(&RealFileName::empty(), working_directory);

    assert_eq!(working_directory.path(RemapPathScopeComponents::DIAGNOSTICS), path("FOO"));
    assert_eq!(working_directory.path(RemapPathScopeComponents::MACRO), path("FOO"));
    assert_eq!(working_directory.path(RemapPathScopeComponents::DEBUGINFO), path("FOO"));

    // Absolute path
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("/foo/src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("/foo/src/main.rs"),
                working_directory: path("/foo"),
                embeddable_name: path("/foo/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("FOO/src/main.rs"),
                working_directory: path("FOO"),
                embeddable_name: path("FOO/src/main.rs")
            },
            scopes: RemapPathScopeComponents::all()
        }
    );

    // Absolute path with unrelated working directory
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("/bar/src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("/bar/src/main.rs"),
                working_directory: path("/foo"),
                embeddable_name: path("/bar/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("BAR/src/main.rs"),
                working_directory: path("FOO"),
                embeddable_name: path("BAR/src/main.rs")
            },
            scopes: RemapPathScopeComponents::all()
        }
    );

    // Absolute path that does not match any prefix
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("/quux/src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("/quux/src/main.rs"),
                working_directory: path("/foo"),
                embeddable_name: path("/quux/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("/quux/src/main.rs"),
                working_directory: path("FOO"),
                embeddable_name: path("/quux/src/main.rs")
            },
            scopes: RemapPathScopeComponents::all()
        }
    );

    // Relative path
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("src/main.rs"),
                working_directory: path("/foo"),
                embeddable_name: path("/foo/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("src/main.rs"),
                working_directory: path("FOO"),
                embeddable_name: path("FOO/src/main.rs")
            },
            scopes: RemapPathScopeComponents::all()
        }
    );

    // Relative path with `./`
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("./src/main.rs"),),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("./src/main.rs"),
                working_directory: path("/foo"),
                embeddable_name: path("/foo/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("./src/main.rs"),
                working_directory: path("FOO"),
                embeddable_name: path("FOO/src/main.rs")
            },
            scopes: RemapPathScopeComponents::all()
        }
    );

    // Relative path that does not match any prefix
    assert_eq!(
        mapping.to_real_filename(
            &mapping.to_real_filename(&RealFileName::empty(), path("/abc")),
            path("quux/src/main.rs"),
        ),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("quux/src/main.rs"),
                working_directory: path("/abc"),
                embeddable_name: path("/abc/quux/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("quux/src/main.rs"),
                working_directory: path("/abc"),
                embeddable_name: path("/abc/quux/src/main.rs")
            },
            scopes: RemapPathScopeComponents::empty()
        }
    );
}

#[test]
fn to_real_filename_with_mixed_scopes() {
    // "virtual" working directory is relative path
    let mapping = &FilePathMapping::new(
        vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))],
        RemapPathScopeComponents::OBJECT,
    );
    let working_directory = path("/foo");
    let working_directory = mapping.to_real_filename(&RealFileName::empty(), working_directory);

    assert_eq!(working_directory.path(RemapPathScopeComponents::DIAGNOSTICS), path("/foo"));
    assert_eq!(working_directory.path(RemapPathScopeComponents::MACRO), path("FOO"));
    assert_eq!(working_directory.path(RemapPathScopeComponents::DEBUGINFO), path("FOO"));

    // Absolute path
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("/foo/src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("/foo/src/main.rs"),
                working_directory: path("/foo"),
                embeddable_name: path("/foo/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("FOO/src/main.rs"),
                working_directory: path("FOO"),
                embeddable_name: path("FOO/src/main.rs")
            },
            scopes: RemapPathScopeComponents::OBJECT
        }
    );

    // Absolute path with unrelated working directory
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("/bar/src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("/bar/src/main.rs"),
                working_directory: path("/foo"),
                embeddable_name: path("/bar/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("BAR/src/main.rs"),
                working_directory: path("FOO"),
                embeddable_name: path("BAR/src/main.rs")
            },
            scopes: RemapPathScopeComponents::OBJECT
        }
    );

    // Absolute path without remapping
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("/quux/src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("/quux/src/main.rs"),
                working_directory: path("/foo"),
                embeddable_name: path("/quux/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("/quux/src/main.rs"),
                working_directory: path("FOO"),
                embeddable_name: path("/quux/src/main.rs")
            },
            scopes: RemapPathScopeComponents::OBJECT
        }
    );

    // Relative path
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("src/main.rs"),
                working_directory: path("/foo"),
                embeddable_name: path("/foo/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("src/main.rs"),
                working_directory: path("FOO"),
                embeddable_name: path("FOO/src/main.rs")
            },
            scopes: RemapPathScopeComponents::OBJECT
        }
    );

    // Relative path that does not match any prefix
    assert_eq!(
        mapping.to_real_filename(
            &mapping.to_real_filename(&RealFileName::empty(), path("/abc")),
            path("quux/src/main.rs"),
        ),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("quux/src/main.rs"),
                working_directory: path("/abc"),
                embeddable_name: path("/abc/quux/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("quux/src/main.rs"),
                working_directory: path("/abc"),
                embeddable_name: path("/abc/quux/src/main.rs")
            },
            scopes: RemapPathScopeComponents::empty()
        }
    );
}
#[test]
fn to_real_filename_without_remapped_cwd() {
    // "virtual" working directory is relative path
    let mapping = &FilePathMapping::new(
        vec![(path("/foo"), path("FOO")), (path("/cwd/bar"), path("CWDBAR"))],
        RemapPathScopeComponents::OBJECT,
    );
    let working_directory = path("/cwd");
    let working_directory = mapping.to_real_filename(&RealFileName::empty(), working_directory);

    assert_eq!(working_directory.path(RemapPathScopeComponents::DIAGNOSTICS), path("/cwd"));
    assert_eq!(working_directory.path(RemapPathScopeComponents::MACRO), path("/cwd"));
    assert_eq!(working_directory.path(RemapPathScopeComponents::DEBUGINFO), path("/cwd"));

    // Absolute path
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("/foo/src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("/foo/src/main.rs"),
                working_directory: path("/cwd"),
                embeddable_name: path("/foo/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("FOO/src/main.rs"),
                working_directory: path("/cwd"),
                embeddable_name: path("FOO/src/main.rs")
            },
            scopes: RemapPathScopeComponents::OBJECT
        }
    );

    // Absolute path with unrelated root
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("/bar/src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("/bar/src/main.rs"),
                working_directory: path("/cwd"),
                embeddable_name: path("/bar/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("/bar/src/main.rs"),
                working_directory: path("/cwd"),
                embeddable_name: path("/bar/src/main.rs")
            },
            scopes: RemapPathScopeComponents::empty()
        }
    );

    // Absolute path with cwd
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("/cwd/bar/src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("/cwd/bar/src/main.rs"),
                working_directory: path("/cwd"),
                embeddable_name: path("/cwd/bar/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("CWDBAR/src/main.rs"),
                working_directory: path("/cwd"),
                embeddable_name: path("CWDBAR/src/main.rs")
            },
            scopes: RemapPathScopeComponents::OBJECT
        }
    );

    // Relative path
    assert_eq!(
        mapping.to_real_filename(&working_directory, path("src/main.rs")),
        RealFileName {
            local: Some(InnerRealFileName {
                name: path("src/main.rs"),
                working_directory: path("/cwd"),
                embeddable_name: path("/cwd/src/main.rs")
            }),
            maybe_remapped: InnerRealFileName {
                name: path("src/main.rs"),
                working_directory: path("/cwd"),
                embeddable_name: path("/cwd/src/main.rs")
            },
            scopes: RemapPathScopeComponents::empty()
        }
    );
}

#[test]
fn path_prefix_remapping_reverse() {
    // Ignores options without alphanumeric chars.
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc"), path("/")), (path("def"), path("."))],
            RemapPathScopeComponents::all(),
        );

        assert_eq!(reverse_map_prefix(mapping, "/hello.rs"), None);
        assert_eq!(reverse_map_prefix(mapping, "./hello.rs"), None);
    }

    // Returns `None` if multiple options match.
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc"), path("/redacted")), (path("def"), path("/redacted"))],
            RemapPathScopeComponents::all(),
        );

        assert_eq!(reverse_map_prefix(mapping, "/redacted/hello.rs"), None);
    }

    // Distinct reverse mappings.
    {
        let mapping = &FilePathMapping::new(
            vec![(path("abc"), path("/redacted")), (path("def/ghi"), path("/fake/dir"))],
            RemapPathScopeComponents::all(),
        );

        assert_eq!(
            reverse_map_prefix(mapping, "/redacted/path/hello.rs"),
            Some(path_str("abc/path/hello.rs"))
        );
        assert_eq!(
            reverse_map_prefix(mapping, "/fake/dir/hello.rs"),
            Some(path_str("def/ghi/hello.rs"))
        );
    }
}

#[test]
fn test_next_point() {
    let sm = SourceMap::new(FilePathMapping::empty());
    sm.new_source_file(filename(&sm, "example.rs"), "a…b".to_string());

    // Dummy spans don't advance.
    let span = DUMMY_SP;
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 0);
    assert_eq!(span.hi().0, 0);

    // Span advance respect multi-byte character
    let span = Span::with_root_ctxt(BytePos(0), BytePos(1));
    assert_eq!(sm.span_to_snippet(span), Ok("a".to_string()));
    let span = sm.next_point(span);
    assert_eq!(sm.span_to_snippet(span), Ok("…".to_string()));
    assert_eq!(span.lo().0, 1);
    assert_eq!(span.hi().0, 4);

    // An empty span pointing just before a multi-byte character should
    // advance to contain the multi-byte character.
    let span = Span::with_root_ctxt(BytePos(1), BytePos(1));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 1);
    assert_eq!(span.hi().0, 4);

    let span = Span::with_root_ctxt(BytePos(1), BytePos(4));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 4);
    assert_eq!(span.hi().0, 5);

    // Reaching to the end of file, return a span that will get error with `span_to_snippet`
    let span = Span::with_root_ctxt(BytePos(4), BytePos(5));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 5);
    assert_eq!(span.hi().0, 6);
    assert!(sm.span_to_snippet(span).is_err());

    // Reaching to the end of file, return a span that will get error with `span_to_snippet`
    let span = Span::with_root_ctxt(BytePos(5), BytePos(5));
    let span = sm.next_point(span);
    assert_eq!(span.lo().0, 5);
    assert_eq!(span.hi().0, 6);
    assert!(sm.span_to_snippet(span).is_err());
}

#[cfg(target_os = "linux")]
#[test]
fn read_binary_file_handles_lying_stat() {
    // read_binary_file tries to read the contents of a file into an Arc<[u8]> while
    // never having two copies of the data in memory at once. This is an optimization
    // to support include_bytes! with large files. But since Rust allocators are
    // sensitive to alignment, our implementation can't be bootstrapped off calling
    // std::fs::read. So we test that we have the same behavior even on files where
    // fs::metadata lies.

    // stat always says that /proc/self/cmdline is length 0, but it isn't.
    let cmdline = Path::new("/proc/self/cmdline");
    let len = std::fs::metadata(cmdline).unwrap().len() as usize;
    let real = std::fs::read(cmdline).unwrap();
    assert!(len < real.len());
    let bin = RealFileLoader.read_binary_file(cmdline).unwrap();
    assert_eq!(&real[..], &bin[..]);

    // stat always says that /sys/devices/system/cpu/kernel_max is the size of a block.
    let kernel_max = Path::new("/sys/devices/system/cpu/kernel_max");
    let len = std::fs::metadata(kernel_max).unwrap().len() as usize;
    let real = std::fs::read(kernel_max).unwrap();
    assert!(len > real.len());
    let bin = RealFileLoader.read_binary_file(kernel_max).unwrap();
    assert_eq!(&real[..], &bin[..]);
}
