livetext 0.9.52 → 0.9.56
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/imports/bookish.rb +3 -3
- 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 +110 -53
- data/lib/livetext/errors.rb +1 -0
- data/lib/livetext/expansion.rb +21 -21
- data/lib/livetext/formatter.rb +70 -200
- data/lib/livetext/formatter_component.rb +189 -0
- data/lib/livetext/function_registry.rb +163 -0
- data/lib/livetext/functions.rb +26 -0
- data/lib/livetext/handler/mixin.rb +53 -0
- data/lib/livetext/helpers.rb +33 -16
- data/lib/livetext/reopen.rb +2 -0
- data/lib/livetext/skeleton.rb +0 -3
- data/lib/livetext/standard.rb +120 -72
- data/lib/livetext/userapi.rb +20 -1
- data/lib/livetext/variable_manager.rb +78 -0
- data/lib/livetext/variables.rb +9 -1
- data/lib/livetext/version.rb +1 -1
- data/lib/livetext.rb +9 -3
- data/plugin/booktool.rb +14 -14
- data/plugin/lt3scriptor.rb +914 -0
- data/plugin/mixin_functions_class.rb +33 -0
- data/test/snapshots/complex_body/expected-error.txt +0 -0
- data/test/snapshots/complex_body/expected-output.txt +8 -0
- data/test/snapshots/complex_body/source.lt3 +19 -0
- data/test/snapshots/debug_command/expected-error.txt +0 -0
- data/test/snapshots/debug_command/expected-output.txt +1 -0
- data/test/snapshots/debug_command/source.lt3 +3 -0
- data/test/snapshots/def_parameters/expected-error.txt +0 -0
- data/test/snapshots/def_parameters/expected-output.txt +21 -0
- data/test/snapshots/def_parameters/source.lt3 +44 -0
- data/test/snapshots/error_missing_end/match-error.txt +1 -1
- data/test/snapshots/functions_reflection/expected-error.txt +0 -0
- data/test/snapshots/functions_reflection/expected-output.txt +27 -0
- data/test/snapshots/functions_reflection/source.lt3 +5 -0
- 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/mixin_functions_class.rb +33 -0
- data/test/snapshots/mixin_functions_class/source.lt3 +17 -0
- data/test/snapshots/multiple_functions/expected-error.txt +0 -0
- data/test/snapshots/multiple_functions/expected-output.txt +5 -0
- data/test/snapshots/multiple_functions/source.lt3 +16 -0
- data/test/snapshots/nested_includes/expected-error.txt +0 -0
- data/test/snapshots/nested_includes/expected-output.txt +68 -0
- data/test/snapshots/nested_includes/level2.inc +34 -0
- data/test/snapshots/nested_includes/level3.inc +20 -0
- data/test/snapshots/nested_includes/source.lt3 +49 -0
- data/test/snapshots/parameter_handling/expected-error.txt +0 -0
- data/test/snapshots/parameter_handling/expected-output.txt +7 -0
- data/test/snapshots/parameter_handling/source.lt3 +10 -0
- data/test/snapshots/subset.txt +1 -0
- data/test/snapshots/system_info/expected-error.txt +0 -0
- data/test/snapshots/system_info/match-output.txt +18 -0
- data/test/snapshots/system_info/source.lt3 +16 -0
- data/test/unit/all.rb +7 -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 +317 -0
- data/test/unit/formatter.rb +84 -0
- data/test/unit/formatter_component.rb +84 -0
- data/test/unit/function_registry.rb +132 -0
- data/test/unit/mixin_functions_class.rb +131 -0
- data/test/unit/stringparser.rb +14 -32
- data/test/unit/variable_manager.rb +71 -0
- metadata +51 -5
- data/imports/markdown.rb +0 -44
- data/lib/livetext/processor.rb +0 -88
- data/plugin/markdown.rb +0 -43
@@ -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
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Testing complex function body logic...
|
2
|
+
|
3
|
+
.func complex
|
4
|
+
if param.empty?
|
5
|
+
'nil'
|
6
|
+
elsif param == "\"\""
|
7
|
+
'empty'
|
8
|
+
elsif param.to_i.to_s == param
|
9
|
+
'number'
|
10
|
+
else
|
11
|
+
param.upcase
|
12
|
+
end
|
13
|
+
.end
|
14
|
+
|
15
|
+
Testing with nil: $$complex[]
|
16
|
+
Testing with empty: $$complex[]
|
17
|
+
Testing with number: $$complex[42]
|
18
|
+
Testing with string: $$complex[hello]
|
19
|
+
Testing explicit empty: $$complex[""]
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Testing no parameters:
|
2
|
+
No parameters method called
|
3
|
+
<p>
|
4
|
+
|
5
|
+
Testing with args and data:
|
6
|
+
Args: ["arg1", "arg2"], Data: "arg1 arg2"
|
7
|
+
This is the data line
|
8
|
+
<p>
|
9
|
+
|
10
|
+
Testing with body:
|
11
|
+
Args: ["arg1", "arg2"], Data: "arg1 arg2"
|
12
|
+
Body has 3 lines:
|
13
|
+
1: This is line 1 of the body
|
14
|
+
2: This is line 2 of the body
|
15
|
+
3: This is line 3 of the body
|
16
|
+
Testing with raw body:
|
17
|
+
Args: ["arg1", "arg2"], Data: "arg1 arg2"
|
18
|
+
Raw body has 3 lines:
|
19
|
+
1: This is line 1 of the raw body
|
20
|
+
2: This is line 2 of the raw body
|
21
|
+
3: This is line 3 of the raw body
|
@@ -0,0 +1,44 @@
|
|
1
|
+
.def no_params
|
2
|
+
api.out "No parameters method called"
|
3
|
+
.end
|
4
|
+
|
5
|
+
.def with_args args
|
6
|
+
api.out "Args: #{args.inspect}, Data: #{data.inspect}"
|
7
|
+
.end
|
8
|
+
|
9
|
+
.def with_body body
|
10
|
+
api.out "Args: #{args.inspect}, Data: #{data.inspect}"
|
11
|
+
api.out "Body has #{body.length} lines:"
|
12
|
+
body.each_with_index do |line, i|
|
13
|
+
api.out " #{i+1}: #{line}"
|
14
|
+
end
|
15
|
+
.end
|
16
|
+
|
17
|
+
.def with_body_raw body raw
|
18
|
+
api.out "Args: #{args.inspect}, Data: #{data.inspect}"
|
19
|
+
api.out "Raw body has #{body.length} lines:"
|
20
|
+
body.each_with_index do |line, i|
|
21
|
+
api.out " #{i+1}: #{line}"
|
22
|
+
end
|
23
|
+
.end
|
24
|
+
|
25
|
+
Testing no parameters:
|
26
|
+
.no_params
|
27
|
+
|
28
|
+
Testing with args and data:
|
29
|
+
.with_args arg1 arg2
|
30
|
+
This is the data line
|
31
|
+
|
32
|
+
Testing with body:
|
33
|
+
.with_body arg1 arg2
|
34
|
+
This is line 1 of the body
|
35
|
+
This is line 2 of the body
|
36
|
+
This is line 3 of the body
|
37
|
+
.end
|
38
|
+
|
39
|
+
Testing with raw body:
|
40
|
+
.with_body_raw arg1 arg2
|
41
|
+
This is line 1 of the raw body
|
42
|
+
This is line 2 of the raw body
|
43
|
+
This is line 3 of the raw body
|
44
|
+
.end
|
@@ -1 +1 @@
|
|
1
|
-
1 /
|
1
|
+
1 /expected .end but found end of file/
|
File without changes
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<h3>Available Functions</h3>
|
2
|
+
<ul>
|
3
|
+
<li><strong>$$br</strong> - builtin</li>
|
4
|
+
<li><strong>$$date</strong> - builtin</li>
|
5
|
+
<li><strong>$$day</strong> - builtin</li>
|
6
|
+
<li><strong>$$days_ago</strong> - builtin</li>
|
7
|
+
<li><strong>$$days_from_now</strong> - builtin</li>
|
8
|
+
<li><strong>$$format_date</strong> - builtin</li>
|
9
|
+
<li><strong>$$hostname</strong> - builtin</li>
|
10
|
+
<li><strong>$$hour</strong> - builtin</li>
|
11
|
+
<li><strong>$$isqrt</strong> - builtin</li>
|
12
|
+
<li><strong>$$link</strong> - builtin</li>
|
13
|
+
<li><strong>$$livetext_version</strong> - builtin</li>
|
14
|
+
<li><strong>$$minute</strong> - builtin</li>
|
15
|
+
<li><strong>$$month</strong> - builtin</li>
|
16
|
+
<li><strong>$$platform</strong> - builtin</li>
|
17
|
+
<li><strong>$$pwd</strong> - builtin</li>
|
18
|
+
<li><strong>$$rand</strong> - builtin</li>
|
19
|
+
<li><strong>$$reverse</strong> - builtin</li>
|
20
|
+
<li><strong>$$ruby_version</strong> - builtin</li>
|
21
|
+
<li><strong>$$second</strong> - builtin</li>
|
22
|
+
<li><strong>$$testfunc</strong> - inline (unknown)</li>
|
23
|
+
<li><strong>$$time</strong> - builtin</li>
|
24
|
+
<li><strong>$$week</strong> - builtin</li>
|
25
|
+
<li><strong>$$weekday</strong> - builtin</li>
|
26
|
+
<li><strong>$$year</strong> - builtin</li>
|
27
|
+
</ul>
|
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,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.
|
File without changes
|
File without changes
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Main file - Level 1
|
2
|
+
# This file includes level2 and tests all variables and functions from all levels
|
3
|
+
<p>
|
4
|
+
|
5
|
+
# Include level2 (which includes level3)
|
6
|
+
# Level 2 - Middle level
|
7
|
+
# This file includes level3 and defines its own variables and functions
|
8
|
+
<p>
|
9
|
+
|
10
|
+
# Level 3 - Deepest level
|
11
|
+
# This file defines variables and functions that should be accessible to all higher levels
|
12
|
+
<p>
|
13
|
+
|
14
|
+
This is content from level 3.
|
15
|
+
The deep variable is: I am from level 3
|
16
|
+
The deep number is: 42
|
17
|
+
This is content from level 2.
|
18
|
+
The middle variable is: I am from level 2
|
19
|
+
The middle number is: 100
|
20
|
+
<p>
|
21
|
+
|
22
|
+
# Test using deep level variables and functions
|
23
|
+
Deep variable from level 2: I am from level 3
|
24
|
+
Deep function call: Deep function called with: from level 2
|
25
|
+
Deep math: 42 = 42
|
26
|
+
<p>
|
27
|
+
|
28
|
+
# Test our own variables and functions
|
29
|
+
Middle function call: Middle function called with: from level 2
|
30
|
+
Combined variables: Deep: I am from level 3, Middle: I am from level 2
|
31
|
+
<p>
|
32
|
+
|
33
|
+
# Test deep method from level 3
|
34
|
+
Deep method called from level 3
|
35
|
+
# Test all variables from all levels
|
36
|
+
Main variable: I am from main level
|
37
|
+
Middle variable: I am from level 2
|
38
|
+
Deep variable: I am from level 3
|
39
|
+
<p>
|
40
|
+
|
41
|
+
# Test all functions from all levels
|
42
|
+
Main function: Main function called with: from main
|
43
|
+
Middle function: Middle function called with: from main
|
44
|
+
Deep function: Deep function called with: from main
|
45
|
+
<p>
|
46
|
+
|
47
|
+
# Test math functions
|
48
|
+
Deep math: 20 = 20
|
49
|
+
Main number: 999
|
50
|
+
Middle number: 100
|
51
|
+
Deep number: 42
|
52
|
+
<p>
|
53
|
+
|
54
|
+
# Test combined functions
|
55
|
+
Combine vars: Deep: I am from level 3, Middle: I am from level 2
|
56
|
+
Test all levels: Main: I am from main level, Middle: I am from level 2, Deep: I am from level 3
|
57
|
+
<p>
|
58
|
+
|
59
|
+
# Test methods from all levels
|
60
|
+
Main method called from main level
|
61
|
+
Middle method called from level 2
|
62
|
+
Deep method called from level 3
|
63
|
+
<p>
|
64
|
+
|
65
|
+
# Test that we can still access everything after the include
|
66
|
+
Final test - deep function: Deep function called with: final call
|
67
|
+
Final test - middle function: Middle function called with: final call
|
68
|
+
Final test - main function: Main function called with: final call
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Level 2 - Middle level
|
2
|
+
# This file includes level3 and defines its own variables and functions
|
3
|
+
|
4
|
+
.include level3.inc
|
5
|
+
|
6
|
+
.set middle_var="I am from level 2", middle_number=100
|
7
|
+
|
8
|
+
.func middle_function
|
9
|
+
"Middle function called with: " + param
|
10
|
+
.end
|
11
|
+
|
12
|
+
.func combine_vars
|
13
|
+
"Deep: " + "I am from level 3" + ", Middle: " + "I am from level 2"
|
14
|
+
.end
|
15
|
+
|
16
|
+
This is content from level 2.
|
17
|
+
The middle variable is: $middle_var
|
18
|
+
The middle number is: $middle_number
|
19
|
+
|
20
|
+
# Test using deep level variables and functions
|
21
|
+
Deep variable from level 2: $deep_var
|
22
|
+
Deep function call: $$deep_function[from level 2]
|
23
|
+
Deep math: $$deep_math[21] = 42
|
24
|
+
|
25
|
+
# Test our own variables and functions
|
26
|
+
Middle function call: $$middle_function[from level 2]
|
27
|
+
Combined variables: $$combine_vars[]
|
28
|
+
|
29
|
+
.def middle_method
|
30
|
+
api.out "Middle method called from level 2"
|
31
|
+
.end
|
32
|
+
|
33
|
+
# Test deep method from level 3
|
34
|
+
.deep_method
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Level 3 - Deepest level
|
2
|
+
# This file defines variables and functions that should be accessible to all higher levels
|
3
|
+
|
4
|
+
.set deep_var="I am from level 3", deep_number=42
|
5
|
+
|
6
|
+
.func deep_function
|
7
|
+
"Deep function called with: " + param
|
8
|
+
.end
|
9
|
+
|
10
|
+
.func deep_math
|
11
|
+
(param.to_i * 2).to_s
|
12
|
+
.end
|
13
|
+
|
14
|
+
.def deep_method
|
15
|
+
api.out "Deep method called from level 3"
|
16
|
+
.end
|
17
|
+
|
18
|
+
This is content from level 3.
|
19
|
+
The deep variable is: $deep_var
|
20
|
+
The deep number is: $deep_number
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Main file - Level 1
|
2
|
+
# This file includes level2 and tests all variables and functions from all levels
|
3
|
+
|
4
|
+
.set main_var="I am from main level", main_number=999
|
5
|
+
|
6
|
+
.func main_function
|
7
|
+
"Main function called with: " + param
|
8
|
+
.end
|
9
|
+
|
10
|
+
.func test_all_levels
|
11
|
+
"Main: " + "I am from main level" + ", Middle: " + "I am from level 2" + ", Deep: " + "I am from level 3"
|
12
|
+
.end
|
13
|
+
|
14
|
+
# Include level2 (which includes level3)
|
15
|
+
.include level2.inc
|
16
|
+
|
17
|
+
# Test all variables from all levels
|
18
|
+
Main variable: $main_var
|
19
|
+
Middle variable: $middle_var
|
20
|
+
Deep variable: $deep_var
|
21
|
+
|
22
|
+
# Test all functions from all levels
|
23
|
+
Main function: $$main_function[from main]
|
24
|
+
Middle function: $$middle_function[from main]
|
25
|
+
Deep function: $$deep_function[from main]
|
26
|
+
|
27
|
+
# Test math functions
|
28
|
+
Deep math: $$deep_math[10] = 20
|
29
|
+
Main number: $main_number
|
30
|
+
Middle number: $middle_number
|
31
|
+
Deep number: $deep_number
|
32
|
+
|
33
|
+
# Test combined functions
|
34
|
+
Combine vars: $$combine_vars[]
|
35
|
+
Test all levels: $$test_all_levels[]
|
36
|
+
|
37
|
+
.def main_method
|
38
|
+
api.out "Main method called from main level"
|
39
|
+
.end
|
40
|
+
|
41
|
+
# Test methods from all levels
|
42
|
+
.main_method
|
43
|
+
.middle_method
|
44
|
+
.deep_method
|
45
|
+
|
46
|
+
# Test that we can still access everything after the include
|
47
|
+
Final test - deep function: $$deep_function[final call]
|
48
|
+
Final test - middle function: $$middle_function[final call]
|
49
|
+
Final test - main function: $$main_function[final call]
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Testing function parameter handling...
|
2
|
+
|
3
|
+
.func testparam
|
4
|
+
param.empty? ? 'nil' : param
|
5
|
+
.end
|
6
|
+
|
7
|
+
Testing with no parameter: $$testparam[]
|
8
|
+
Testing with empty parameter: $$testparam[]
|
9
|
+
Testing with string parameter: $$testparam[hello]
|
10
|
+
Testing with number parameter: $$testparam[42]
|
data/test/snapshots/subset.txt
CHANGED
@@ -23,6 +23,7 @@ h This file specifies which snapshots will/won't be run.
|
|
23
23
|
|
24
24
|
# import/include/mixin, others...
|
25
25
|
|
26
|
+
|
26
27
|
error_no_such_inc # Output BEFORE error doesn't get passed through ("leading" output)
|
27
28
|
error_no_such_copy # ^ Same behavior as error_no_such_inc
|
28
29
|
error_no_such_mixin # ^ Same behavior as error_missing_end
|
File without changes
|
@@ -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}/
|
@@ -0,0 +1,16 @@
|
|
1
|
+
System Info Variables:
|
2
|
+
Hostname: $Hostname
|
3
|
+
Platform: $Platform
|
4
|
+
Ruby Version: $RubyVersion
|
5
|
+
Livetext Version: $LivetextVersion
|
6
|
+
|
7
|
+
System Info Functions:
|
8
|
+
Hostname: $$hostname
|
9
|
+
Platform: $$platform
|
10
|
+
Ruby Version: $$ruby_version
|
11
|
+
Livetext Version: $$livetext_version
|
12
|
+
|
13
|
+
Date Formatting Functions:
|
14
|
+
Default: $$format_date
|
15
|
+
Days ago: $$days_ago[7]
|
16
|
+
Days from now: $$days_from_now[7]
|
data/test/unit/all.rb
CHANGED
@@ -7,5 +7,12 @@ require_relative 'single'
|
|
7
7
|
require_relative 'double'
|
8
8
|
require_relative 'bracketed'
|
9
9
|
require_relative 'variables'
|
10
|
+
require_relative 'variable_manager'
|
10
11
|
require_relative 'functions'
|
12
|
+
require_relative 'function_registry'
|
13
|
+
require_relative 'mixin_functions_class'
|
14
|
+
require_relative 'formatter'
|
15
|
+
require_relative 'formatter_component'
|
16
|
+
require_relative 'core_methods'
|
17
|
+
require_relative 'stringparser'
|
11
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
|