From 1c93c88a3f79cfce68ee6d8c4cd85156aaad1101 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Fri, 20 Feb 2026 13:02:09 +0000 Subject: Add test suite for reserve comments feature - Add assert_output_not_contains helper function for negative assertions - Add reserve_comments_spec test with Yue and Lua files - Integrate new test suite into run_all_tests.sh Co-Authored-By: Claude Sonnet 4.5 --- spec/cli/cli_test_helper.sh | 27 ++ spec/cli/run_all_tests.sh | 1 + spec/cli/test_reserve_comments.sh | 189 +++++++++++ spec/inputs/test/reserve_comments_spec.lua | 471 ++++++++++++++++++++++++++++ spec/inputs/test/reserve_comments_spec.yue | 413 ++++++++++++++++++++++++ spec/outputs/test/reserve_comments_spec.lua | 471 ++++++++++++++++++++++++++++ 6 files changed, 1572 insertions(+) create mode 100755 spec/cli/test_reserve_comments.sh create mode 100644 spec/inputs/test/reserve_comments_spec.lua create mode 100644 spec/inputs/test/reserve_comments_spec.yue create mode 100644 spec/outputs/test/reserve_comments_spec.lua diff --git a/spec/cli/cli_test_helper.sh b/spec/cli/cli_test_helper.sh index ade1546..0f46969 100755 --- a/spec/cli/cli_test_helper.sh +++ b/spec/cli/cli_test_helper.sh @@ -123,6 +123,33 @@ assert_output_equals() { fi } +# Assert that output does NOT contain expected string +assert_output_not_contains() { + local description="$1" + local unexpected="$2" + shift 2 + TESTS_RUN=$((TESTS_RUN + 1)) + + if "$@" > /tmp/test_stdout.txt 2> /tmp/test_stderr.txt; then + if grep -qF -- "$unexpected" /tmp/test_stdout.txt || grep -qF -- "$unexpected" /tmp/test_stderr.txt; then + echo -e "${RED}✗${NC} $description (output contains '$unexpected')" + echo -e " ${YELLOW}STDOUT:$(cat /tmp/test_stdout.txt)${NC}" + echo -e " ${YELLOW}STDERR:$(cat /tmp/test_stderr.txt)${NC}" + TESTS_FAILED=$((TESTS_FAILED + 1)) + return 1 + else + echo -e "${GREEN}✓${NC} $description" + TESTS_PASSED=$((TESTS_PASSED + 1)) + return 0 + fi + else + echo -e "${RED}✗${NC} $description (command failed)" + echo -e " ${YELLOW}Exit code: $?${NC}" + TESTS_FAILED=$((TESTS_FAILED + 1)) + return 1 + fi +} + # Assert file exists assert_file_exists() { local description="$1" diff --git a/spec/cli/run_all_tests.sh b/spec/cli/run_all_tests.sh index 43b74bc..c4836ca 100755 --- a/spec/cli/run_all_tests.sh +++ b/spec/cli/run_all_tests.sh @@ -105,6 +105,7 @@ run_test_suite() { # Run all test suites run_test_suite "Basic Options Test" "$SCRIPT_DIR/test_basic_options.sh" run_test_suite "Compilation Test" "$SCRIPT_DIR/test_compilation.sh" +run_test_suite "Reserve Comments Test" "$SCRIPT_DIR/test_reserve_comments.sh" run_test_suite "Error Handling Test" "$SCRIPT_DIR/test_error_handling.sh" run_test_suite "Execution Test" "$SCRIPT_DIR/test_execution.sh" diff --git a/spec/cli/test_reserve_comments.sh b/spec/cli/test_reserve_comments.sh new file mode 100755 index 0000000..6c0c1a7 --- /dev/null +++ b/spec/cli/test_reserve_comments.sh @@ -0,0 +1,189 @@ +#!/bin/bash +# Test Reserve Comments Functionality for YueScript CLI +# Tests: -c, --reserve-comments option + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/cli_test_helper.sh" + +# Check binary +check_yue_binary + +# Setup test environment +setup_test_env +TMP_DIR=$(get_test_tmp_dir) + +echo "========================================" +echo "Testing Reserve Comments (-c) Option" +echo "========================================" +echo "" + +# Test 1: Reserve top-level comments +echo "Testing top-level comments preservation..." +cat > "$TMP_DIR/top_level.yue" << 'EOF' +-- Top level comment +x = 1 +-- Another comment +y = 2 +EOF + +assert_output_contains "Reserve top-level comments" "Top level comment" $YUE_BIN -c -p "$TMP_DIR/top_level.yue" +assert_output_contains "Reserve second comment" "Another comment" $YUE_BIN -c -p "$TMP_DIR/top_level.yue" + +# Test 2: Without -c option, comments should not appear +echo "" +echo "Testing comments are removed without -c option..." +assert_output_not_contains "Comments should be removed without -c" "Top level comment" $YUE_BIN -p "$TMP_DIR/top_level.yue" + +# Test 3: Reserve comments in table +echo "" +echo "Testing comments in tables..." +cat > "$TMP_DIR/table_comments.yue" << 'EOF' +t = { + -- First value comment + 1, + -- Second value comment + 2 +} +EOF + +assert_output_contains "Table comments should be preserved" "First value comment" $YUE_BIN -c -p "$TMP_DIR/table_comments.yue" +assert_output_contains "Table second comment preserved" "Second value comment" $YUE_BIN -c -p "$TMP_DIR/table_comments.yue" + +# Test 4: Reserve comments in if statement +echo "" +echo "Testing comments in if statements..." +cat > "$TMP_DIR/if_comments.yue" << 'EOF' +if true + -- Inside if block + print "test" +EOF + +assert_output_contains "If block comments should be preserved" "Inside if block" $YUE_BIN -c -p "$TMP_DIR/if_comments.yue" + +# Test 5: Reserve comments in function +echo "" +echo "Testing comments in functions..." +cat > "$TMP_DIR/func_comments.yue" << 'EOF' +func = => + -- Inside function + print "hello" +EOF + +assert_output_contains "Function comments should be preserved" "Inside function" $YUE_BIN -c -p "$TMP_DIR/func_comments.yue" + +# Test 6: Reserve comments with empty lines +echo "" +echo "Testing empty lines preservation..." +cat > "$TMP_DIR/empty_lines.yue" << 'EOF' +-- First comment +x = 1 +-- Second comment +EOF + +OUTPUT_WITHOUT_C=$($YUE_BIN -p "$TMP_DIR/empty_lines.yue") +OUTPUT_WITH_C=$($YUE_BIN -c -p "$TMP_DIR/empty_lines.yue") +if [ $? -eq 0 ]; then + # Count newlines - with -c should have more (or equal) lines due to comment preservation + LINES_WITHOUT_C=$(echo "$OUTPUT_WITHOUT_C" | wc -l) + LINES_WITH_C=$(echo "$OUTPUT_WITH_C" | wc -l) + if [ $LINES_WITH_C -ge $LINES_WITHOUT_C ]; then + echo -e "${GREEN}✓${NC} Empty lines and comments should be preserved" + TESTS_PASSED=$((TESTS_PASSED + 1)) + else + echo -e "${RED}✗${NC} Empty lines and comments should be preserved" + echo -e " ${YELLOW}Lines without -c: $LINES_WITHOUT_C, with -c: $LINES_WITH_C${NC}" + TESTS_FAILED=$((TESTS_FAILED + 1)) + fi + TESTS_RUN=$((TESTS_RUN + 1)) +else + echo -e "${RED}✗${NC} Empty lines test failed" + TESTS_FAILED=$((TESTS_FAILED + 1)) + TESTS_RUN=$((TESTS_RUN + 1)) +fi + +# Test 7: Reserve comments in table with TableBlock syntax +echo "" +echo "Testing comments in TableBlock..." +cat > "$TMP_DIR/tableblock_comments.yue" << 'EOF' +tbl = { + -- Key comment + key: "value" + -- Another key + another: 123 +} +EOF + +assert_output_contains "TableBlock key comment preserved" "Key comment" $YUE_BIN -c -p "$TMP_DIR/tableblock_comments.yue" +assert_output_contains "TableBlock second comment preserved" "Another key" $YUE_BIN -c -p "$TMP_DIR/tableblock_comments.yue" + +# Test 8: Reserve comments - long form option +echo "" +echo "Testing --reserve-comments long form option..." +assert_output_contains "Long form option should preserve comments" "First value comment" $YUE_BIN --reserve-comments -p "$TMP_DIR/table_comments.yue" + +# Test 9: Compile to file with reserve comments +echo "" +echo "Testing compilation to file with comments..." +cat > "$TMP_DIR/file_comment.yue" << 'EOF' +-- This is a test +value = 42 +EOF + +assert_success "Compile with -c to file" $YUE_BIN -c "$TMP_DIR/file_comment.yue" -o "$TMP_DIR/file_comment.lua" +assert_file_exists "Output file should exist" "$TMP_DIR/file_comment.lua" +assert_output_contains "Compiled file should contain comments" "This is a test" cat "$TMP_DIR/file_comment.lua" + +# Test 10: Reserve comments with multiple statements +echo "" +echo "Testing comments with multiple statements..." +cat > "$TMP_DIR/multi_stmt.yue" << 'EOF' +-- Assign x +x = 1 +-- Assign y +y = 2 +-- Assign z +z = 3 +EOF + +OUTPUT=$($YUE_BIN -c -p "$TMP_DIR/multi_stmt.yue") +if [ $? -eq 0 ]; then + if echo "$OUTPUT" | grep -q "Assign x" && echo "$OUTPUT" | grep -q "Assign y" && echo "$OUTPUT" | grep -q "Assign z"; then + echo -e "${GREEN}✓${NC} All comments should be preserved" + TESTS_PASSED=$((TESTS_PASSED + 1)) + else + echo -e "${RED}✗${NC} All comments should be preserved" + echo -e " ${YELLOW}Output: $OUTPUT${NC}" + TESTS_FAILED=$((TESTS_FAILED + 1)) + fi + TESTS_RUN=$((TESTS_RUN + 1)) +else + echo -e "${RED}✗${NC} Multiple statements test failed" + TESTS_FAILED=$((TESTS_FAILED + 1)) + TESTS_RUN=$((TESTS_RUN + 1)) +fi + +# Test 11: Comments in while loop +echo "" +echo "Testing comments in while loop..." +cat > "$TMP_DIR/while_comments.yue" << 'EOF' +while true + -- Loop body comment + print "looping" + break +EOF + +assert_output_contains "While loop comments preserved" "Loop body comment" $YUE_BIN -c -p "$TMP_DIR/while_comments.yue" + +# Test 12: Comments in for loop +echo "" +echo "Testing comments in for loop..." +cat > "$TMP_DIR/for_comments.yue" << 'EOF' +for i = 1, 3 + -- For loop comment + print i +EOF + +assert_output_contains "For loop comments preserved" "For loop comment" $YUE_BIN -c -p "$TMP_DIR/for_comments.yue" + +echo "" +print_summary diff --git a/spec/inputs/test/reserve_comments_spec.lua b/spec/inputs/test/reserve_comments_spec.lua new file mode 100644 index 0000000..b4e8174 --- /dev/null +++ b/spec/inputs/test/reserve_comments_spec.lua @@ -0,0 +1,471 @@ +return describe("reserve_comments option", function() + local to_lua + do + local _obj_0 = require("yue") + to_lua = _obj_0.to_lua + end + it("should preserve top-level comments with reserve_comment option", function() + local code = [[-- Top level comment +x = 1 +-- Another comment +y = 2 +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("Top level comment") ~= nil) + return assert.is_true(result:match("Another comment") ~= nil) + end) + it("should NOT preserve comments without reserve_comment option", function() + local code = [[-- Top level comment +x = 1 +-- Another comment +y = 2 +]] + local result = to_lua(code, { }) + assert.is_true(result:match("Top level comment") == nil) + return assert.is_true(result:match("Another comment") == nil) + end) + it("should preserve comments in table literals", function() + local code = [[t = { + -- First value comment + 1, + -- Second value comment + 2 +} +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("First value comment") ~= nil) + return assert.is_true(result:match("Second value comment") ~= nil) + end) + it("should preserve comments in if statement", function() + local code = [[if true + -- Inside if block + print "test" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("Inside if block") ~= nil) + end) + it("should preserve comments in function body", function() + local code = [[func = => + -- Inside function + print "hello" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("Inside function") ~= nil) + end) + it("should preserve comments in while loop", function() + local code = [[while true + -- Loop body comment + print "looping" + break +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("Loop body comment") ~= nil) + end) + it("should preserve comments in for loop", function() + local code = [[for i = 1, 3 + -- For loop comment + print i +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("For loop comment") ~= nil) + end) + it("should preserve comments in TableBlock syntax", function() + local code = [[tbl = { + -- Key comment + key: "value" + -- Another key + another: 123 +} +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("Key comment") ~= nil) + return assert.is_true(result:match("Another key") ~= nil) + end) + it("should preserve multiple comments across statements", function() + local code = [[-- Assign x +x = 1 +-- Assign y +y = 2 +-- Assign z +z = 3 +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("Assign x") ~= nil) + assert.is_true(result:match("Assign y") ~= nil) + return assert.is_true(result:match("Assign z") ~= nil) + end) + it("should handle table with mixed values and comments", function() + local code = [[t = { + -- First item + 1, + -- Second item + 2, + -- Third item + 3 +} +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("First item") ~= nil) + assert.is_true(result:match("Second item") ~= nil) + return assert.is_true(result:match("Third item") ~= nil) + end) + it("should preserve comments in nested structures", function() + local code = [[outer = { + -- outer comment + inner: { + -- inner comment + value: 42 + } +} +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("outer comment") ~= nil) + return assert.is_true(result:match("inner comment") ~= nil) + end) + it("should preserve comments in else block", function() + local code = [[if false + print "if" +else + -- else comment + print "else" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("else comment") ~= nil) + end) + it("should preserve comments in elseif block", function() + local code = [[if false + print "if" +elseif true + -- elseif comment + print "elseif" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("elseif comment") ~= nil) + end) + it("should preserve comments before return statement", function() + local code = [[func = => + -- before return + return 42 +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("before return") ~= nil) + end) + it("should preserve comments in switch statement", function() + local code = [[switch 2 + when 1 + -- case 1 comment + print "one" + when 2 + -- case 2 comment + print "two" +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("case 1 comment") ~= nil) + return assert.is_true(result:match("case 2 comment") ~= nil) + end) + it("should preserve comments in with statement", function() + local code = [[with t + -- with body comment + .value = 10 +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("with body comment") ~= nil) + end) + it("should handle empty lines with reserve_comment", function() + local code = [[-- First comment +x = 1 +-- Second comment +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result ~= nil) + return assert.is_true(type(result) == "string") + end) + it("should preserve comments in class body", function() + local code = [[class MyClass + -- property comment + value: 10 + -- method comment + method: => print "hello" +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("property comment") ~= nil) + return assert.is_true(result:match("method comment") ~= nil) + end) + it("should preserve comments in class with inheritance", function() + local code = [[class Child extends Parent + -- child property + value: 100 +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("child property") ~= nil) + end) + it("should preserve comments in export statement", function() + local code = [[-- export value comment +export x = 42 +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("export value comment") ~= nil) + end) + it("should preserve comments in import statement", function() + local code = [[-- import comment +import format from "string" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("import comment") ~= nil) + end) + it("should preserve empty lines between comments in TableBlock", function() + local code = "tb =\n\t-- line\n\n\n\n\t--[[ajdjd]]\n\ta: ->\n\n\t-- line 2\n\tb: 123\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("line") ~= nil) + assert.is_true(result:match("ajdjd") ~= nil) + return assert.is_true(result:match("line 2") ~= nil) + end) + it("should preserve block comments in TableBlock", function() + local code = "tb =\n\t--[[block comment]]\n\ta: 1\n\n\t--[[another block]]\n\tb: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("block comment") ~= nil) + return assert.is_true(result:match("another block") ~= nil) + end) + it("should preserve multiple empty lines in table literal", function() + local code = "tb = {\n\t-- line\n\n\n\n\t--[[ajdjd]]\n\ta: ->\n\n\t-- line 2\n\tb: 123\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("line") ~= nil) + assert.is_true(result:match("ajdjd") ~= nil) + return assert.is_true(result:match("line 2") ~= nil) + end) + it("should preserve mixed single and block comments in TableBlock", function() + local code = "tb =\n\t-- single line comment\n\ta: 1\n\n\t--[[multi\n\tline\n\tblock\n\tcomment]]\n\tb: 2\n\n\t-- another single\n\tc: 3\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("single line comment") ~= nil) + assert.is_true(result:match("multi") ~= nil) + return assert.is_true(result:match("another single") ~= nil) + end) + it("should preserve comments and empty lines in table with colon syntax", function() + local code = "tbl = {\n\t-- first key\n\tkey1: \"value1\"\n\n\n\t-- second key\n\tkey2: \"value2\"\n\n\t-- third key\n\tkey3: \"value3\"\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("first key") ~= nil) + assert.is_true(result:match("second key") ~= nil) + return assert.is_true(result:match("third key") ~= nil) + end) + it("should preserve comments in nested TableBlock structures", function() + local code = "outer =\n\t-- outer item\n\ta: 1\n\n\t-- inner tableblock\n\tinner:\n\t\t-- inner item 1\n\t\tx: 10\n\t\t-- inner item 2\n\t\ty: 20\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("outer item") ~= nil) + assert.is_true(result:match("inner tableblock") ~= nil) + assert.is_true(result:match("inner item 1") ~= nil) + return assert.is_true(result:match("inner item 2") ~= nil) + end) + it("should handle function values in TableBlock with comments", function() + local code = "tb =\n\t-- comment before function\n\tfunc1: => print \"a\"\n\n\t-- another function\n\tfunc2: (x) => x * 2\n\n\t-- method\n\tmethod: =>\n\t\t-- inside method\n\t\tprint \"method\"\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("comment before function") ~= nil) + assert.is_true(result:match("another function") ~= nil) + assert.is_true(result:match("method") ~= nil) + return assert.is_true(result:match("inside method") ~= nil) + end) + it("should preserve comments in TableBlock with various value types", function() + local code = "tb =\n\t-- string value\n\tstr: \"hello\"\n\n\t-- number value\n\tnum: 42\n\n\t-- boolean value\n\tbool: true\n\n\t-- table value\n\ttbl: {1, 2, 3}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("string value") ~= nil) + assert.is_true(result:match("number value") ~= nil) + assert.is_true(result:match("boolean value") ~= nil) + return assert.is_true(result:match("table value") ~= nil) + end) + it("should preserve empty lines at end of TableBlock", function() + local code = "tb =\n\t-- item 1\n\ta: 1\n\n\t-- item 2\n\tb: 2\n\n\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("item 1") ~= nil) + return assert.is_true(result:match("item 2") ~= nil) + end) + it("should preserve empty lines in TableBlock between comments", function() + local code = "tb =\n\t-- a\n\t\n\t\n\t\n\tval: 1\n" + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve empty lines in TableBlock with comments", function() + local code = "tb =\n\t-- first\n\t\n\t\n\tval: 1\n\t\n\t-- second\n\tval2: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("first") ~= nil) + assert.is_true(result:match("second") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve empty lines in table literal", function() + local code = "t = {\n\t-- item1\n\t\n\t\n\t1,\n\t\n\t-- item2\n\t2\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("item1") ~= nil) + assert.is_true(result:match("item2") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should have more newlines with reserve_comment than without", function() + local code = "-- comment1\nx = 1\n-- comment2\ny = 2\n" + local result_with = to_lua(code, { + reserve_comment = true + }) + local result_without = to_lua(code, { }) + local newlines_with = 0 + local newlines_without = 0 + for _ in result_with:gmatch("\n") do + newlines_with = newlines_with + 1 + end + for _ in result_without:gmatch("\n") do + newlines_without = newlines_without + 1 + end + return assert.is_true(newlines_with >= newlines_without) + end) + it("should preserve empty lines in TableBlock between entries", function() + local code = "tb =\n\t-- key1\n\tkey1: 1\n\t\n\t\n\t-- key2\n\tkey2: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("key1") ~= nil) + assert.is_true(result:match("key2") ~= nil) + return assert.is_true(result:match("\t-- %d+\n") ~= nil) + end) + it("should preserve empty lines in class body", function() + local code = "class C\n\t-- prop1\n\tprop1: 1\n\t\n\t\n\t-- prop2\n\tprop2: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("prop1") ~= nil) + return assert.is_true(result:match("prop2") ~= nil) + end) + it("should preserve empty lines between comments in table", function() + local code = "t = {\n\t-- first\n\t\n\t-- second\n\t\n\t-- third\n\tval: 1\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("first") ~= nil) + assert.is_true(result:match("second") ~= nil) + assert.is_true(result:match("third") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve multiple consecutive empty lines in TableBlock", function() + local code = "tb =\n\t-- start\n\tval1: 1\n\t\n\t\n\t\n\t-- middle\n\tval2: 2\n\t\n\t\n\t-- end\n\tval3: 3\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("start") ~= nil) + assert.is_true(result:match("middle") ~= nil) + assert.is_true(result:match("end") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve comments in table literal", function() + local code = "t = {\n\t-- comment\n\tkey: 1\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("comment") ~= nil) + end) + it("should preserve comments in TableBlock", function() + local code = "t =\n\t-- comment\n\tkey: 1\n" + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("comment") ~= nil) + end) + it("should preserve comments in class body", function() + local code = "class C\n\t-- comment\n\tkey: 1\n" + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("comment") ~= nil) + end) + it("should preserve multiple comments in class body", function() + local code = "class C\n\t-- prop1\n\tprop1: 1\n\t-- prop2\n\tprop2: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("prop1") ~= nil) + return assert.is_true(result:match("prop2") ~= nil) + end) + it("should preserve empty lines in table literal", function() + local code = "t = {\n\t-- a\n\t\n\t-- b\n\tkey: 1\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("a") ~= nil) + assert.is_true(result:match("b") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve empty lines in TableBlock", function() + local code = "t =\n\t-- a\n\t\n\t-- b\n\tkey: 1\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("a") ~= nil) + assert.is_true(result:match("b") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + return it("should preserve empty lines in class body", function() + local code = "class C\n\t-- a\n\ta: 1\n\t\n\t-- b\n\tb: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("a") ~= nil) + return assert.is_true(result:match("b") ~= nil) + end) +end) diff --git a/spec/inputs/test/reserve_comments_spec.yue b/spec/inputs/test/reserve_comments_spec.yue new file mode 100644 index 0000000..3c0b824 --- /dev/null +++ b/spec/inputs/test/reserve_comments_spec.yue @@ -0,0 +1,413 @@ +describe "reserve_comments option", -> + import to_lua from require("yue") + + it "should preserve top-level comments with reserve_comment option", -> + code = [[ +-- Top level comment +x = 1 +-- Another comment +y = 2 +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("Top level comment") ~= nil + assert.is_true result\match("Another comment") ~= nil + + it "should NOT preserve comments without reserve_comment option", -> + code = [[ +-- Top level comment +x = 1 +-- Another comment +y = 2 +]] + result = to_lua code, {} + assert.is_true result\match("Top level comment") == nil + assert.is_true result\match("Another comment") == nil + + it "should preserve comments in table literals", -> + code = [[ +t = { + -- First value comment + 1, + -- Second value comment + 2 +} +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("First value comment") ~= nil + assert.is_true result\match("Second value comment") ~= nil + + it "should preserve comments in if statement", -> + code = [[ +if true + -- Inside if block + print "test" +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("Inside if block") ~= nil + + it "should preserve comments in function body", -> + code = [[ +func = => + -- Inside function + print "hello" +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("Inside function") ~= nil + + it "should preserve comments in while loop", -> + code = [[ +while true + -- Loop body comment + print "looping" + break +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("Loop body comment") ~= nil + + it "should preserve comments in for loop", -> + code = [[ +for i = 1, 3 + -- For loop comment + print i +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("For loop comment") ~= nil + + it "should preserve comments in TableBlock syntax", -> + code = [[ +tbl = { + -- Key comment + key: "value" + -- Another key + another: 123 +} +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("Key comment") ~= nil + assert.is_true result\match("Another key") ~= nil + + it "should preserve multiple comments across statements", -> + code = [[ +-- Assign x +x = 1 +-- Assign y +y = 2 +-- Assign z +z = 3 +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("Assign x") ~= nil + assert.is_true result\match("Assign y") ~= nil + assert.is_true result\match("Assign z") ~= nil + + it "should handle table with mixed values and comments", -> + code = [[ +t = { + -- First item + 1, + -- Second item + 2, + -- Third item + 3 +} +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("First item") ~= nil + assert.is_true result\match("Second item") ~= nil + assert.is_true result\match("Third item") ~= nil + + it "should preserve comments in nested structures", -> + code = [[ +outer = { + -- outer comment + inner: { + -- inner comment + value: 42 + } +} +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("outer comment") ~= nil + assert.is_true result\match("inner comment") ~= nil + + it "should preserve comments in else block", -> + code = [[ +if false + print "if" +else + -- else comment + print "else" +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("else comment") ~= nil + + it "should preserve comments in elseif block", -> + code = [[ +if false + print "if" +elseif true + -- elseif comment + print "elseif" +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("elseif comment") ~= nil + + it "should preserve comments before return statement", -> + code = [[ +func = => + -- before return + return 42 +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("before return") ~= nil + + it "should preserve comments in switch statement", -> + code = [[ +switch 2 + when 1 + -- case 1 comment + print "one" + when 2 + -- case 2 comment + print "two" +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("case 1 comment") ~= nil + assert.is_true result\match("case 2 comment") ~= nil + + it "should preserve comments in with statement", -> + code = [[ +with t + -- with body comment + .value = 10 +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("with body comment") ~= nil + + it "should handle empty lines with reserve_comment", -> + code = [[ +-- First comment +x = 1 +-- Second comment +]] + -- Just verify it compiles without error + result = to_lua code, {reserve_comment: true} + assert.is_true result ~= nil + assert.is_true type(result) == "string" + + it "should preserve comments in class body", -> + code = [[ +class MyClass + -- property comment + value: 10 + -- method comment + method: => print "hello" +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("property comment") ~= nil + assert.is_true result\match("method comment") ~= nil + + it "should preserve comments in class with inheritance", -> + code = [[ +class Child extends Parent + -- child property + value: 100 +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("child property") ~= nil + + it "should preserve comments in export statement", -> + code = [[ +-- export value comment +export x = 42 +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("export value comment") ~= nil + + it "should preserve comments in import statement", -> + code = [[ +-- import comment +import format from "string" +]] + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("import comment") ~= nil + + -- Additional tests for TableBlock syntax with multiple empty lines + it "should preserve empty lines between comments in TableBlock", -> + code = "tb =\n\t-- line\n\n\n\n\t--[[ajdjd]]\n\ta: ->\n\n\t-- line 2\n\tb: 123\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("line") ~= nil + assert.is_true result\match("ajdjd") ~= nil + assert.is_true result\match("line 2") ~= nil + + it "should preserve block comments in TableBlock", -> + code = "tb =\n\t--[[block comment]]\n\ta: 1\n\n\t--[[another block]]\n\tb: 2\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("block comment") ~= nil + assert.is_true result\match("another block") ~= nil + + it "should preserve multiple empty lines in table literal", -> + code = "tb = {\n\t-- line\n\n\n\n\t--[[ajdjd]]\n\ta: ->\n\n\t-- line 2\n\tb: 123\n}\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("line") ~= nil + assert.is_true result\match("ajdjd") ~= nil + assert.is_true result\match("line 2") ~= nil + + it "should preserve mixed single and block comments in TableBlock", -> + code = "tb =\n\t-- single line comment\n\ta: 1\n\n\t--[[multi\n\tline\n\tblock\n\tcomment]]\n\tb: 2\n\n\t-- another single\n\tc: 3\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("single line comment") ~= nil + assert.is_true result\match("multi") ~= nil + assert.is_true result\match("another single") ~= nil + + it "should preserve comments and empty lines in table with colon syntax", -> + code = "tbl = {\n\t-- first key\n\tkey1: \"value1\"\n\n\n\t-- second key\n\tkey2: \"value2\"\n\n\t-- third key\n\tkey3: \"value3\"\n}\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("first key") ~= nil + assert.is_true result\match("second key") ~= nil + assert.is_true result\match("third key") ~= nil + + it "should preserve comments in nested TableBlock structures", -> + code = "outer =\n\t-- outer item\n\ta: 1\n\n\t-- inner tableblock\n\tinner:\n\t\t-- inner item 1\n\t\tx: 10\n\t\t-- inner item 2\n\t\ty: 20\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("outer item") ~= nil + assert.is_true result\match("inner tableblock") ~= nil + assert.is_true result\match("inner item 1") ~= nil + assert.is_true result\match("inner item 2") ~= nil + + it "should handle function values in TableBlock with comments", -> + code = "tb =\n\t-- comment before function\n\tfunc1: => print \"a\"\n\n\t-- another function\n\tfunc2: (x) => x * 2\n\n\t-- method\n\tmethod: =>\n\t\t-- inside method\n\t\tprint \"method\"\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("comment before function") ~= nil + assert.is_true result\match("another function") ~= nil + assert.is_true result\match("method") ~= nil + assert.is_true result\match("inside method") ~= nil + + it "should preserve comments in TableBlock with various value types", -> + code = "tb =\n\t-- string value\n\tstr: \"hello\"\n\n\t-- number value\n\tnum: 42\n\n\t-- boolean value\n\tbool: true\n\n\t-- table value\n\ttbl: {1, 2, 3}\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("string value") ~= nil + assert.is_true result\match("number value") ~= nil + assert.is_true result\match("boolean value") ~= nil + assert.is_true result\match("table value") ~= nil + + it "should preserve empty lines at end of TableBlock", -> + code = "tb =\n\t-- item 1\n\ta: 1\n\n\t-- item 2\n\tb: 2\n\n\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("item 1") ~= nil + assert.is_true result\match("item 2") ~= nil + + -- Tests specifically for empty lines between comments + it "should preserve empty lines in TableBlock between comments", -> + code = "tb =\n\t-- a\n\t\n\t\n\t\n\tval: 1\n" + result = to_lua code, {reserve_comment: true} + -- Empty lines should produce line number comments in output + -- Check that there's a line with just a comment marker (line number) + assert.is_true result\match("-- %d+") ~= nil + + it "should preserve empty lines in TableBlock with comments", -> + code = "tb =\n\t-- first\n\t\n\t\n\tval: 1\n\t\n\t-- second\n\tval2: 2\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("first") ~= nil + assert.is_true result\match("second") ~= nil + -- Should have empty line representations (lines with line number comments) + assert.is_true result\match("-- %d+") ~= nil + + it "should preserve empty lines in table literal", -> + code = "t = {\n\t-- item1\n\t\n\t\n\t1,\n\t\n\t-- item2\n\t2\n}\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("item1") ~= nil + assert.is_true result\match("item2") ~= nil + -- Empty lines should produce line comments + assert.is_true result\match("-- %d+") ~= nil + + it "should have more newlines with reserve_comment than without", -> + code = "-- comment1\nx = 1\n-- comment2\ny = 2\n" + result_with = to_lua code, {reserve_comment: true} + result_without = to_lua code, {} + -- Count newlines in both results using gmatch + newlines_with = 0 + newlines_without = 0 + for _ in result_with\gmatch("\n") + newlines_with += 1 + for _ in result_without\gmatch("\n") + newlines_without += 1 + -- With reserve_comment should have equal or more newlines + assert.is_true newlines_with >= newlines_without + + it "should preserve empty lines in TableBlock between entries", -> + code = "tb =\n\t-- key1\n\tkey1: 1\n\t\n\t\n\t-- key2\n\tkey2: 2\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("key1") ~= nil + assert.is_true result\match("key2") ~= nil + -- Empty lines should produce lines with line number comments + assert.is_true result\match("\t-- %d+\n") ~= nil + + it "should preserve empty lines in class body", -> + code = "class C\n\t-- prop1\n\tprop1: 1\n\t\n\t\n\t-- prop2\n\tprop2: 2\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("prop1") ~= nil + assert.is_true result\match("prop2") ~= nil + + it "should preserve empty lines between comments in table", -> + code = "t = {\n\t-- first\n\t\n\t-- second\n\t\n\t-- third\n\tval: 1\n}\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("first") ~= nil + assert.is_true result\match("second") ~= nil + assert.is_true result\match("third") ~= nil + -- Empty lines should produce line comments + assert.is_true result\match("-- %d+") ~= nil + + it "should preserve multiple consecutive empty lines in TableBlock", -> + code = "tb =\n\t-- start\n\tval1: 1\n\t\n\t\n\t\n\t-- middle\n\tval2: 2\n\t\n\t\n\t-- end\n\tval3: 3\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("start") ~= nil + assert.is_true result\match("middle") ~= nil + assert.is_true result\match("end") ~= nil + -- Should have line number comments for empty lines + assert.is_true result\match("-- %d+") ~= nil + + -- Comparison tests: Table literal vs TableBlock vs Class + it "should preserve comments in table literal", -> + code = "t = {\n\t-- comment\n\tkey: 1\n}\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("comment") ~= nil + + it "should preserve comments in TableBlock", -> + code = "t =\n\t-- comment\n\tkey: 1\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("comment") ~= nil + + it "should preserve comments in class body", -> + code = "class C\n\t-- comment\n\tkey: 1\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("comment") ~= nil + + it "should preserve multiple comments in class body", -> + code = "class C\n\t-- prop1\n\tprop1: 1\n\t-- prop2\n\tprop2: 2\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("prop1") ~= nil + assert.is_true result\match("prop2") ~= nil + + it "should preserve empty lines in table literal", -> + code = "t = {\n\t-- a\n\t\n\t-- b\n\tkey: 1\n}\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("a") ~= nil + assert.is_true result\match("b") ~= nil + -- Empty lines produce line comments + assert.is_true result\match("-- %d+") ~= nil + + it "should preserve empty lines in TableBlock", -> + code = "t =\n\t-- a\n\t\n\t-- b\n\tkey: 1\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("a") ~= nil + assert.is_true result\match("b") ~= nil + -- Empty lines produce line comments + assert.is_true result\match("-- %d+") ~= nil + + it "should preserve empty lines in class body", -> + code = "class C\n\t-- a\n\ta: 1\n\t\n\t-- b\n\tb: 2\n" + result = to_lua code, {reserve_comment: true} + assert.is_true result\match("a") ~= nil + assert.is_true result\match("b") ~= nil + -- Empty lines in class should also be preserved diff --git a/spec/outputs/test/reserve_comments_spec.lua b/spec/outputs/test/reserve_comments_spec.lua new file mode 100644 index 0000000..b4e8174 --- /dev/null +++ b/spec/outputs/test/reserve_comments_spec.lua @@ -0,0 +1,471 @@ +return describe("reserve_comments option", function() + local to_lua + do + local _obj_0 = require("yue") + to_lua = _obj_0.to_lua + end + it("should preserve top-level comments with reserve_comment option", function() + local code = [[-- Top level comment +x = 1 +-- Another comment +y = 2 +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("Top level comment") ~= nil) + return assert.is_true(result:match("Another comment") ~= nil) + end) + it("should NOT preserve comments without reserve_comment option", function() + local code = [[-- Top level comment +x = 1 +-- Another comment +y = 2 +]] + local result = to_lua(code, { }) + assert.is_true(result:match("Top level comment") == nil) + return assert.is_true(result:match("Another comment") == nil) + end) + it("should preserve comments in table literals", function() + local code = [[t = { + -- First value comment + 1, + -- Second value comment + 2 +} +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("First value comment") ~= nil) + return assert.is_true(result:match("Second value comment") ~= nil) + end) + it("should preserve comments in if statement", function() + local code = [[if true + -- Inside if block + print "test" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("Inside if block") ~= nil) + end) + it("should preserve comments in function body", function() + local code = [[func = => + -- Inside function + print "hello" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("Inside function") ~= nil) + end) + it("should preserve comments in while loop", function() + local code = [[while true + -- Loop body comment + print "looping" + break +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("Loop body comment") ~= nil) + end) + it("should preserve comments in for loop", function() + local code = [[for i = 1, 3 + -- For loop comment + print i +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("For loop comment") ~= nil) + end) + it("should preserve comments in TableBlock syntax", function() + local code = [[tbl = { + -- Key comment + key: "value" + -- Another key + another: 123 +} +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("Key comment") ~= nil) + return assert.is_true(result:match("Another key") ~= nil) + end) + it("should preserve multiple comments across statements", function() + local code = [[-- Assign x +x = 1 +-- Assign y +y = 2 +-- Assign z +z = 3 +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("Assign x") ~= nil) + assert.is_true(result:match("Assign y") ~= nil) + return assert.is_true(result:match("Assign z") ~= nil) + end) + it("should handle table with mixed values and comments", function() + local code = [[t = { + -- First item + 1, + -- Second item + 2, + -- Third item + 3 +} +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("First item") ~= nil) + assert.is_true(result:match("Second item") ~= nil) + return assert.is_true(result:match("Third item") ~= nil) + end) + it("should preserve comments in nested structures", function() + local code = [[outer = { + -- outer comment + inner: { + -- inner comment + value: 42 + } +} +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("outer comment") ~= nil) + return assert.is_true(result:match("inner comment") ~= nil) + end) + it("should preserve comments in else block", function() + local code = [[if false + print "if" +else + -- else comment + print "else" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("else comment") ~= nil) + end) + it("should preserve comments in elseif block", function() + local code = [[if false + print "if" +elseif true + -- elseif comment + print "elseif" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("elseif comment") ~= nil) + end) + it("should preserve comments before return statement", function() + local code = [[func = => + -- before return + return 42 +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("before return") ~= nil) + end) + it("should preserve comments in switch statement", function() + local code = [[switch 2 + when 1 + -- case 1 comment + print "one" + when 2 + -- case 2 comment + print "two" +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("case 1 comment") ~= nil) + return assert.is_true(result:match("case 2 comment") ~= nil) + end) + it("should preserve comments in with statement", function() + local code = [[with t + -- with body comment + .value = 10 +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("with body comment") ~= nil) + end) + it("should handle empty lines with reserve_comment", function() + local code = [[-- First comment +x = 1 +-- Second comment +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result ~= nil) + return assert.is_true(type(result) == "string") + end) + it("should preserve comments in class body", function() + local code = [[class MyClass + -- property comment + value: 10 + -- method comment + method: => print "hello" +]] + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("property comment") ~= nil) + return assert.is_true(result:match("method comment") ~= nil) + end) + it("should preserve comments in class with inheritance", function() + local code = [[class Child extends Parent + -- child property + value: 100 +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("child property") ~= nil) + end) + it("should preserve comments in export statement", function() + local code = [[-- export value comment +export x = 42 +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("export value comment") ~= nil) + end) + it("should preserve comments in import statement", function() + local code = [[-- import comment +import format from "string" +]] + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("import comment") ~= nil) + end) + it("should preserve empty lines between comments in TableBlock", function() + local code = "tb =\n\t-- line\n\n\n\n\t--[[ajdjd]]\n\ta: ->\n\n\t-- line 2\n\tb: 123\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("line") ~= nil) + assert.is_true(result:match("ajdjd") ~= nil) + return assert.is_true(result:match("line 2") ~= nil) + end) + it("should preserve block comments in TableBlock", function() + local code = "tb =\n\t--[[block comment]]\n\ta: 1\n\n\t--[[another block]]\n\tb: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("block comment") ~= nil) + return assert.is_true(result:match("another block") ~= nil) + end) + it("should preserve multiple empty lines in table literal", function() + local code = "tb = {\n\t-- line\n\n\n\n\t--[[ajdjd]]\n\ta: ->\n\n\t-- line 2\n\tb: 123\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("line") ~= nil) + assert.is_true(result:match("ajdjd") ~= nil) + return assert.is_true(result:match("line 2") ~= nil) + end) + it("should preserve mixed single and block comments in TableBlock", function() + local code = "tb =\n\t-- single line comment\n\ta: 1\n\n\t--[[multi\n\tline\n\tblock\n\tcomment]]\n\tb: 2\n\n\t-- another single\n\tc: 3\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("single line comment") ~= nil) + assert.is_true(result:match("multi") ~= nil) + return assert.is_true(result:match("another single") ~= nil) + end) + it("should preserve comments and empty lines in table with colon syntax", function() + local code = "tbl = {\n\t-- first key\n\tkey1: \"value1\"\n\n\n\t-- second key\n\tkey2: \"value2\"\n\n\t-- third key\n\tkey3: \"value3\"\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("first key") ~= nil) + assert.is_true(result:match("second key") ~= nil) + return assert.is_true(result:match("third key") ~= nil) + end) + it("should preserve comments in nested TableBlock structures", function() + local code = "outer =\n\t-- outer item\n\ta: 1\n\n\t-- inner tableblock\n\tinner:\n\t\t-- inner item 1\n\t\tx: 10\n\t\t-- inner item 2\n\t\ty: 20\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("outer item") ~= nil) + assert.is_true(result:match("inner tableblock") ~= nil) + assert.is_true(result:match("inner item 1") ~= nil) + return assert.is_true(result:match("inner item 2") ~= nil) + end) + it("should handle function values in TableBlock with comments", function() + local code = "tb =\n\t-- comment before function\n\tfunc1: => print \"a\"\n\n\t-- another function\n\tfunc2: (x) => x * 2\n\n\t-- method\n\tmethod: =>\n\t\t-- inside method\n\t\tprint \"method\"\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("comment before function") ~= nil) + assert.is_true(result:match("another function") ~= nil) + assert.is_true(result:match("method") ~= nil) + return assert.is_true(result:match("inside method") ~= nil) + end) + it("should preserve comments in TableBlock with various value types", function() + local code = "tb =\n\t-- string value\n\tstr: \"hello\"\n\n\t-- number value\n\tnum: 42\n\n\t-- boolean value\n\tbool: true\n\n\t-- table value\n\ttbl: {1, 2, 3}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("string value") ~= nil) + assert.is_true(result:match("number value") ~= nil) + assert.is_true(result:match("boolean value") ~= nil) + return assert.is_true(result:match("table value") ~= nil) + end) + it("should preserve empty lines at end of TableBlock", function() + local code = "tb =\n\t-- item 1\n\ta: 1\n\n\t-- item 2\n\tb: 2\n\n\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("item 1") ~= nil) + return assert.is_true(result:match("item 2") ~= nil) + end) + it("should preserve empty lines in TableBlock between comments", function() + local code = "tb =\n\t-- a\n\t\n\t\n\t\n\tval: 1\n" + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve empty lines in TableBlock with comments", function() + local code = "tb =\n\t-- first\n\t\n\t\n\tval: 1\n\t\n\t-- second\n\tval2: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("first") ~= nil) + assert.is_true(result:match("second") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve empty lines in table literal", function() + local code = "t = {\n\t-- item1\n\t\n\t\n\t1,\n\t\n\t-- item2\n\t2\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("item1") ~= nil) + assert.is_true(result:match("item2") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should have more newlines with reserve_comment than without", function() + local code = "-- comment1\nx = 1\n-- comment2\ny = 2\n" + local result_with = to_lua(code, { + reserve_comment = true + }) + local result_without = to_lua(code, { }) + local newlines_with = 0 + local newlines_without = 0 + for _ in result_with:gmatch("\n") do + newlines_with = newlines_with + 1 + end + for _ in result_without:gmatch("\n") do + newlines_without = newlines_without + 1 + end + return assert.is_true(newlines_with >= newlines_without) + end) + it("should preserve empty lines in TableBlock between entries", function() + local code = "tb =\n\t-- key1\n\tkey1: 1\n\t\n\t\n\t-- key2\n\tkey2: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("key1") ~= nil) + assert.is_true(result:match("key2") ~= nil) + return assert.is_true(result:match("\t-- %d+\n") ~= nil) + end) + it("should preserve empty lines in class body", function() + local code = "class C\n\t-- prop1\n\tprop1: 1\n\t\n\t\n\t-- prop2\n\tprop2: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("prop1") ~= nil) + return assert.is_true(result:match("prop2") ~= nil) + end) + it("should preserve empty lines between comments in table", function() + local code = "t = {\n\t-- first\n\t\n\t-- second\n\t\n\t-- third\n\tval: 1\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("first") ~= nil) + assert.is_true(result:match("second") ~= nil) + assert.is_true(result:match("third") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve multiple consecutive empty lines in TableBlock", function() + local code = "tb =\n\t-- start\n\tval1: 1\n\t\n\t\n\t\n\t-- middle\n\tval2: 2\n\t\n\t\n\t-- end\n\tval3: 3\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("start") ~= nil) + assert.is_true(result:match("middle") ~= nil) + assert.is_true(result:match("end") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve comments in table literal", function() + local code = "t = {\n\t-- comment\n\tkey: 1\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("comment") ~= nil) + end) + it("should preserve comments in TableBlock", function() + local code = "t =\n\t-- comment\n\tkey: 1\n" + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("comment") ~= nil) + end) + it("should preserve comments in class body", function() + local code = "class C\n\t-- comment\n\tkey: 1\n" + local result = to_lua(code, { + reserve_comment = true + }) + return assert.is_true(result:match("comment") ~= nil) + end) + it("should preserve multiple comments in class body", function() + local code = "class C\n\t-- prop1\n\tprop1: 1\n\t-- prop2\n\tprop2: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("prop1") ~= nil) + return assert.is_true(result:match("prop2") ~= nil) + end) + it("should preserve empty lines in table literal", function() + local code = "t = {\n\t-- a\n\t\n\t-- b\n\tkey: 1\n}\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("a") ~= nil) + assert.is_true(result:match("b") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + it("should preserve empty lines in TableBlock", function() + local code = "t =\n\t-- a\n\t\n\t-- b\n\tkey: 1\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("a") ~= nil) + assert.is_true(result:match("b") ~= nil) + return assert.is_true(result:match("-- %d+") ~= nil) + end) + return it("should preserve empty lines in class body", function() + local code = "class C\n\t-- a\n\ta: 1\n\t\n\t-- b\n\tb: 2\n" + local result = to_lua(code, { + reserve_comment = true + }) + assert.is_true(result:match("a") ~= nil) + return assert.is_true(result:match("b") ~= nil) + end) +end) -- cgit v1.2.3-55-g6feb