Index: Externals/Eagle/lib/Eagle1.0/init.eagle ================================================================== --- Externals/Eagle/lib/Eagle1.0/init.eagle +++ Externals/Eagle/lib/Eagle1.0/init.eagle @@ -748,11 +748,12 @@ } # # NOTE: This proc can be used to dynamically compile C# code in a script. # - proc compileCSharp { string resultsVarName errorsVarName args } { + proc compileCSharp { + string memory symbols strict resultsVarName errorsVarName args } { # # NOTE: Create the C# code provider object (i.e. the compiler). # set provider [object create -alias Microsoft.CSharp.CSharpCodeProvider] @@ -762,14 +763,22 @@ # set parameters [object create -alias \ System.CodeDom.Compiler.CompilerParameters] # - # NOTE: By default, we do not want to persist the generated assembly - # to disk. + # NOTE: Do we not want to persist the generated assembly to disk? # - $parameters GenerateInMemory true + if {$memory} then { + $parameters GenerateInMemory true + } + + # + # NOTE: Do we want symbols to be generated for the generated assembly? + # + if {$symbols} then { + $parameters IncludeDebugInformation true + } # # NOTE: Make sure that the "standard" preprocessor defines match those # for the platform (i.e. the ones used to compile the Eagle core # library assembly). @@ -830,20 +839,16 @@ # # NOTE: Fetch the collection of compiler errors (which may be empty). # set errors [$results -alias Errors] - # - # NOTE: How many compile errors? - # - set count [$errors Count] - # # NOTE: It is assumed that no assembly was generated if there were - # any compile errors. + # any compiler errors. Ignore all compiler warnings unless + # we are in strict mode. # - if {$count > 0} then { + if {[$errors HasErrors] || ($strict && [$errors HasWarnings])} then { # # NOTE: Compilation of the assembly failed. # set code Error @@ -850,10 +855,19 @@ # # NOTE: Prepare to transfer the error messages to the caller. # upvar 1 $errorsVarName local_errors + # + # NOTE: How many compile errors? + # + set count [$errors Count] + + # + # NOTE: Grab each error object and append the string itself to + # the overall list of errors. + # for {set index 0} {$index < $count} {incr index} { # # NOTE: Get the compiler error object at this index. # set error [$errors -alias Item $index] Index: Externals/Eagle/lib/Eagle1.0/test.eagle ================================================================== --- Externals/Eagle/lib/Eagle1.0/test.eagle +++ Externals/Eagle/lib/Eagle1.0/test.eagle @@ -857,13 +857,13 @@ if {[isEagle]} then { host title "" } } - proc reportTestPercent { channel percent } { + proc reportTestPercent { channel percent failed leaked } { set status [appendArgs "---- test suite running, about " $percent \ - "% complete..."] + "% complete (" $failed " failed, " $leaked " leaked)..."] tputs $channel [appendArgs $status \n] if {[isEagle]} then { host title $status @@ -911,11 +911,13 @@ # set percent [formatDecimal \ [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]] if {$percent != $lastPercent} then { - reportTestPercent $channel $percent + reportTestPercent $channel $percent \ + [llength $failed] [llength $leaked] + set lastPercent $percent } # # NOTE: Skipping over any file name that matches a pattern in the @@ -1032,11 +1034,13 @@ # set percent [formatDecimal \ [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]] if {$percent != $lastPercent} then { - reportTestPercent $channel $percent + reportTestPercent $channel $percent \ + [llength $failed] [llength $leaked] + set lastPercent $percent } # # NOTE: Record failed test count after this file. @@ -1088,11 +1092,13 @@ # set percent [formatDecimal \ [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]] if {$percent != $lastPercent} then { - reportTestPercent $channel $percent + reportTestPercent $channel $percent \ + [llength $failed] [llength $leaked] + set lastPercent $percent } # # NOTE: If the test file raised an error (i.e. to indicate a @@ -1115,11 +1121,13 @@ # set percent [formatDecimal \ [expr {$total != 0 ? 100.0 * ($count / double($total)) : 100}]] if {$percent != $lastPercent} then { - reportTestPercent $channel $percent + reportTestPercent $channel $percent \ + [llength $failed] [llength $leaked] + set lastPercent $percent } } # Index: Externals/Eagle/lib/Test1.0/constraints.eagle ================================================================== --- Externals/Eagle/lib/Test1.0/constraints.eagle +++ Externals/Eagle/lib/Test1.0/constraints.eagle @@ -801,10 +801,30 @@ tputs $channel [appendArgs "yes (" $threadId ")\n"] } else { tputs $channel [appendArgs "no (" $threadId ")\n"] } } + + proc checkForDefaultAppDomain { channel } { + tputs $channel "---- checking for default application domain... " + + set appDomain [object invoke AppDomain CurrentDomain] + + if {[string length $appDomain] > 0} then { + if {[object invoke $appDomain IsDefaultAppDomain]} then { + addConstraint defaultAppDomain + + tputs $channel [appendArgs "yes (" [object invoke $appDomain Id] \ + ")\n"] + } else { + tputs $channel [appendArgs "no (" [object invoke $appDomain Id] \ + ")\n"] + } + } else { + tputs $channel [appendArgs "no (null)\n"] + } + } proc checkForRuntime { channel } { tputs $channel "---- checking for runtime... " # @@ -1061,13 +1081,15 @@ tputs $channel "---- checking for thread culture... " # # NOTE: Grab the current thread culture. # + set culture [object invoke System.Threading.Thread.CurrentThread \ + CurrentCulture] + set culture [object invoke Eagle._Components.Private.FormatOps \ - CultureName [object invoke System.Threading.Thread.CurrentThread \ - CurrentCulture] false] + CultureName $culture false] if {[string length $culture] > 0} then { # # NOTE: The culture information is present, use it and show it. # Index: Externals/Eagle/lib/Test1.0/prologue.eagle ================================================================== --- Externals/Eagle/lib/Test1.0/prologue.eagle +++ Externals/Eagle/lib/Test1.0/prologue.eagle @@ -552,10 +552,20 @@ # if {![info exists no(primaryThread)]} then { checkForPrimaryThread $test_channel } + # + # NOTE: Has default application domain detection support been + # disabled? We do this check [nearly] first as it may + # [eventually] be used to help determine if other + # constraints should be skipped. + # + if {![info exists no(defaultAppDomain)]} then { + checkForDefaultAppDomain $test_channel + } + # # NOTE: Has runtime detection support been disabled? We do this # checking [nearly] first as it may skip other constraints. # if {![info exists no(runtime)]} then { @@ -1031,10 +1041,64 @@ # checkForObjectMember $test_channel Eagle._Tests.Default+Disposable \ *ToString* Eagle._Tests.Default.Disposable.ToString } + # + # NOTE: Has linked variable testing support been disabled? + # + if {![info exists no(testLinkedVariables)]} then { + # + # NOTE: For tests "basic-1.39", "basic-1.40", "basic-1.41", + # "basic-1.42", and "basic-1.43". + # + checkForObjectMember $test_channel Eagle._Tests.Default \ + *TestSetVariableLinks* + + checkForObjectMember $test_channel Eagle._Tests.Default \ + *TestUnsetVariableLinks* + } + + # + # NOTE: Has field testing support been disabled? + # + if {![info exists no(testFields)]} then { + # + # NOTE: For tests "basic-1.39", "basic-1.40", "basic-1.41", + # "basic-1.42", and "basic-1.43". + # + checkForObjectMember $test_channel Eagle._Tests.Default \ + *privateField* + + checkForObjectMember $test_channel Eagle._Tests.Default \ + *objectField* + + checkForObjectMember $test_channel Eagle._Tests.Default \ + *intField* + } + + # + # NOTE: Has property testing support been disabled? + # + if {![info exists no(testProperties)]} then { + # + # NOTE: For tests "basic-1.39", "basic-1.40", "basic-1.41", + # "basic-1.42", and "basic-1.43". + # + checkForObjectMember $test_channel Eagle._Tests.Default \ + *get_SimpleProperty* + + # + # NOTE: For test "object-3.1". + # + checkForObjectMember $test_channel Eagle._Tests.Default \ + *get_Item* + + checkForObjectMember $test_channel Eagle._Tests.Default \ + *set_Item* + } + # # NOTE: Has core marshaller testing support been disabled? # if {![info exists no(testMarshaller)]} then { # @@ -1068,19 +1132,10 @@ *TestMulti3Array* checkForObjectMember $test_channel Eagle._Tests.Default \ *TestNestedArray* - # - # NOTE: For test "object-3.1". - # - checkForObjectMember $test_channel Eagle._Tests.Default \ - *get_Item* - - checkForObjectMember $test_channel Eagle._Tests.Default \ - *set_Item* - # # NOTE: For tests "object-3.6" and "object-3.7". # checkForObjectMember $test_channel Eagle._Tests.Default \ *TestStringIListReturnValue* @@ -1355,177 +1410,183 @@ } } } # - # NOTE: For test "package-1.0". - # - if {![info exists no(pkgAll.tcl)]} then { - checkForFile $test_channel [file join $base_path Package Tests all.tcl] \ - pkgAll.tcl - } - - # - # NOTE: For tests "subst-1.*". - # - if {![info exists no(bad_subst.txt)]} then { - checkForFile $test_channel [file join $test_path bad_subst.txt] - } - - # - # NOTE: For tests "fileIO-1.*". - # - if {![info exists no(file.dat)]} then { - checkForFile $test_channel [file join $test_path file.dat] - } - - # - # NOTE: For test "garbage-1.1". - # - if {![info exists no(garbage.txt)]} then { - checkForFile $test_channel [file join $test_path garbage.txt] - } - - # - # NOTE: For tests "xaml-1.*". - # - if {![info exists no(test.png)]} then { - checkForFile $test_channel [file join $test_path test.png] - } - - # - # NOTE: For test "socket-1.2". - # - if {![info exists no(client.tcl)]} then { - checkForFile $test_channel [file join $test_path client.tcl] - } - - # - # NOTE: For test "tclLoad-1.2". - # - if {![info exists no(tcl_unload.tcl)]} then { - checkForFile $test_channel [file join $test_path tcl_unload.tcl] - } - - # - # NOTE: For test "basic-1.4". - # - if {![info exists no(read.eagle)]} then { - checkForFile $test_channel [file join $test_path read.eagle] - } - - # - # NOTE: For test "basic-1.5". - # - if {![info exists no(read2.eagle)]} then { - checkForFile $test_channel [file join $test_path read2.eagle] - } - - # - # NOTE: For test "basic-1.6". - # - if {![info exists no(read3.eagle)]} then { - checkForFile $test_channel [file join $test_path read3.eagle] - } - - # - # NOTE: For test "basic-1.7". - # - if {![info exists no(read4.eagle)]} then { - checkForFile $test_channel [file join $test_path read4.eagle] - } - - # - # NOTE: For test "infoScript-1.1". - # - if {![info exists no(script.eagle)]} then { - checkForFile $test_channel [file join $test_path script.eagle] - } - - # - # NOTE: For test "basic-1.1". - # - if {![info exists no(source.eagle)]} then { - checkForFile $test_channel [file join $test_path source.eagle] - } - - # - # NOTE: For test "basic-1.2". - # - if {![info exists no(unbalanced_brace.eagle)]} then { - checkForFile $test_channel [file join $test_path unbalanced_brace.eagle] - } - - # - # NOTE: For test "basic-1.3". - # - if {![info exists no(unbalanced_brace2.eagle)]} then { - checkForFile $test_channel [file join $test_path unbalanced_brace2.eagle] - } - - # - # NOTE: For tests "excel-2.*". - # - if {![info exists no(test.xls)]} then { - checkForFile $test_channel [file join $test_path test.xls] - } - - # - # NOTE: For test "interp-1.10". - # - if {![info exists no(settings.xml)]} then { - checkForFile $test_channel [file join $test_path settings.xml] - } - - # - # NOTE: For tests "load-1.1.*". - # - if {![info exists no(Plugin.dll)]} then { - checkForFile $test_channel [file join $lib_path Plugin1.0 Plugin.dll] - } - - # - # NOTE: For test "object-6.1". - # - if {![info exists no(Sample.exe)]} then { - checkForFile $test_channel [file join $bin_path Sample.exe] - } - - # - # NOTE: For test "object-4.8". - # - if {![info exists no(EagleCmdlets.dll)]} then { - checkForFile $test_channel [file join $bin_path EagleCmdlets.dll] - } - - # - # NOTE: For test "object-4.10". - # - if {![info exists no(EagleExtensions.dll)]} then { - checkForFile $test_channel [file join $bin_path EagleExtensions.dll] - } - - # - # NOTE: For test "object-4.10". - # - if {![info exists no(test.wxs)]} then { - checkForFile $test_channel [file join $base_path Installer Tests test.wxs] - } - - # - # NOTE: For test "sql-1.2". - # - if {![info exists no(sqlite3.dll)]} then { - checkForFile $test_channel [file join $bin_path sqlite3.dll] - } - - if {![info exists no(System.Data.SQLite.dll)]} then { - checkForFile $test_channel [file join $bin_path System.Data.SQLite.dll] - } - - if {![info exists no(test.sqlite3)]} then { - checkForFile $test_channel [file join $test_path test.sqlite3] + # NOTE: Has checking for the extra files needed by various tests been + # disabled? + # + if {![info exists no(checkForFile)]} then { + # + # NOTE: For test "package-1.0". + # + if {![info exists no(pkgAll.tcl)]} then { + checkForFile $test_channel [file join $base_path Package Tests all.tcl] \ + pkgAll.tcl + } + + # + # NOTE: For tests "subst-1.*". + # + if {![info exists no(bad_subst.txt)]} then { + checkForFile $test_channel [file join $test_path bad_subst.txt] + } + + # + # NOTE: For tests "fileIO-1.*". + # + if {![info exists no(file.dat)]} then { + checkForFile $test_channel [file join $test_path file.dat] + } + + # + # NOTE: For test "garbage-1.1". + # + if {![info exists no(garbage.txt)]} then { + checkForFile $test_channel [file join $test_path garbage.txt] + } + + # + # NOTE: For tests "xaml-1.*". + # + if {![info exists no(test.png)]} then { + checkForFile $test_channel [file join $test_path test.png] + } + + # + # NOTE: For test "socket-1.2". + # + if {![info exists no(client.tcl)]} then { + checkForFile $test_channel [file join $test_path client.tcl] + } + + # + # NOTE: For test "tclLoad-1.2". + # + if {![info exists no(tcl_unload.tcl)]} then { + checkForFile $test_channel [file join $test_path tcl_unload.tcl] + } + + # + # NOTE: For test "basic-1.4". + # + if {![info exists no(read.eagle)]} then { + checkForFile $test_channel [file join $test_path read.eagle] + } + + # + # NOTE: For test "basic-1.5". + # + if {![info exists no(read2.eagle)]} then { + checkForFile $test_channel [file join $test_path read2.eagle] + } + + # + # NOTE: For test "basic-1.6". + # + if {![info exists no(read3.eagle)]} then { + checkForFile $test_channel [file join $test_path read3.eagle] + } + + # + # NOTE: For test "basic-1.7". + # + if {![info exists no(read4.eagle)]} then { + checkForFile $test_channel [file join $test_path read4.eagle] + } + + # + # NOTE: For test "infoScript-1.1". + # + if {![info exists no(script.eagle)]} then { + checkForFile $test_channel [file join $test_path script.eagle] + } + + # + # NOTE: For test "basic-1.1". + # + if {![info exists no(source.eagle)]} then { + checkForFile $test_channel [file join $test_path source.eagle] + } + + # + # NOTE: For test "basic-1.2". + # + if {![info exists no(unbalanced_brace.eagle)]} then { + checkForFile $test_channel [file join $test_path unbalanced_brace.eagle] + } + + # + # NOTE: For test "basic-1.3". + # + if {![info exists no(unbalanced_brace2.eagle)]} then { + checkForFile $test_channel [file join $test_path unbalanced_brace2.eagle] + } + + # + # NOTE: For tests "excel-2.*". + # + if {![info exists no(test.xls)]} then { + checkForFile $test_channel [file join $test_path test.xls] + } + + # + # NOTE: For test "interp-1.10". + # + if {![info exists no(settings.xml)]} then { + checkForFile $test_channel [file join $test_path settings.xml] + } + + # + # NOTE: For tests "load-1.1.*". + # + if {![info exists no(Plugin.dll)]} then { + checkForFile $test_channel [file join $lib_path Plugin1.0 Plugin.dll] + } + + # + # NOTE: For test "object-6.1". + # + if {![info exists no(Sample.exe)]} then { + checkForFile $test_channel [file join $bin_path Sample.exe] + } + + # + # NOTE: For test "object-4.8". + # + if {![info exists no(EagleCmdlets.dll)]} then { + checkForFile $test_channel [file join $bin_path EagleCmdlets.dll] + } + + # + # NOTE: For test "object-4.10". + # + if {![info exists no(EagleExtensions.dll)]} then { + checkForFile $test_channel [file join $bin_path EagleExtensions.dll] + } + + # + # NOTE: For test "object-4.10". + # + if {![info exists no(test.wxs)]} then { + checkForFile $test_channel [file join $base_path Installer Tests test.wxs] + } + + # + # NOTE: For test "sql-1.2". + # + if {![info exists no(sqlite3.dll)]} then { + checkForFile $test_channel [file join $bin_path sqlite3.dll] + } + + if {![info exists no(System.Data.SQLite.dll)]} then { + checkForFile $test_channel [file join $bin_path System.Data.SQLite.dll] + } + + if {![info exists no(test.sqlite3)]} then { + checkForFile $test_channel [file join $test_path test.sqlite3] + } } # # NOTE: Check the core test constraints unless they have been # explicitly disabled. Index: Tests/basic.eagle ================================================================== --- Tests/basic.eagle +++ Tests/basic.eagle @@ -182,11 +182,11 @@ { // do nothing. } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} GetReservedWords @@ -242,11 +242,11 @@ { // do nothing. } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { set rows [list] @@ -338,11 +338,11 @@ { // do nothing. } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { set savedCount -1; set savedInterval -1 @@ -424,11 +424,11 @@ } } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main @@ -485,11 +485,11 @@ } } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main @@ -547,11 +547,11 @@ } } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main @@ -871,11 +871,11 @@ { // do nothing. } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} GetConnectionString \ @@ -946,11 +946,11 @@ { // do nothing. } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] lappend results $code [expr {[info exists errors] ? $errors : ""}] if {$code eq "Ok"} then { set keys [list null Version Synchronous UseUTF16Encoding Pooling \ Index: Tests/common.eagle ================================================================== --- Tests/common.eagle +++ Tests/common.eagle @@ -382,18 +382,19 @@ return $result } proc compileCSharpWith { - text resultsVarName errorsVarName fileNames args } { + text memory symbols strict resultsVarName errorsVarName fileNames + args } { # # NOTE: Create the base command to evaluate and add the property settings # that are almost always needed by our unit tests (i.e. the System # and System.Data assembly references). # - set command [list compileCSharp $text results errors \ - ReferencedAssemblies.Add System.dll ReferencedAssemblies.Add \ + set command [list compileCSharp $text $memory $symbols $strict results \ + errors ReferencedAssemblies.Add System.dll ReferencedAssemblies.Add \ System.Data.dll ReferencedAssemblies.Add System.Xml.dll] # # NOTE: Add all the provided file names as assembly references. # Index: Tests/tkt-201128cc88.eagle ================================================================== --- Tests/tkt-201128cc88.eagle +++ Tests/tkt-201128cc88.eagle @@ -66,11 +66,11 @@ { SQLiteFunction.RegisterFunction(typeof(Test${id})); } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] # # NOTE: Compile the C# code (above) to register the custom SQLite function # and then open the database for this test case and attempt to execute # the function. Normally, we would open the database in the test setup Index: Tests/tkt-343d392b51.eagle ================================================================== --- Tests/tkt-343d392b51.eagle +++ Tests/tkt-343d392b51.eagle @@ -171,11 +171,11 @@ } } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main @@ -277,11 +277,11 @@ } } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main @@ -415,11 +415,11 @@ } } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main Index: Tests/tkt-7e3fa93744.eagle ================================================================== --- Tests/tkt-7e3fa93744.eagle +++ Tests/tkt-7e3fa93744.eagle @@ -115,11 +115,11 @@ } } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main Index: Tests/tkt-e1b2e0f769.eagle ================================================================== --- Tests/tkt-e1b2e0f769.eagle +++ Tests/tkt-e1b2e0f769.eagle @@ -101,11 +101,11 @@ return Tkt_e1b2e0f769(connection).Count; } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] lappend result1 $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main Index: Tests/tkt-e30b820248.eagle ================================================================== --- Tests/tkt-e30b820248.eagle +++ Tests/tkt-e30b820248.eagle @@ -94,11 +94,11 @@ Trace.Listeners.Remove(listener); } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main @@ -241,11 +241,11 @@ Trace.Listeners.Remove(listener); } } } } - }] results errors System.Data.SQLite.dll] + }] true true true results errors System.Data.SQLite.dll] list $code $results \ [expr {[info exists errors] ? $errors : ""}] \ [expr {$code eq "Ok" ? [catch { object invoke _Dynamic${id}.Test${id} Main