livetext 0.9.55 → 0.9.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/livetext/ast/show_ast_clean.rb +10 -0
- data/lib/livetext/ast/show_ast_result.rb +60 -0
- data/lib/livetext/ast/show_raw_arrays.rb +13 -0
- data/lib/livetext/ast.rb +464 -0
- data/lib/livetext/ast_to_html.rb +32 -0
- data/lib/livetext/core.rb +6 -4
- data/lib/livetext/errors.rb +1 -0
- data/lib/livetext/functions.rb +26 -0
- data/lib/livetext/handler/mixin.rb +28 -0
- data/lib/livetext/helpers.rb +19 -20
- data/lib/livetext/standard.rb +2 -2
- data/lib/livetext/userapi.rb +20 -1
- data/lib/livetext/variable_manager.rb +14 -1
- data/lib/livetext/variables.rb +5 -1
- data/lib/livetext/version.rb +1 -1
- data/plugin/booktool.rb +6 -6
- data/plugin/lt3scriptor.rb +914 -0
- data/plugin/mixin_functions_class.rb +33 -0
- data/test/snapshots/error_missing_end/match-error.txt +1 -1
- data/test/snapshots/mixin_functions_class/expected-error.txt +0 -0
- data/test/snapshots/mixin_functions_class/expected-output.txt +20 -0
- data/test/snapshots/mixin_functions_class/match-error.txt +1 -0
- data/test/snapshots/mixin_functions_class/mixin_functions_class.rb +33 -0
- data/test/snapshots/mixin_functions_class/source.lt3 +17 -0
- data/test/snapshots/system_info/match-output.txt +18 -0
- data/test/unit/all.rb +3 -0
- data/test/unit/ast.rb +90 -0
- data/test/unit/ast_directives.rb +104 -0
- data/test/unit/ast_variables.rb +71 -0
- data/test/unit/core_methods.rb +180 -0
- data/test/unit/formatter_component.rb +1 -1
- data/test/unit/mixin_functions_class.rb +131 -0
- data/test/unit/stringparser.rb +14 -32
- metadata +19 -5
- data/imports/markdown.rb +0 -44
- data/plugin/markdown.rb +0 -43
- data/test/snapshots/system_info/expected-output.txt +0 -18
@@ -0,0 +1,33 @@
|
|
1
|
+
def some_dot_command(args, data)
|
2
|
+
# This is a dot command, not a function
|
3
|
+
api.out "Dot command called with: #{data}"
|
4
|
+
end
|
5
|
+
|
6
|
+
class Livetext::Functions
|
7
|
+
def class_func(param)
|
8
|
+
"Class function called with: #{param}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def another_class_func(param)
|
12
|
+
"Another class function called with: #{param}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def simple_class_func
|
16
|
+
"Simple class function with no parameters"
|
17
|
+
end
|
18
|
+
|
19
|
+
def vars_test(param)
|
20
|
+
# New approach: Access variables through the instance variables
|
21
|
+
# @live and @vars are now available in Livetext::Functions
|
22
|
+
|
23
|
+
# Access variables using the new instance-based approach
|
24
|
+
view_var = @live.vars.View || "no_view"
|
25
|
+
|
26
|
+
# Alternative approaches:
|
27
|
+
# view_var = @vars.View || "no_view" # Direct access to vars
|
28
|
+
# view_var = get_var(:View) || "no_view" # Using helper method
|
29
|
+
# view_var = Livetext::Vars[:View] || "no_view" # Fallback to global
|
30
|
+
|
31
|
+
"Vars test: param=#{param}, View=#{view_var}"
|
32
|
+
end
|
33
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
1 /
|
1
|
+
1 /expected .end but found end of file/
|
File without changes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Testing functions defined in Livetext::Functions class
|
2
|
+
<p>
|
3
|
+
|
4
|
+
Now calling functions defined in Livetext::Functions class:
|
5
|
+
Class function called with: test_parameter
|
6
|
+
<p>
|
7
|
+
|
8
|
+
And another one with brackets:
|
9
|
+
Another class function called with: with brackets
|
10
|
+
<p>
|
11
|
+
|
12
|
+
And a function with no parameters:
|
13
|
+
Simple class function with no parameters
|
14
|
+
<p>
|
15
|
+
|
16
|
+
Testing that the functions have access to Livetext::Vars:
|
17
|
+
Vars test: param=some_value, View=[View is undefined]
|
18
|
+
<p>
|
19
|
+
|
20
|
+
That's all.
|
@@ -0,0 +1 @@
|
|
1
|
+
1 No error expected
|
@@ -0,0 +1,33 @@
|
|
1
|
+
def some_dot_command(args, data)
|
2
|
+
# This is a dot command, not a function
|
3
|
+
api.out "Dot command called with: #{data}"
|
4
|
+
end
|
5
|
+
|
6
|
+
class Livetext::Functions
|
7
|
+
def class_func(param)
|
8
|
+
"Class function called with: #{param}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def another_class_func(param)
|
12
|
+
"Another class function called with: #{param}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def simple_class_func
|
16
|
+
"Simple class function with no parameters"
|
17
|
+
end
|
18
|
+
|
19
|
+
def vars_test(param)
|
20
|
+
# New approach: Access variables through the instance variables
|
21
|
+
# @live and @vars are now available in Livetext::Functions
|
22
|
+
|
23
|
+
# Access variables using the new instance-based approach
|
24
|
+
view_var = @live.vars.View || "no_view"
|
25
|
+
|
26
|
+
# Alternative approaches:
|
27
|
+
# view_var = @vars.View || "no_view" # Direct access to vars
|
28
|
+
# view_var = get_var(:View) || "no_view" # Using helper method
|
29
|
+
# view_var = Livetext::Vars[:View] || "no_view" # Fallback to global
|
30
|
+
|
31
|
+
"Vars test: param=#{param}, View=#{view_var}"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Testing functions defined in Livetext::Functions class
|
2
|
+
|
3
|
+
.mixin mixin_functions_class
|
4
|
+
|
5
|
+
Now calling functions defined in Livetext::Functions class:
|
6
|
+
$$class_func:test_parameter
|
7
|
+
|
8
|
+
And another one with brackets:
|
9
|
+
$$another_class_func[with brackets]
|
10
|
+
|
11
|
+
And a function with no parameters:
|
12
|
+
$$simple_class_func
|
13
|
+
|
14
|
+
Testing that the functions have access to Livetext::Vars:
|
15
|
+
$$vars_test:some_value
|
16
|
+
|
17
|
+
That's all.
|
@@ -0,0 +1,18 @@
|
|
1
|
+
1 System Info Variables:
|
2
|
+
2 Hostname: HAL9000
|
3
|
+
3 /Platform: .*x86_64-darwin\d+/
|
4
|
+
4 /Ruby Version: \d+\.\d+\.\d+/
|
5
|
+
5 Livetext Version: 0.9.55
|
6
|
+
6 <p>
|
7
|
+
7
|
8
|
+
8 System Info Functions:
|
9
|
+
9 Hostname: HAL9000
|
10
|
+
10 /Platform: .*x86_64-darwin\d+/
|
11
|
+
11 /Ruby Version: \d+\.\d+\.\d+/
|
12
|
+
12 Livetext Version: 0.9.55
|
13
|
+
13 <p>
|
14
|
+
14
|
15
|
+
15 Date Formatting Functions:
|
16
|
+
16 /Default: \d{4}-\d{2}-\d{2}/
|
17
|
+
17 /Days ago: \d{4}-\d{2}-\d{2}/
|
18
|
+
18 /Days from now: \d{4}-\d{2}-\d{2}/
|
data/test/unit/all.rb
CHANGED
@@ -10,6 +10,9 @@ require_relative 'variables'
|
|
10
10
|
require_relative 'variable_manager'
|
11
11
|
require_relative 'functions'
|
12
12
|
require_relative 'function_registry'
|
13
|
+
require_relative 'mixin_functions_class'
|
13
14
|
require_relative 'formatter'
|
15
|
+
require_relative 'formatter_component'
|
14
16
|
require_relative 'core_methods'
|
17
|
+
require_relative 'stringparser'
|
15
18
|
|
data/test/unit/ast.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require_relative '../../lib/livetext/ast'
|
4
|
+
|
5
|
+
class TestingLivetextAST < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@ast = LivetextAST.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_ast_initialization
|
11
|
+
# Test that AST is properly initialized
|
12
|
+
assert(@ast, "AST should be initialized")
|
13
|
+
assert_instance_of(LivetextAST, @ast)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_basic_formatting
|
17
|
+
# Test basic text formatting
|
18
|
+
assert_equal([:bold, "bold"], @ast.parse_inline_formatting("*bold"))
|
19
|
+
assert_equal([:italic, "italic"], @ast.parse_inline_formatting("_italic"))
|
20
|
+
assert_equal([:code, "code"], @ast.parse_inline_formatting("`code"))
|
21
|
+
assert_equal([:strike, "strike"], @ast.parse_inline_formatting("~strike"))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_double_markers
|
25
|
+
# Test double markers
|
26
|
+
assert_equal([:bold, "bold"], @ast.parse_inline_formatting("**bold"))
|
27
|
+
assert_equal("**", @ast.parse_inline_formatting("**")) # standalone
|
28
|
+
assert_equal(" ** ", @ast.parse_inline_formatting(" ** ")) # surrounded by spaces
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_bracketed_markers
|
32
|
+
# Test bracketed markers
|
33
|
+
assert_equal([:bold, "content"], @ast.parse_inline_formatting("*[content]"))
|
34
|
+
assert_equal([:italic, "content"], @ast.parse_inline_formatting("_[content]"))
|
35
|
+
assert_equal([:code, "content"], @ast.parse_inline_formatting("`[content]"))
|
36
|
+
assert_equal([], @ast.parse_inline_formatting("*[]")) # empty brackets disappear
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_escaped_markers
|
40
|
+
# Test escaped markers
|
41
|
+
assert_equal("*literal", @ast.parse_inline_formatting("\\*literal"))
|
42
|
+
assert_equal("_literal", @ast.parse_inline_formatting("\\_literal"))
|
43
|
+
assert_equal("`literal", @ast.parse_inline_formatting("\\`literal"))
|
44
|
+
assert_equal("~literal", @ast.parse_inline_formatting("\\~literal"))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_mixed_content
|
48
|
+
# Test mixed content with text and formatting
|
49
|
+
assert_equal([:text, [:bold, "bold"], " text"], @ast.parse_inline_formatting("*bold text"))
|
50
|
+
assert_equal([:text, "Hello ", [:bold, "world!"]], @ast.parse_inline_formatting("Hello *world!"))
|
51
|
+
assert_equal([:text, [:bold, "bold,"], " ", [:italic, "italic,"], " and ", [:code, "code"]],
|
52
|
+
@ast.parse_inline_formatting("*bold, _italic, and `code"))
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_double_marker_termination
|
56
|
+
# Test double markers ending at comma and period
|
57
|
+
assert_equal([:text, [:bold, "word"], ", text"], @ast.parse_inline_formatting("**word, text"))
|
58
|
+
assert_equal([:text, [:bold, "word"], ". text"], @ast.parse_inline_formatting("**word. text"))
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_edge_cases
|
62
|
+
# Test edge cases
|
63
|
+
assert_equal([], @ast.parse_inline_formatting(nil))
|
64
|
+
assert_equal([], @ast.parse_inline_formatting(""))
|
65
|
+
assert_equal("plain text", @ast.parse_inline_formatting("plain text"))
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_complex_examples
|
69
|
+
# Test more complex examples
|
70
|
+
input = "Hello *world and **bold, text with _italic and `code"
|
71
|
+
expected = [:text, "Hello ", [:bold, "world"], " and ", [:bold, "bold"], ", text with ", [:italic, "italic"], " and ", [:code, "code"]]
|
72
|
+
assert_equal(expected, @ast.parse_inline_formatting(input))
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_bracketed_with_spaces
|
76
|
+
# Test bracketed markers with spaces
|
77
|
+
assert_equal([:text, [:bold, "This whole thing"], " is bold"],
|
78
|
+
@ast.parse_inline_formatting("*[This whole thing] is bold"))
|
79
|
+
assert_equal([:text, [:italic, "Important note"], " here"],
|
80
|
+
@ast.parse_inline_formatting("_[Important note] here"))
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_escaped_in_context
|
84
|
+
# Test escaped markers in context
|
85
|
+
assert_equal("Literal *asterisks* here",
|
86
|
+
@ast.parse_inline_formatting("Literal \\*asterisks\\* here"))
|
87
|
+
assert_equal([:text, "Mixed ", [:bold, "bold"], " and *literal* text"],
|
88
|
+
@ast.parse_inline_formatting("Mixed *bold and \\*literal\\* text"))
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require_relative '../../lib/livetext/ast'
|
4
|
+
|
5
|
+
class TestingLivetextASTDirectives < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@ast = LivetextAST.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_single_line_directives
|
11
|
+
# Single line directives (2 parameters: args, data)
|
12
|
+
assert_equal([LivetextAST::DIRECTIVE, "h1", "My Title"],
|
13
|
+
@ast.parse_directives([".h1 My Title"]))
|
14
|
+
|
15
|
+
assert_equal([LivetextAST::DIRECTIVE, "set", "name=value"],
|
16
|
+
@ast.parse_directives([".set name=value"]))
|
17
|
+
|
18
|
+
assert_equal([LivetextAST::DIRECTIVE, "comment", "This is a comment"],
|
19
|
+
@ast.parse_directives([". This is a comment"]))
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_multi_line_comment_directive
|
23
|
+
# Multi-line .comment directive
|
24
|
+
input = [
|
25
|
+
".comment",
|
26
|
+
" This is a multi-line comment",
|
27
|
+
" It can span multiple lines",
|
28
|
+
".end"
|
29
|
+
]
|
30
|
+
expected = [
|
31
|
+
LivetextAST::DIRECTIVE, "comment", "",
|
32
|
+
[LivetextAST::BODY, [" This is a multi-line comment", " It can span multiple lines"]]
|
33
|
+
]
|
34
|
+
assert_equal(expected, @ast.parse_directives(input))
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_multi_line_directives
|
38
|
+
# Multi line directives (3 parameters: args, data, body)
|
39
|
+
input = [
|
40
|
+
".list",
|
41
|
+
" * item 1",
|
42
|
+
" * item 2",
|
43
|
+
" * item 3",
|
44
|
+
".end"
|
45
|
+
]
|
46
|
+
expected = [
|
47
|
+
LivetextAST::DIRECTIVE, "list", "",
|
48
|
+
[LivetextAST::BODY, [" * item 1", " * item 2", " * item 3"]]
|
49
|
+
]
|
50
|
+
assert_equal(expected, @ast.parse_directives(input))
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_directive_with_args_and_body
|
54
|
+
input = [
|
55
|
+
".func myfunc",
|
56
|
+
" return 'Hello, World!'",
|
57
|
+
".end"
|
58
|
+
]
|
59
|
+
expected = [
|
60
|
+
LivetextAST::DIRECTIVE, "func", "myfunc",
|
61
|
+
[LivetextAST::BODY, [" return 'Hello, World!'"]]
|
62
|
+
]
|
63
|
+
assert_equal(expected, @ast.parse_directives(input))
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_missing_end_error
|
67
|
+
input = [
|
68
|
+
".list",
|
69
|
+
" * item 1",
|
70
|
+
" * item 2"
|
71
|
+
# Missing .end
|
72
|
+
]
|
73
|
+
expected = [
|
74
|
+
LivetextAST::ERROR, "Missing .end", 1, "list"
|
75
|
+
]
|
76
|
+
assert_equal(expected, @ast.parse_directives(input))
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_unknown_directive
|
80
|
+
input = [".unknown_directive some args"]
|
81
|
+
expected = [
|
82
|
+
LivetextAST::ERROR, "Unknown directive", 1, "unknown_directive"
|
83
|
+
]
|
84
|
+
assert_equal(expected, @ast.parse_directives(input))
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_empty_input
|
88
|
+
assert_equal([], @ast.parse_directives([]))
|
89
|
+
assert_equal([], @ast.parse_directives(nil))
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_non_directive_lines
|
93
|
+
input = [
|
94
|
+
"Just some text",
|
95
|
+
"More text here",
|
96
|
+
".h1 A Title",
|
97
|
+
"More text"
|
98
|
+
]
|
99
|
+
expected = [
|
100
|
+
LivetextAST::DIRECTIVE, "h1", "A Title"
|
101
|
+
]
|
102
|
+
assert_equal(expected, @ast.parse_directives(input))
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require_relative '../../lib/livetext/ast'
|
4
|
+
|
5
|
+
class TestingLivetextASTVariables < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@ast = LivetextAST.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_variable_parsing
|
11
|
+
# Basic variables
|
12
|
+
assert_equal([LivetextAST::VAR, "name"], @ast.parse_variables("$name"))
|
13
|
+
assert_equal([LivetextAST::VAR, "my_var"], @ast.parse_variables("$my_var"))
|
14
|
+
assert_equal([LivetextAST::VAR, "font.title"], @ast.parse_variables("$font.title"))
|
15
|
+
|
16
|
+
# Invalid names should be left as literal text
|
17
|
+
assert_equal("$_invalid", @ast.parse_variables("$_invalid"))
|
18
|
+
assert_equal("$3invalid", @ast.parse_variables("$3invalid"))
|
19
|
+
|
20
|
+
# Edge cases - Livetext behavior:
|
21
|
+
# $foo. -> parses $foo as variable, . as literal (matches Livetext)
|
22
|
+
assert_equal([LivetextAST::TEXT, [LivetextAST::VAR, "foo"], "."], @ast.parse_variables("$foo."))
|
23
|
+
# $a..b -> parses $a as variable, ..b as literal (matches Livetext)
|
24
|
+
assert_equal([LivetextAST::TEXT, [LivetextAST::VAR, "a"], "..b"], @ast.parse_variables("$a..b"))
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_function_parsing
|
28
|
+
# No parameter
|
29
|
+
assert_equal([LivetextAST::FUNC, "myfunc", LivetextAST::SPACE, nil], @ast.parse_functions("$$myfunc "))
|
30
|
+
assert_equal([LivetextAST::FUNC, "myfunc", LivetextAST::EOL, nil], @ast.parse_functions("$$myfunc"))
|
31
|
+
|
32
|
+
# Colon parameter
|
33
|
+
assert_equal([LivetextAST::FUNC, "greet", LivetextAST::COLON, "world"], @ast.parse_functions("$$greet:world"))
|
34
|
+
|
35
|
+
# Bracket parameter
|
36
|
+
assert_equal([LivetextAST::FUNC, "mean", LivetextAST::LBRACK, "1,2,3"], @ast.parse_functions("$$mean[1,2,3]"))
|
37
|
+
assert_equal([LivetextAST::FUNC, "title", LivetextAST::LBRACK, "My Title"], @ast.parse_functions("$$title[My Title]"))
|
38
|
+
|
39
|
+
# Note: Function parameter delimiters are tracked as requested:
|
40
|
+
# SPACE, EOL, COLON, LBRACK for debugging/future use
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_mixed_content
|
44
|
+
# Variables in text
|
45
|
+
input = "Hello $name, welcome to $nation!"
|
46
|
+
expected = [LivetextAST::TEXT, "Hello ", [LivetextAST::VAR, "name"], ", welcome to ", [LivetextAST::VAR, "nation"], "!"]
|
47
|
+
assert_equal(expected, @ast.parse_variables(input))
|
48
|
+
|
49
|
+
# Functions in text
|
50
|
+
input = "The result is $$mean[1,2,3] as expected."
|
51
|
+
expected = [LivetextAST::TEXT, "The result is ", [LivetextAST::FUNC, "mean", LivetextAST::LBRACK, "1,2,3"], " as expected."]
|
52
|
+
assert_equal(expected, @ast.parse_functions(input))
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_escaped_dollars
|
56
|
+
# Escaped variables and functions
|
57
|
+
# Note: Backslash escapes the entire $ or $$ sequence
|
58
|
+
assert_equal("\\$literal", @ast.parse_variables("\\$literal"))
|
59
|
+
assert_equal("\\$\\$literal", @ast.parse_functions("\\$\\$literal"))
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_edge_cases
|
63
|
+
# Empty strings
|
64
|
+
assert_equal([], @ast.parse_variables(""))
|
65
|
+
assert_equal([], @ast.parse_functions(""))
|
66
|
+
|
67
|
+
# No variables/functions
|
68
|
+
assert_equal("plain text", @ast.parse_variables("plain text"))
|
69
|
+
assert_equal("plain text", @ast.parse_functions("plain text"))
|
70
|
+
end
|
71
|
+
end
|
data/test/unit/core_methods.rb
CHANGED
@@ -29,6 +29,186 @@ class TestingLivetextCoreMethods < Minitest::Test
|
|
29
29
|
assert_equal(@live, result) # Should return self
|
30
30
|
end
|
31
31
|
|
32
|
+
def test_customize_with_plugin
|
33
|
+
# Test customize with a real plugin
|
34
|
+
obj = Livetext.customize(
|
35
|
+
mix: ['tutorial'],
|
36
|
+
call: [],
|
37
|
+
vars: {}
|
38
|
+
)
|
39
|
+
|
40
|
+
assert_instance_of(Livetext, obj)
|
41
|
+
# Should have loaded the tutorial plugin
|
42
|
+
assert_includes(obj.methods, :title)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_customize_with_commands
|
46
|
+
# Test customize with dot commands
|
47
|
+
obj = Livetext.customize(
|
48
|
+
mix: [],
|
49
|
+
call: ['.set VAR="test_value"'],
|
50
|
+
vars: {}
|
51
|
+
)
|
52
|
+
|
53
|
+
assert_instance_of(Livetext, obj)
|
54
|
+
# Process some text to see if the variable was set
|
55
|
+
body, vars = obj.process(text: "Variable: $VAR")
|
56
|
+
assert_includes(body, "Variable: test_value")
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_customize_with_variables
|
60
|
+
# Test customize with variables
|
61
|
+
obj = Livetext.customize(
|
62
|
+
mix: [],
|
63
|
+
call: [],
|
64
|
+
vars: { 'name' => 'World', 'title' => 'Test' }
|
65
|
+
)
|
66
|
+
|
67
|
+
assert_instance_of(Livetext, obj)
|
68
|
+
# Process some text to see if variables were set
|
69
|
+
body, vars = obj.process(text: "Hello $name\n.h1 $title")
|
70
|
+
assert_includes(body, "Hello World")
|
71
|
+
assert_includes(body, "Test")
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_customize_comprehensive
|
75
|
+
# Test all features together
|
76
|
+
obj = Livetext.customize(
|
77
|
+
mix: ['tutorial'],
|
78
|
+
call: ['.set PLUGIN_VAR="plugin_value"'],
|
79
|
+
vars: { 'custom_var' => 'custom_value' }
|
80
|
+
)
|
81
|
+
|
82
|
+
assert_instance_of(Livetext, obj)
|
83
|
+
|
84
|
+
# Test that plugin was loaded
|
85
|
+
assert_includes(obj.methods, :title)
|
86
|
+
|
87
|
+
# Test that variables were set
|
88
|
+
body, vars = obj.process(text: "Plugin: $PLUGIN_VAR\nCustom: $custom_var")
|
89
|
+
assert_includes(body, "Plugin: plugin_value")
|
90
|
+
assert_includes(body, "Custom: custom_value")
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_customize_error_handling
|
94
|
+
# Test customize with invalid plugin
|
95
|
+
assert_raises(FileNotFound) do
|
96
|
+
Livetext.customize(mix: ['nonexistent_plugin'])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_customize_empty_parameters
|
101
|
+
# Test customize with empty parameters
|
102
|
+
obj = Livetext.customize()
|
103
|
+
assert_instance_of(Livetext, obj)
|
104
|
+
|
105
|
+
# Should still work for basic processing
|
106
|
+
body, vars = obj.process(text: "Hello world")
|
107
|
+
assert_includes(body, "Hello world")
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_customize_string_vs_array
|
111
|
+
# Test that string parameters are converted to arrays
|
112
|
+
obj = Livetext.customize(
|
113
|
+
mix: 'tutorial',
|
114
|
+
call: '.nopara',
|
115
|
+
vars: { 'test' => 'value' }
|
116
|
+
)
|
117
|
+
|
118
|
+
assert_instance_of(Livetext, obj)
|
119
|
+
assert_includes(obj.methods, :title)
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_customize_variables_accessible
|
123
|
+
# Test that variables passed to customize are actually accessible afterward
|
124
|
+
obj = Livetext.customize(
|
125
|
+
mix: [],
|
126
|
+
call: [],
|
127
|
+
vars: { 'name' => 'World', 'title' => 'Test Title', 'count' => '42' }
|
128
|
+
)
|
129
|
+
|
130
|
+
assert_instance_of(Livetext, obj)
|
131
|
+
|
132
|
+
# Test that variables are accessible via vars.to_h
|
133
|
+
vars_hash = obj.vars.to_h
|
134
|
+
assert_equal('World', vars_hash[:name])
|
135
|
+
assert_equal('Test Title', vars_hash[:title])
|
136
|
+
assert_equal('42', vars_hash[:count])
|
137
|
+
|
138
|
+
# Test that variables are accessible via variables.to_h
|
139
|
+
variables_hash = obj.variables.to_h
|
140
|
+
assert_equal('World', variables_hash[:name])
|
141
|
+
assert_equal('Test Title', variables_hash[:title])
|
142
|
+
assert_equal('42', variables_hash[:count])
|
143
|
+
|
144
|
+
# Test that variables work in processing
|
145
|
+
body, vars = obj.process(text: "Hello $name\n.h1 $title\nCount: $count")
|
146
|
+
assert_includes(body, "Hello World")
|
147
|
+
assert_includes(body, "Test Title")
|
148
|
+
assert_includes(body, "Count: 42")
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_customize_variables_global_access
|
152
|
+
# Test that variables passed to customize are accessible via Livetext::Vars
|
153
|
+
obj = Livetext.customize(
|
154
|
+
mix: [],
|
155
|
+
call: [],
|
156
|
+
vars: { 'name' => 'World', 'title' => 'Test Title', 'count' => '42' }
|
157
|
+
)
|
158
|
+
|
159
|
+
assert_instance_of(Livetext, obj)
|
160
|
+
|
161
|
+
# Test that variables are accessible via Livetext::Vars (global access)
|
162
|
+
assert_equal('World', Livetext::Vars[:name])
|
163
|
+
assert_equal('Test Title', Livetext::Vars[:title])
|
164
|
+
assert_equal('42', Livetext::Vars[:count])
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_variable_dot_access
|
168
|
+
# Test that variables can be accessed via live.vars.myvar syntax
|
169
|
+
obj = Livetext.customize(
|
170
|
+
mix: [],
|
171
|
+
call: [],
|
172
|
+
vars: { 'name' => 'World', 'title' => 'Test Title', 'count' => '42' }
|
173
|
+
)
|
174
|
+
|
175
|
+
assert_instance_of(Livetext, obj)
|
176
|
+
|
177
|
+
# Test dot access syntax
|
178
|
+
assert_equal('World', obj.vars.name)
|
179
|
+
assert_equal('Test Title', obj.vars.title)
|
180
|
+
assert_equal('42', obj.vars.count)
|
181
|
+
|
182
|
+
# Test that built-in variables also work
|
183
|
+
assert_equal(Livetext::VERSION, obj.vars.Version)
|
184
|
+
assert_equal(`hostname`.chomp, obj.vars.Hostname)
|
185
|
+
|
186
|
+
# Test that respond_to? works correctly
|
187
|
+
assert(obj.vars.respond_to?(:name))
|
188
|
+
assert(obj.vars.respond_to?(:title))
|
189
|
+
assert(obj.vars.respond_to?(:Version))
|
190
|
+
assert(obj.vars.respond_to?(:nonexistent)) # Now returns true since method_missing always returns a value
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_variable_dot_access_nonexistent
|
194
|
+
# Test what happens when accessing a nonexistent variable with dot syntax
|
195
|
+
obj = Livetext.customize(
|
196
|
+
mix: [],
|
197
|
+
call: [],
|
198
|
+
vars: { 'name' => 'World' }
|
199
|
+
)
|
200
|
+
|
201
|
+
assert_instance_of(Livetext, obj)
|
202
|
+
|
203
|
+
# Test that all access methods return the same fallback message
|
204
|
+
assert_equal('[nonexistent is undefined]', obj.vars.nonexistent)
|
205
|
+
assert_equal('[nonexistent is undefined]', obj.vars[:nonexistent])
|
206
|
+
assert_equal('[nonexistent is undefined]', obj.vars.get(:nonexistent))
|
207
|
+
|
208
|
+
# Test global access also returns fallback message
|
209
|
+
assert_equal('[nonexistent is undefined]', Livetext::Vars[:nonexistent])
|
210
|
+
end
|
211
|
+
|
32
212
|
def test_process_text
|
33
213
|
# Test processing text directly
|
34
214
|
text = "Hello world\nThis is a test\n.h1 Title"
|
@@ -10,7 +10,7 @@ class TestingLivetextFormatter < Minitest::Test
|
|
10
10
|
def test_formatter_component_initialization
|
11
11
|
# Test that FormatterComponent is properly initialized
|
12
12
|
assert(@live.formatter, "FormatterComponent should be initialized")
|
13
|
-
assert_instance_of(Livetext::
|
13
|
+
assert_instance_of(Livetext::Formatter, @live.formatter)
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_basic_formatting
|