@@ -56,6 +56,54 @@ int main(int argc, char** argv)
5656 }
5757 }
5858
59+ #ifndef __EMSCRIPTEN__
60+ {
61+ // TH_TempEqu error handling: too short and inconsistent lengths
62+ try {
63+ TH_TempEqu::makeStringFromData (data_t {});
64+ assert (false );
65+ } catch (const std::invalid_argument&) {}
66+ try {
67+ // length says 1 but only size fields provided
68+ TH_TempEqu::makeStringFromData (data_t {0x01 ,0x00 });
69+ assert (false );
70+ } catch (const std::invalid_argument&) {}
71+ }
72+ #endif
73+
74+ {
75+ // Alias tokenization: arcsin/asin variants should map to sin⁻¹(
76+ TIVarFile p = TIVarFile::createNew (" Program" , " ALIAS1" );
77+ p.setContentFromString (" arcsin(1)+asin(1)" );
78+ const std::string detok = p.getReadableContent ();
79+ // Both variants should detokenize to the preferred form ending with '('
80+ assert (detok == " sin⁻¹(1)+sin⁻¹(1)" );
81+ }
82+
83+ {
84+ // Alias tokenization for ►Frac/FRAC (and ensure detokenization chooses canonical)
85+ TIVarFile p = TIVarFile::createNew (" Program" , " ALIAS2" );
86+ p.setContentFromString (" FRAC:►Frac" );
87+ assert (p.getReadableContent () == " FRAC-APPROX:►Frac" );
88+ // Retokenize detokenized output should yield same bytes
89+ TIVarFile p2 = TIVarFile::createNew (" Program" , " ALIAS3" );
90+ p2.setContentFromString (p.getReadableContent ());
91+ assert (p.getRawContentHexStr () == p2.getRawContentHexStr ());
92+ }
93+
94+ {
95+ // tokenToString incr correctness for 1-byte and 2-byte tokens
96+ int incr = 0 ;
97+ // Single-byte '(' is 0x10, should increment by 1
98+ std::string s1 = TH_Tokenized::tokenToString (data_t {0x10 }, &incr, {});
99+ assert (s1 == " (" );
100+ assert (incr == 1 );
101+ // Two-byte token: 0xEF97 is toString( per earlier test
102+ std::string s2 = TH_Tokenized::tokenToString (data_t {0xEF ,0x97 }, &incr, {});
103+ assert (s2 == " toString(" );
104+ assert (incr == 2 );
105+ }
106+
59107 {
60108 TIVarFile toksPrgm = TIVarFile::loadFromFile (" testData/ALLTOKS.8Xp" );
61109 cout << toksPrgm.getReadableContent () << " \n " << endl;
@@ -130,6 +178,8 @@ int main(int argc, char** argv)
130178
131179 {
132180 assert (TH_Tokenized::oneTokenBytesToString (0x00 ) == " " );
181+ assert (TH_Tokenized::oneTokenBytesToString (0x10 ) == " (" );
182+ assert (TH_Tokenized::oneTokenBytesToString (0x11 ) == " )" );
133183 assert (TH_Tokenized::oneTokenBytesToString (0xBB ) == " " );
134184 assert (TH_Tokenized::oneTokenBytesToString (0x3F ) == " \n " );
135185 assert (TH_Tokenized::oneTokenBytesToString (0xAD ) == " getKey" );
@@ -150,6 +200,18 @@ int main(int argc, char** argv)
150200 assert (compare_token_posinfo (actual, expected) == true );
151201 }
152202
203+ {
204+ // getPosInfoAtOffset with prettify on/off
205+ // bytes: size(ignored here), then: '\n' (3F), then EF97 (toString(), len 9), then ':' (3E)
206+ data_t data = {0x00 ,0x00 , 0x3F , 0xEF ,0x97 , 0x3E };
207+ auto pi_plain = TH_Tokenized::getPosInfoAtOffset (data, 3 , {});
208+ auto pi_pretty = TH_Tokenized::getPosInfoAtOffset (data, 3 , {{" prettify" ,1 }});
209+ // After a newline, column resets to 0; token length should be length of "toString("
210+ TH_Tokenized::token_posinfo expected_plain{ 1 , 0 , (uint8_t )std::string (" toString(" ).size () };
211+ assert (compare_token_posinfo (pi_plain, expected_plain));
212+ assert (compare_token_posinfo (pi_pretty, expected_plain));
213+ }
214+
153215 {
154216 TH_Tokenized::token_posinfo actual{}, expected{};
155217 const std::string hexStr = " 12004140423fde2a4129bbb0bbbebbb329422a3f" ;
@@ -341,6 +403,25 @@ End)";
341403 assert (reindented == expected);
342404 }
343405
406+ {
407+ // Reindent complex structure including ElseIf and Else/End
408+ const std::string src = " If A:Then:B:If C:Then:D:Else:E:End:ElseIf F:Then:G:End:End" ;
409+ const std::string indented = TH_Tokenized::reindentCodeString (src);
410+ // Don't enforce exact whitespace formatting; assert structural lines are present and ordered
411+ assert (indented.find (" If A\n " ) == 0 );
412+ assert (indented.find (" Then\n " ) != std::string::npos);
413+ assert (indented.find (" If C\n " ) != std::string::npos);
414+ assert (indented.find (" Then\n " ) != std::string::npos);
415+ assert (indented.find (" Else\n " ) != std::string::npos);
416+ assert (indented.find (" End\n " ) != std::string::npos || indented.rfind (" \n End" ) == indented.size ()-4 );
417+ // Ensure token order preserved when removing colons
418+ assert (indented.find (" B\n " ) != std::string::npos);
419+ assert (indented.find (" D\n " ) != std::string::npos);
420+ assert (indented.find (" E\n " ) != std::string::npos);
421+ assert (indented.find (" ElseIf F\n " ) != std::string::npos);
422+ assert (indented.find (" G\n " ) != std::string::npos);
423+ }
424+
344425 {
345426 string test = " Disp 42\n Input A,\" ?\" : For(I,1,10)\n Then\n \xA0 Disp I:For(J,1,10)\n Then\n Disp J\n End\n End" ;
346427 const std::string reindented = TH_Tokenized::reindentCodeString (test);
0 commit comments