/******************************************************************************* * Copyright (c) 2012, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package dtool.sourcegen; import static dtool.sourcegen.TemplatedSourceProcessor.StandardErrors.MISMATCHED_VARIATION_SIZE; import static dtool.sourcegen.TemplatedSourceProcessor.StandardErrors.REDEFINITION; import static dtool.sourcegen.TemplatedSourceProcessor.StandardErrors.UNDEFINED_REFER; import org.junit.FixMethodOrder; import org.junit.Ignore; import org.junit.Test; import org.junit.runners.MethodSorters; import dtool.sourcegen.AnnotatedSource.MetadataEntry; import dtool.sourcegen.TemplatedSourceProcessor.StandardErrors; /* BASIC EXPANSION FORMATS: A: #@{1, 2, 3} Unnamed-Expansion B: #@EXP{1, 2, 3} Definition-Expansion B2: #@EXP!{1, 2, 3} Definition-only Bx: #@EXP Full-Reference R1: #@{1, 2, 3}(EXP) Expansion, pairing with active(EXP) R2: #@EXP2(EXP) Refer-Expansion(EXP2), pairing with active(EXP) R3: #@EXP2{1,2,3}(EXP) Definition-Expansion, pairing with active(EXP) H: #@^EXP Unpaired Full-Reference */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TemplatedSourceProcessorExpansionTest extends TemplatedSourceProcessorCommonTest { @Test public void test1_ExpansionSyntax() throws Exception { testExpansionSyntax$(); } public void testExpansionSyntax$() throws Exception { // Basic syntax, escapes testSourceProcessing("#", "asdf ## #{,#},#,,##, ,line}==", checkMD("asdf # =="),checkMD("asdf # }=="), checkMD("asdf # ,=="), checkMD("asdf # #=="), checkMD("asdf # =="), checkMD("asdf # line==") ); testSourceProcessing("#", "xx #{,#},## #{a,xxx#}#,},last}==", checkMD("xx =="),checkMD("xx }=="),checkMD("xx # a=="),checkMD("xx # xxx},=="),checkMD("xx last==") ); // Syntax errors: testSourceProcessing("#", "foo #@{", 7); testSourceProcessing("#", "foo #@==", 6); testSourceProcessing("#", "foo #@!", 7); testSourceProcessing("#", "foo #@EXPANSION1{", 17); testSourceProcessing("#", "foo #@EXPANSION1(", 17); testSourceProcessing("#", "foo #@EXPANSION1(EXP:", 17+3); testSourceProcessing("#", "foo #@EXPANSION1{12,}(", 22); testSourceProcessing("#", "foo #@EXPANSION1{12,}(EXP:", 22+3); testSourceProcessing("#", "> #@!(EXP2)", 5); } @Test public void test2_ExpansionAdvancedSyntax() throws Exception { testExpansionAdvancedSyntax$(); } public void testExpansionAdvancedSyntax$() throws Exception { // Different kmarker testSourceProcessing("#!", "asdf #ok #!{,#!},#!#! #!{a,xxx#!}#!,},last#}!==", checkMD("asdf #ok !=="), checkMD("asdf #ok }!=="), checkMD("asdf #ok #! a!=="), checkMD("asdf #ok #! xxx},!=="), checkMD("asdf #ok last#!==") ); // Uniform list close syntax ---- testSourceProcessing("#", "> #@{A,B,C,\n ¤}==", checkMD("> A=="), checkMD("> B=="), checkMD("> C==") ); testSourceProcessing("#", "> #@{xxx, b ,text\n¤}==", 19); testSourceProcessing("#", "> #@{xxx, b ,\n¤ }==", 16); // Uniform argument separator syntax ---- testSourceProcessing("#", "> #@{►\nasd,► ,line}==", checkMD("> \nasd=="), checkMD("> =="), checkMD("> line==") ); testSourceProcessing("#", "> #@《 ►\nasdf● ► ● line》==", checkMD("> \nasdf=="), checkMD("> =="), checkMD("> line==") ); testSourceProcessing("#", "> #@{ text ►abc\ndef, ,line,\n}==", 12); testSourceProcessing("#", "> #@{ ► ►abc\ndef, ,line,\n}==", 10); // Uniform argument separator syntax -- in metadata testSourceProcessing("#", "> #MD(►xyz, line\n){ ►ABC,line}==", checkMD("> ►ABC,line==", new MetadataEntry("MD", "►xyz, line\n", " ►ABC,line", 2, true))); testSourceProcessing("#", "> #MD:\n►asd, line\n ==", checkMD("> ", new MetadataEntry("MD", null, "►asd, line\n ==", 2, false))); // Syntax errors: interactions: testSourceProcessing("#", "foo #@EXPANSION1{12,}:EXP:", checkMD("foo 12:EXP:"), checkMD("foo :EXP:")); testSourceProcessing("#", "> #,", 3); testSourceProcessing("#", "> #}", 3); testSourceProcessing("#", "foo #@EXPANSION1{12#:SPLIT\n}", 19); testSourceProcessing("#", "foo #@EXPANSION1{12#:END:\n}", 20+4); testSourceProcessing("#", "foo #@EXPANSION1{12}(#:SPLIT\n)", 21); testSourceProcessing("#", "foo #@EXPANSION1{12}(xxx:END:\n)", 21+3); for (int i = 0; i < TemplatedSourceProcessorParser.OPEN_DELIMS.length; i++) { String openDelim = TemplatedSourceProcessorParser.OPEN_DELIMS[i]; if(openDelim.equals("{")) continue; String close = TemplatedSourceProcessorParser.CLOSE_DELIMS[i]; testSourceProcessing("#", prepString("asdf #@EXP►,}◙► #◄,last#◙}◄==", openDelim, close), checkMD(prepString("asdf ,}==", openDelim, close)), checkMD(prepString("asdf ► ◄,last●}==", openDelim, close)) ); testSourceProcessing("#", prepString("asdf #► ", openDelim, close), 6); } } @Test public void test3_Expansion() throws Exception { testExpansion$(); } public void testExpansion$() throws Exception { // A: Unnamed-Expansion testSourceProcessing("#", "foo #@{var1,var2#,,var3##}==", checkMD("foo var1=="), checkMD("foo var2,=="), checkMD("foo var3#==") ); // B: #@EXP{1, 2, 3} Definition-Expansion //Error: redefined: testSourceProcessing("#", "foo #@EXP1{a,b} -- #@EXP1{a,b}", REDEFINITION, "EXP1"); testSourceProcessing("#", "foo #@EXP1{a,#@EXP1{a,b}}", REDEFINITION, "EXP1"); testSourceProcessing("#", "foo #@EXP1《¤》", StandardErrors.NO_ARGUMENTS, "EXP1"); // B2: #@EXP!{1, 2, 3} Definition only testSourceProcessing("#", "foo #@EXPANSION1! -- #@EXPANSION1{a,b}", 17); // Bad syntax: no args testSourceProcessing("#", "foo #@! -- #@EXPANSION1{a,b}", 7); // Bad syntax: no id testSourceProcessing("#", "foo #@EXPANSION1!{a,b} -- #@EXPANSION1{a,b}", REDEFINITION, "EXPANSION1"); testSourceProcessing("#", "> #@EXPANSION1!{A,B,C} b", checkMD("> b")); // Bx: #@EXP Full-Reference testSourceProcessing("#", "> #@EXP2", UNDEFINED_REFER, "EXP2"); testSourceProcessing("#", "#@EXPANSION1{var1,var2,var3} == #@EXPANSION1", checkMD("var1 == var1"), checkMD("var2 == var2"), checkMD("var3 == var3") ); testSourceProcessing("#", "foo #@EXPANSION1{var1,var2,var3} == #{a,xxx} -- #@EXPANSION1", checkMD("foo var1 == a -- var1"), checkMD("foo var1 == xxx -- var1"), checkMD("foo var2 == a -- var2"), checkMD("foo var2 == xxx -- var2"), checkMD("foo var3 == a -- var3"), checkMD("foo var3 == xxx -- var3") ); testSourceProcessing("#", "#@EXPANSION1!{var1,var2,var3}"+ "#@EXPANSION1 == #@EXPANSION1", checkMD("var1 == var1"), checkMD("var2 == var2"), checkMD("var3 == var3") ); testSourceProcessing("#", "foo #@EXPANSION1!{a,#@EXPANSION1{a,b}} #@EXPANSION1", REDEFINITION, "EXPANSION1"); //R1: #@{1, 2, 3}(EXP) Expansion, pairing with active(EXP) //R2: #@EXP2(EXP) Refer-Expansion(EXP2), pairing with active(EXP) //R3: #@EXP2{1,2,3}(EXP) Definition-Expansion, pairing with active(EXP) testSourceProcessing("#", "> #@(EXPANSION1)", 16); // Syntax error // Error: undefined ref testSourceProcessing("#", "> #@{A,B,C}(EXPANSION1)", UNDEFINED_REFER, ":EXPANSION1"); testSourceProcessing("#", "> #@EXP2(EXPANSION1)", UNDEFINED_REFER, "EXP2:EXPANSION1"); testSourceProcessing("#", "> #@EXP2{A,B,C}(EXPANSION1)", UNDEFINED_REFER, "EXP2:EXPANSION1"); testSourceProcessing("#", "#@H_EXP!{z1,z2,z3}"+ "> #@H_EXP(EXPANSION1)", UNDEFINED_REFER, "H_EXP:EXPANSION1"); //Error: Mismatched argument count: testSourceProcessing("#", "> #@EXP1{a,b} -- #@{a}(EXP1)", MISMATCHED_VARIATION_SIZE, ":EXP1"); testSourceProcessing("#", "> #@EXP1{a,b} -- #@{a,b,c}(EXP1)", MISMATCHED_VARIATION_SIZE, ":EXP1"); testSourceProcessing("#", "> #@EXP1{a,b} -- #@EXP2{a,b,c}(EXP1)", MISMATCHED_VARIATION_SIZE, "EXP2:EXP1"); testSourceProcessing("#", "> #@H_EXP{a,b} -- #@{a,b,c}(H_EXP)", MISMATCHED_VARIATION_SIZE, ":H_EXP"); testSourceProcessing("#", "foo #@EXPANSION1{var1,var2,var3}==#@{A,B,C}(EXPANSION1)", checkMD("foo var1==A"), checkMD("foo var2==B"), checkMD("foo var3==C") ); testSourceProcessing("#", "#@EXPANSION1!{var1,var2,var3}"+ "#@EXPANSION1 == #@{A,B,C}(EXPANSION1)", checkMD("var1 == A"), checkMD("var2 == B"), checkMD("var3 == C") ); testSourceProcessing("#", "#@EXPANSION1!{var1,var2,var3}" + "#@{A,B,C}(EXPANSION1) == #@EXPANSION1", checkMD("A == var1"), checkMD("B == var2"), checkMD("C == var3") ); testSourceProcessing("#", "#@EXP2!{A,B,C}"+ "#@EXP1{var1,var2,var3}"+"==#@EXP2(EXP1) -- #@{x,y,z}(EXP1)", checkMD("var1==A -- x"), checkMD("var2==B -- y"), checkMD("var3==C -- z") ); testSourceProcessing("#", "#@EXP1{var1,var2,var3}"+"==#@EXP2{A,B,C}(EXP1) -- #@{x,y,z}(EXP1)", checkMD("var1==A -- x"), checkMD("var2==B -- y"), checkMD("var3==C -- z") ); // Make sure both H_EXP and EXP ids can be referred (master id != master element id) testSourceProcessing("#", "#@H_EXP!{var1,var2,var3}" + "#@EXP{A,B,C}(H_EXP) #@{x,y,z}(EXP)--#@H_EXP", checkMD("A x--var1"), checkMD("B y--var2"), checkMD("C z--var3") ); // test indirect pairing master: EXP2->EXP1 testSourceProcessing("#", "#@EXP1{var1,var2,var3}"+"#@EXP2!{z1,z2,z3}"+"> #@EXP2(EXP1) -- #@{A,B,C}(EXP2)", checkMD("var1> z1 -- A"), checkMD("var2> z2 -- B"), checkMD("var3> z3 -- C") ); // another indirect pairing master (through define-only) : EXP2->EXP1 testSourceProcessing("#", "#@EXP1{var1,var2,var3}"+"#@EXP2!{z1,z2,z3}(EXP1)"+"> #@EXP2 -- #@{A,B,C}(EXP2)", checkMD("var1> z1 -- A"), checkMD("var2> z2 -- B"), checkMD("var3> z3 -- C") ); testSourceProcessing("#", "#@EXPANSION1{var1,var2,var3}==#@EXP2{VAR1,VAR2,VAR3}(EXPANSION1) ||"+ " #@EXPANSION1•X == #@EXP2", checkMD("var1==VAR1 || var1X == VAR1"), checkMD("var2==VAR2 || var2X == VAR2"), checkMD("var3==VAR3 || var3X == VAR3") ); // H: #@^EXP Unnamed-Expansion with argument referral(EXP) testSourceProcessing("#", "> #@^{1,2,3}", 5); // Bad syntax: no name testSourceProcessing("#", "> #@^EXP1!{1,2,3}", 10); // Bad syntax: has define only testSourceProcessing("#", "> #@^EXP1{1,2,3}", 16); // Bad syntax: ^ with arguments (makes definition) testSourceProcessing("#", "> #@^EXP1(EXP2)", 10); // Bad syntax: has refer id GeneratedSourceChecker[] expectedCasesH = array( checkMD("> var1 -- var1"), checkMD("> var1 -- var2"), checkMD("> var1 -- var3"), checkMD("> var2 -- var1"), checkMD("> var2 -- var2"), checkMD("> var2 -- var3"), checkMD("> var3 -- var1"), checkMD("> var3 -- var2"), checkMD("> var3 -- var3")); testSourceProcessing("#", "#@EXP1!{var1,var2,var3}> #@^EXP1 -- #@EXP1", expectedCasesH ); testSourceProcessing("#", "> #@EXP1{var1,var2,var3} -- #@^EXP1", expectedCasesH ); testSourceProcessing("#", "#@EXP1!{var1,var2,var3}"+ "#@EXP2!{1,2,3}"+ "> #@EXP1 -- #@EXP2 - #@EXP1(EXP2)", checkMD("> var1 -- 1 - var1"), checkMD("> var1 -- 2 - var2"), checkMD("> var1 -- 3 - var3"), checkMD("> var2 -- 1 - var1"), checkMD("> var2 -- 2 - var2"), checkMD("> var2 -- 3 - var3"), checkMD("> var3 -- 1 - var1"), checkMD("> var3 -- 2 - var2"), checkMD("> var3 -- 3 - var3") ); testSourceProcessing("#","#@EXP1!{var1,var2,var3}"+ "> #@^EXP1 -- #@{1,2,3}(EXP1)", checkMD("> var1 -- 1"), checkMD("> var1 -- 2"), checkMD("> var1 -- 3"), checkMD("> var2 -- 1"), checkMD("> var2 -- 2"), checkMD("> var2 -- 3"), checkMD("> var3 -- 1"), checkMD("> var3 -- 2"), checkMD("> var3 -- 3") ); // ============== Advanced cases ============== // ------------- Test some nesting issues: ------------- testSourceProcessing("#", "#@EXP{var1,#@SUB【var2A●var2B】,var3}==#@{A,#@SUB,#@【C】}(EXP)", checkMD("var1==A"), checkMD("var2A==var2A"), checkMD("var2B==var2B"), checkMD("var3==C") ); testSourceProcessing("#", "#@EXP{var1,#@SUB【var2A●var2B】,var3}==#@{A,#@【var2A●var2B】(SUB),#@【C】}(EXP)", checkMD("var1==A"), checkMD("var2A==var2A"), checkMD("var2B==var2B"), checkMD("var3==C") ); testSourceProcessing("#", "#@EXPANSION1{var1,var2,var3}==#@{A,#@【B1●B2】,C}(EXPANSION1)", checkMD("var1==A"), checkMD("var2==B1"), checkMD("var2==B2"), checkMD("var3==C") ); testSourceProcessing("#", "foo #@EXPANSION1{var1,#@【var2A●var2B】,var3}==#@{A,B,C}(EXPANSION1)", checkMD("foo var1==A"), checkMD("foo var2A==B"), checkMD("foo var2B==B"), checkMD("foo var3==C") ); // Visibility of nested-definitions: testSourceProcessing("#", ">#@{#@INNER_EXP{A,B,C},#@INNER_EXP{A,B}}", checkMD(">A"),checkMD(">B"),checkMD(">C"), checkMD(">A"),checkMD(">B")); testSourceProcessing("#", "> #@{#@INNER_EXP{A,B,C}, #@INNER_EXP}", UNDEFINED_REFER, "INNER_EXP"); testSourceProcessing("#", "> #@{#@INNER_EXP{A,B,C}, } #@INNER_EXP", UNDEFINED_REFER, "INNER_EXP"); // Define-only with nested: TODO: testSourceProcessing("#", "#@H_EXP!{var1,#@SUB【var2A●var2B】,var3}"+"#@H_EXP==#@H_EXP", checkMD("var1==var1"), checkMD("var2A==var2A"), checkMD("var2B==var2B"), checkMD("var3==var3") ); // Nested-definitions: testSourceProcessing("#", ">#@EXPA!{A,B,C} #@X{#@EXPA,x} #@X", checkMD("> A A"), checkMD("> B B"), checkMD("> C C"), checkMD("> x x") ); testSourceProcessing("#", "> #@X{#@EXPA{A,B,C},x} #@X", checkMD("> A A"), checkMD("> B B"), checkMD("> C C"), checkMD("> x x") ); } @Test public void test4_Discard() throws Exception { testDiscard$(); } public void testDiscard$() throws Exception { testSourceProcessing("#", "> #@{A,B #:DISCARD_CASE ,C}==", checkMD("> A=="), checkMD("> C==") ); testSourceProcessing("#", "Ⓗ━━\n #@FOO《A● B #:DISCARD_CASE ●-C-》 ━━\n> #@FOO<", checkMD("> A<"), checkMD("> -C-<") ); // discard only existing case testSourceProcessing("#", "> #:DISCARD_CASE =="); } @Test public void test5_ExpansionWithSplit() throws Exception { testExpansionWithSplit$(); } public void testExpansionWithSplit$() throws Exception { testSourceProcessing("#", "#:SPLIT ____\n"+"#@EXPANSION1{var1,var2#,,var3##}"+ "#:SPLIT\n> #@EXPANSION1", StandardErrors.UNDEFINED_REFER, "EXPANSION1" ); testSourceProcessing("#", "#:HEADER ____header____\n"+ "#@EXPANSION1{var1,var2,var3}"+ "#@EXPANSION2{A,BB,CCC}"+ "#:SPLIT ___\n> #@EXPANSION2{xxxA,xxxb,xxxc}", StandardErrors.REDEFINITION, "EXPANSION2" ); testSourceProcessing("#", "#:HEADER ____\n"+"#@EXPANSION1{var1,var2,var3}"+ "#:SPLIT\n> #@EXPANSION1", checkMD("> var1"), checkMD("> var2"), checkMD("> var3") ); testSourceProcessing("#", "#:HEADER ____\n"+"#@EXPANSION1{var1,var2,var3}"+ "#:SPLIT\n> #@EXPANSION1 == #@{A,B,C}(EXPANSION1)", checkMD("> var1 == A"), checkMD("> var2 == B"), checkMD("> var3 == C") ); testSourceProcessing("#", "#:HEADER ____\n"+"#@EXPANSION1{var1,var2,var3}"+ "#:SPLIT\n> #@EXPANSION1 == #@EXPANSION1", checkMD("> var1 == var1"), checkMD("> var2 == var2"), checkMD("> var3 == var3") ); // Activate only testSourceProcessing("#", "#:HEADER ____\n"+"#@EXPANSION1{var1,var2,var3}"+ "#:SPLIT\n> #@{A,B,C}(EXPANSION1) -- #@EXPANSION1", checkMD("> A -- var1"), checkMD("> B -- var2"), checkMD("> C -- var3") ); // Across cases testSourceProcessing("#", "#:HEADER ____header____\n"+ "#@EXPAN_X{X,ZZ}"+ "#@EXPANSION1{var1,var2,var3}"+ "#:SPLIT ___\n1: #@EXPANSION3{xxxA,xxxB,xxxC}(EXPANSION1) == #@EXPANSION1"+ "#:SPLIT ___\n2: "+ "#@EXPAN_X _ #@EXPANSION3{xA,xxB,xxxC}(EXPANSION1) == #@{a,bb}(EXPAN_X)", checkMD("1: xxxA == var1"), checkMD("1: xxxB == var2"), checkMD("1: xxxC == var3"), checkMD("2: X _ xA == a"), checkMD("2: X _ xxB == a"), checkMD("2: X _ xxxC == a"), checkMD("2: ZZ _ xA == bb"), checkMD("2: ZZ _ xxB == bb"), checkMD("2: ZZ _ xxxC == bb") ); // Nested testSourceProcessing("#", "#:HEADER ____\n"+"#@EXPANSION1{var1,var2,var3}━━\n"+ "> #@OUTER{.#@EXPANSION1.,B} -- #@EXPANSION1", checkMD("> .var1. -- var1"), checkMD("> .var2. -- var2"), checkMD("> .var3. -- var3"), checkMD("> B -- var1"), checkMD("> B -- var2"), checkMD("> B -- var3") ); testSourceProcessing("#", "#:HEADER ____\n"+"#@EXPANSION1{var1,var2,var3}━━\n"+ "> #@EXPANSION1 -- #@OUTER{.#@EXPANSION1.,B}", checkMD("> var1 -- .var1."), checkMD("> var1 -- B"), checkMD("> var2 -- .var2."), checkMD("> var2 -- B"), checkMD("> var3 -- .var3."), checkMD("> var3 -- B") ); testSourceProcessing("#", "#:HEADER ____\n"+"#@EXPANSION1{var1,var2,var3}━━\n"+ "> #@{b,.#@EXPANSION1.} -- #@OUTER{.#@EXPANSION1.,B}", checkMD("> b -- .var1."), checkMD("> b -- .var2."), checkMD("> b -- .var3."), checkMD("> b -- B"), checkMD("> .var1. -- .var1."), checkMD("> .var1. -- B"), checkMD("> .var2. -- .var2."), checkMD("> .var2. -- B"), checkMD("> .var3. -- .var3."), checkMD("> .var3. -- B") ); testSourceProcessing("#", "#:HEADER ____\n"+"#@EXPANSION1{var1,var2,var3}"+ "#:SPLIT\n> #@OUTER{.#@EXPANSION1.,~#@EXPANSION1~} -- #@EXPANSION1", checkMD("> .var1. -- var1"), checkMD("> .var2. -- var2"), checkMD("> .var3. -- var3"), checkMD("> ~var1~ -- var1"), checkMD("> ~var2~ -- var2"), checkMD("> ~var3~ -- var3") ); } /* ------------------------ METADATA-EXPANSION interactions ------------------------ */ @Test public void test6_Metadata_Interactions() throws Exception { testMetadata_Interactions$(); } public void testMetadata_Interactions$() throws Exception { testSourceProcessing("#", "asdf #{#}#tag_A(asfd,3,4){xxx},abc###tag_B(arg1,arg2,arg3){sourceValue2}}==#{1,xxx}", checkMD("asdf }xxx==1", new MetadataEntry("tag_A", "asfd,3,4", "xxx", 6)), checkMD("asdf }xxx==xxx", new MetadataEntry("tag_A", "asfd,3,4", "xxx", 6)), checkMD("asdf abc#sourceValue2==1", new MetadataEntry("tag_B", "arg1,arg2,arg3", "sourceValue2", 9)), checkMD("asdf abc#sourceValue2==xxx", new MetadataEntry("tag_B", "arg1,arg2,arg3", "sourceValue2", 9)) ); testSourceProcessing("#", "#{1,xxx}asdf #{#}#tag_A(asfd,3,4){xxx},###tag_B(arg1,arg2,arg3){sourceValue2}}==", checkMD("1asdf }xxx==", new MetadataEntry("tag_A", "asfd,3,4", "xxx", 7)), checkMD("1asdf #sourceValue2==", new MetadataEntry("tag_B", "arg1,arg2,arg3", "sourceValue2", 7)), checkMD("xxxasdf }xxx==", new MetadataEntry("tag_A", "asfd,3,4", "xxx", 9)), checkMD("xxxasdf #sourceValue2==", new MetadataEntry("tag_B", "arg1,arg2,arg3", "sourceValue2", 9)) ); testSourceProcessing("#", "foo1 ## #error_EXP(asdf,3,4){xxx}=="+ "asdf ## #error(info1)=="+ "#:SPLIT ____\n"+ "asdf ## #error=="+ "asdf ## #error{xxx}=="+ "#:SPLIT ____\n"+ "multilineMD #error(arg1,arg2,arg3):\n line1\nline2\nline3\n#:END:lineOther4\n", checkMD( "foo1 # xxx=="+ "asdf # ==", new MetadataEntry("error_EXP", "asdf,3,4", "xxx", 7), new MetadataEntry("error", "info1", null, 7 +5+7) ), checkMD( "asdf # =="+ "asdf # xxx==", new MetadataEntry("error", null, null, 7), new MetadataEntry("error", null, "xxx", 7 +2+7) ), checkMD( "multilineMD lineOther4\n", new MetadataEntry("error", "arg1,arg2,arg3", " line1\nline2\nline3\n", 12, false) ) ); // Unnamed definitions in header testSourceProcessing("#", "#:HEADER ____\n"+"> #@{A,B,C}", 2); } @Ignore @Test public void testExpansionPerformance() throws Exception { testExpansionPerformance$(); } public void testExpansionPerformance$() throws Exception { // Performance test: AnnotatedSource[] processTemplatedSource = TemplatedSourceProcessor.processTemplatedSource("#", ">#@N{X#tag(arg){xxx} #tag2(arg){xxx} #tag3(arg){xxx}}"+ " #@N2!{a#@N,b#@N,c#@N,d#@N,e#@N,f#@N),g#@N,h#@N,k#@N,l#@N}"+ " #@N3{#@N2,#@N2,#@N2,#@N2,#@N2,#@N2),#@N2,#@N2,#@N2,#@N2}"+ " #@N4{#@N2,#@N2,#@N2,#@N2,#@N2,#@N2),#@N2,#@N2,#@N2,#@N2}"+ " #@N5{#@N2,#@N2,#@N2,#@N2,#@N2,#@N2),#@N2,#@N2,#@N2,#@N2}"+ " #@N6{#@N2,#@N2,#@N2,#@N2,#@N2,#@N2),#@N2,#@N2,#@N2,#@N2}"+ " #@N7{#@N2,#@N2,#@N2,#@N2,#@N2,#@N2),#@N2,#@N2,#@N2,#@N2}"+ "=="); System.out.println(processTemplatedSource.length); } @Test public void test6b_ExpansionInMetadata() throws Exception { testExpansionInMetadata$(); } public void testExpansionInMetadata$() throws Exception { testSourceProcessing("#", "> #@EXPANSION1{var1,var2,var3xxx} #tag(arg1,arg2,arg3){mdsource:#@EXPANSION1}", checkMD("> var1 mdsource:var1", new MetadataEntry("tag", "arg1,arg2,arg3", "mdsource:var1", 7)), checkMD("> var2 mdsource:var2", new MetadataEntry("tag", "arg1,arg2,arg3", "mdsource:var2", 7)), checkMD("> var3xxx mdsource:var3xxx", new MetadataEntry("tag", "arg1,arg2,arg3", "mdsource:var3xxx", 10)) ); testSourceProcessing("#", "> #tag(arg1){mdsource: #@EXPANSION1{var1,var2,var3xxx} -- #@{A,B,C}(EXPANSION1)}", checkMD("> mdsource: var1 -- A", new MetadataEntry("tag", "arg1", "mdsource: var1 -- A", 2)), checkMD("> mdsource: var2 -- B", new MetadataEntry("tag", "arg1", "mdsource: var2 -- B", 2)), checkMD("> mdsource: var3xxx -- C", new MetadataEntry("tag", "arg1", "mdsource: var3xxx -- C", 2)) ); testSourceProcessing("#", "> #tag(arg){mdsource: #@EXPANSION1{var1,var2,var3xxx} -- #nestedMD{nestedMDsrc #@{A,B,C}(EXPANSION1)}}", checkMD("> mdsource: var1 -- nestedMDsrc A", new MetadataEntry("tag", "arg", "mdsource: var1 -- nestedMDsrc A", 2), new MetadataEntry("nestedMD", null, "nestedMDsrc A", 20)), checkMD("> mdsource: var2 -- nestedMDsrc B", new MetadataEntry("tag", "arg", "mdsource: var2 -- nestedMDsrc B", 2), new MetadataEntry("nestedMD", null, "nestedMDsrc B", 20)), checkMD("> mdsource: var3xxx -- nestedMDsrc C", new MetadataEntry("tag", "arg", "mdsource: var3xxx -- nestedMDsrc C", 2), new MetadataEntry("nestedMD", null, "nestedMDsrc C", 23)) ); MetadataEntry top; testSourceProcessing("#", "> #@EXP{AA,B,CCCC} #tag(arg):\ntagMD #nestedMD{xxx}", checkMD("> AA ", top = new MetadataEntry("tag", "arg", "tagMD xxx", 5, false), new MetadataEntry("nestedMD", null, "xxx", 6, top)) , checkMD("> B ", top = new MetadataEntry("tag", "arg", "tagMD xxx", 4, false), new MetadataEntry("nestedMD", null, "xxx", 6, top)) , checkMD("> CCCC ", top = new MetadataEntry("tag", "arg", "tagMD xxx", 7, false), new MetadataEntry("nestedMD", null, "xxx", 6, top) ) ); } /* ------------------------ CONDITIONAL EXPANSION ------------------------ */ @Test public void test9_IfElseExpansion() throws Exception { testIfElseExpansion$(); } public void testIfElseExpansion$() throws Exception { testSourceProcessing("#", "> #@{A,B#var(Bactive)} #?var{THEN}-#?var!{NOT_THEN}", checkMD("> A -NOT_THEN"), checkMD("> B THEN-", new MetadataEntry("var", "Bactive", null, 3)) ); testSourceProcessing("#", "> #@{A,B#var(Bactive)} #?var{THEN,ELSE}-#?var!{NOT_THEN,NOT_ELSE}", checkMD("> A ELSE-NOT_THEN"), checkMD("> B THEN-NOT_ELSE", new MetadataEntry("var", "Bactive", null, 3)) ); testSourceProcessing("#", "> #?{THEN,ELSE, INVALID}", 4); testSourceProcessing("#", "> #@{A ,B #var(Bactive) } #?var{THEN,ELSE, INVALID}", 51); testSourceProcessing("#", "#:HEADER ____\n"+"#@EXPANSION1{1#var1,2#var2,3#var3}"+ "#:SPLIT\n> #?var1{IF,ELSE} #@{A,B,C}(EXPANSION1) -- #@EXPANSION1 "+ "#?var1{THEN,ELSE}#?var2{var2}", checkMD("> ELSE A -- 1 THEN", new MetadataEntry("var1", null, null, 13)), checkMD("> ELSE B -- 2 ELSEvar2", new MetadataEntry("var2", null, null, 13)), checkMD("> ELSE C -- 3 ELSE", new MetadataEntry("var3", null, null, 13)) ); // Test conditional exp when conditional is inside referred MD testSourceProcessing("#", "#parentMD【> #@{A,B#var(Bactive)} #?var{IF} #?parentMD{parentMDActive}】", checkMD("> A parentMDActive", new MetadataEntry("parentMD", null, DONT_CHECK, 0) ), checkMD("> B IF parentMDActive", new MetadataEntry("parentMD", null, DONT_CHECK, 0), new MetadataEntry("var", "Bactive", null, 3) ) ); } }