trivet 3.1.0

The trivet Parser Library
Documentation
// Trivet
// Copyright (c) 2025 by Stacy Prowell.  All rights reserved.
// https://gitlab.com/binary-tools/trivet

//! Tests for comment parsing.

use crate::parse_from_string;
use crate::parsers::comments::CommentParser;
use crate::ParserCore;

/// A collection of comments and non-comments.
const COMMENTS: &str = r#"
    /*
    This is a multi-line C-style comment.

    * Is is pretty normal to start each line of such a comment with an asterisk.
    * This is, of course, not necessary.  Here is another comment start: /*.  It
    * should be ignored.  Here is a not-quite comment end, that should also be
    * ignored: * /.
    */
    not_a_comment_1
    /**/not_a_comment_2

    //
    // This is a single line comment.  It is the usual form for C++ comments, and
    // nearly all comments in Rust code.
    //
    not_a_comment_3

    ############
    ## This is a Python comment.
    ## Lots of languages use this comment form.
    ############
    not_a_comment_4

    <!---->
    <!-- This is the XML and HTML comment form.  Also SGML, probably.
      -- It can run over several lines, and does not nest.  So <!--
      -- does nothing. -->not_a_comment_5
    
    <#
    For some reason PowerShell has multi-line comments.
    #>not_a_comment_6

    -- This is a single-line Lua comment.
    not_a_comment_7

    --[[
        This is a multi-line Lua comment.  ]]  It should
        not be confused by parts -- being present in the
        comment --] itself.
    --]] not_a_comment_8

    ---[[ This is, confusingly, a single-line Lua comment.
    not_a_comment_9"#;

#[test]
fn comments() {
    let mut parser = parse_from_string(COMMENTS);

    // Turn on all comment forms.
    let compar = CommentParser {
        enable_powershell: true,
        enable_python: true,
        enable_xml: true,
        enable_custom: true,
        custom: Box::new(|parser: &mut ParserCore| -> bool {
            // This implements parsing Lua comments.  These are a bit unusual,
            // due to the "greedy" nature of the comment delimiter.
            if parser.peek_and_consume_chars(&['-', '-', '[', '[']) {
                parser.take_until("--]]");
                return true;
            } else if parser.peek_and_consume_chars(&['-', '-']) {
                parser.take_while(|ch| ch != '\n');
                return true;
            }
            false
        }),
        ..Default::default()
    };

    // Install our comment parser.
    parser.replace_comment_parser(compar);

    // Now try to process the entire comment block.  When done we should only see the
    // "not_a_comment_N" entries.
    let mut counter = 1;
    while !parser.is_at_eof() {
        // Keep going until we reach the end.
        parser.consume_ws();
        // Check for the end marker.  It must be next if things are correct.
        let marker = format!("not_a_comment_{}", counter);
        counter += 1;
        assert!(parser.peek_and_consume_str(&marker));
    }
    assert_eq!(counter, 10);
}

#[test]
fn default_custom_test() {
    let mut parser = parse_from_string(COMMENTS);

    // Enable custom parsing but do not override the default.  Turn off other forms.
    let compar = CommentParser {
        enable_custom: true,
        enable_c: false,
        enable_cpp: false,
        enable_powershell: false,
        enable_python: false,
        enable_xml: false,
        ..Default::default()
    };

    // Install our comment parser.
    parser.replace_comment_parser(compar);

    // Now try to process a comment.  This should fail.
    parser.consume_ws_only();
    let next = parser.peek_n(10);
    parser.consume_ws();
    assert_eq!(next, parser.peek_n(10));
}