PageRenderTime 51ms CodeModel.GetById 8ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 1ms

/IronPython_2_0/Src/IronPythonTest/EngineTest.cs

#
C# | 1013 lines | 725 code | 197 blank | 91 comment | 29 complexity | 9a69c6c2bb11f6762f72319e8c2c63b9 MD5 | raw file
   1/* ****************************************************************************
   2 *
   3 * Copyright (c) Microsoft Corporation. 
   4 *
   5 * This source code is subject to terms and conditions of the Microsoft Public License. A 
   6 * copy of the license can be found in the License.html file at the root of this distribution. If 
   7 * you cannot locate the  Microsoft Public License, please send an email to 
   8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
   9 * by the terms of the Microsoft Public License.
  10 *
  11 * You must not remove this notice, or any other, from this software.
  12 *
  13 *
  14 * ***************************************************************************/
  15
  16using System; using Microsoft;
  17using System.Collections;
  18using System.Collections.Generic;
  19using System.Diagnostics;
  20using System.IO;
  21using System.Security;
  22using System.Security.Policy;
  23using System.Text;
  24
  25using Microsoft.Scripting;
  26using Microsoft.Scripting.Hosting;
  27using Microsoft.Scripting.Runtime;
  28
  29using IronPython;
  30using IronPython.Hosting;
  31using IronPython.Runtime;
  32using IronPython.Runtime.Exceptions;
  33
  34namespace IronPythonTest {
  35#if !SILVERLIGHT
  36    class Common {
  37        public static string RootDirectory;
  38        public static string RuntimeDirectory;
  39        public static string ScriptTestDirectory;
  40        public static string InputTestDirectory;
  41
  42        static Common() {
  43            RuntimeDirectory = Path.GetDirectoryName(typeof(PythonContext).Assembly.Location);
  44            RootDirectory = Environment.GetEnvironmentVariable("MERLIN_ROOT");
  45            if (RootDirectory != null) {
  46                ScriptTestDirectory = Path.Combine(RootDirectory, "Languages\\IronPython\\Tests");
  47            } else {
  48                RootDirectory = new System.IO.FileInfo(System.Reflection.Assembly.GetEntryAssembly().GetFiles()[0].Name).Directory.FullName;
  49                ScriptTestDirectory = Path.Combine(RootDirectory, "Src\\Tests");
  50            }
  51            InputTestDirectory = Path.Combine(ScriptTestDirectory, "Inputs");
  52        }
  53    }
  54#endif
  55
  56    public static class TestHelpers {
  57        public static LanguageContext GetContext(CodeContext context) {
  58            return context.LanguageContext;
  59        }
  60    }
  61
  62    public delegate int IntIntDelegate(int arg);
  63    public delegate string RefStrDelegate(ref string arg);
  64    public delegate int RefIntDelegate(ref int arg);
  65    public delegate T GenericDelegate<T, U, V>(U arg1, V arg2);
  66
  67    public class ClsPart {
  68        public int Field;
  69        int m_property;
  70        public int Property { get { return m_property; } set { m_property = value; } }
  71        public event IntIntDelegate Event;
  72        public int Method(int arg) {
  73            if (Event != null)
  74                return Event(arg);
  75            else
  76                return -1;
  77        }
  78
  79        // Private members
  80#pragma warning disable 169
  81        // This field is accessed from the test
  82        private int privateField;
  83        private int privateProperty { get { return m_property; } set { m_property = value; } }
  84        private event IntIntDelegate privateEvent;
  85        private int privateMethod(int arg) {
  86            if (privateEvent != null)
  87                return privateEvent(arg);
  88            else
  89                return -1;
  90        }
  91        private static int privateStaticMethod() {
  92            return 100;
  93        }
  94#pragma warning restore 169
  95    }
  96
  97    internal class InternalClsPart {
  98#pragma warning disable 649
  99        // This field is accessed from the test
 100        internal int Field;
 101#pragma warning restore 649
 102        int m_property;
 103        internal int Property { get { return m_property; } set { m_property = value; } }
 104        internal event IntIntDelegate Event;
 105        internal int Method(int arg) {
 106            if (Event != null)
 107                return Event(arg);
 108            else
 109                return -1;
 110        }
 111    }
 112
 113    public class EngineTest
 114#if !SILVERLIGHT // remoting not supported in Silverlight
 115        : MarshalByRefObject
 116#endif
 117    {
 118
 119        private readonly ScriptEngine _pe;
 120        private readonly ScriptRuntime _env;
 121
 122        public EngineTest() {
 123            // Load a script with all the utility functions that are required
 124            // pe.ExecuteFile(InputTestDirectory + "\\EngineTests.py");
 125            _env = Python.CreateRuntime();
 126            _env.LoadAssembly(typeof(string).Assembly);
 127            _env.LoadAssembly(typeof(Debug).Assembly);
 128            _pe = _env.GetEngine("py");
 129        }
 130
 131        // Used to test exception thrown in another domain can be shown correctly.
 132        public void Run(string script) {
 133            ScriptScope scope = _env.CreateScope();
 134            _pe.CreateScriptSourceFromString(script, SourceCodeKind.File).Execute(scope);
 135        }
 136
 137        static readonly string clspartName = "clsPart";
 138        
 139        /// <summary>
 140        /// Asserts an condition it true
 141        /// </summary>
 142        private static void Assert(bool condition, string msg) {
 143            if (!condition) throw new Exception(String.Format("Assertion failed: {0}", msg));
 144        }
 145
 146        private static void Assert(bool condition) {
 147            if (!condition) throw new Exception("Assertion failed");
 148        }
 149
 150        private static T AssertExceptionThrown<T>(Action f) where T : Exception {
 151            try {
 152                f();
 153            } catch (T ex) {
 154                return ex;
 155            }
 156
 157            Assert(false, "Expecting exception '" + typeof(T) + "'.");
 158            return null;
 159        }
 160
 161#if !SILVERLIGHT
 162        public void ScenarioHostingHelpers() {
 163            AppDomain remote = AppDomain.CreateDomain("foo");
 164            Dictionary<string, object> options = new Dictionary<string,object>();
 165            // DLR ScriptRuntime options
 166            options["Debug"] = true;
 167            options["PrivateBinding"] = true;
 168            
 169            // python options
 170            options["StripDocStrings"] = true;
 171            options["Optimize"] = true;
 172            options["DivisionOptions"] = PythonDivisionOptions.New;
 173            options["RecursionLimit"] = 42;
 174            options["IndentationInconsistencySeverity"] = Severity.Warning;
 175            options["WarningFilters"] = new string[] { "warnonme" };
 176
 177            ScriptEngine engine1 = Python.CreateEngine();
 178            ScriptEngine engine2 = Python.CreateEngine(AppDomain.CurrentDomain);
 179            ScriptEngine engine3 = Python.CreateEngine(remote);
 180
 181            TestEngines(null, new ScriptEngine[] { engine1, engine2, engine3 });
 182
 183            ScriptEngine engine4 = Python.CreateEngine(options);
 184            ScriptEngine engine5 = Python.CreateEngine(AppDomain.CurrentDomain, options);
 185            ScriptEngine engine6 = Python.CreateEngine(remote, options);
 186
 187            TestEngines(options, new ScriptEngine[] { engine4, engine5, engine6 });
 188
 189            ScriptRuntime runtime1 = Python.CreateRuntime();
 190            ScriptRuntime runtime2 = Python.CreateRuntime(AppDomain.CurrentDomain);
 191            ScriptRuntime runtime3 = Python.CreateRuntime(remote);
 192
 193            TestRuntimes(null, new ScriptRuntime[] { runtime1, runtime2, runtime3 });
 194
 195            ScriptRuntime runtime4 = Python.CreateRuntime(options);
 196            ScriptRuntime runtime5 = Python.CreateRuntime(AppDomain.CurrentDomain, options);
 197            ScriptRuntime runtime6 = Python.CreateRuntime(remote, options);
 198
 199            TestRuntimes(options, new ScriptRuntime[] { runtime4, runtime5, runtime6 });
 200        }
 201
 202        private void TestEngines(Dictionary<string, object> options, ScriptEngine[] engines) {
 203            foreach (ScriptEngine engine in engines) {
 204                TestEngine(engine, options);
 205                TestRuntime(engine.Runtime, options);
 206            }
 207        }
 208
 209        private void TestRuntimes(Dictionary<string, object> options, ScriptRuntime[] runtimes) {
 210            foreach (ScriptRuntime runtime in runtimes) {
 211                TestRuntime(runtime, options);
 212
 213                TestEngine(Python.GetEngine(runtime), options);
 214            }
 215        }
 216
 217        private void TestEngine(ScriptEngine scriptEngine, Dictionary<string, object> options) {
 218            // basic smoke tests that the engine is alive and working
 219            AreEqual((int)scriptEngine.CreateScriptSourceFromString("42").Execute(scriptEngine.CreateScope()), 42);
 220
 221            if(options != null) {
 222                PythonOptions po = (PythonOptions)Microsoft.Scripting.Hosting.Providers.HostingHelpers.CallEngine<object, LanguageOptions>(
 223                    scriptEngine, 
 224                    (lc, obj) => lc.Options,
 225                    null
 226                );
 227
 228                AreEqual(po.StripDocStrings, true);
 229                AreEqual(po.Optimize, true);
 230                AreEqual(po.DivisionOptions, PythonDivisionOptions.New);
 231                AreEqual(po.RecursionLimit, 42);
 232                AreEqual(po.IndentationInconsistencySeverity, Severity.Warning);
 233                AreEqual(po.WarningFilters[0], "warnonme");
 234            }
 235
 236            AreEqual(Python.GetSysModule(scriptEngine).GetVariable<string>("platform"), "cli");
 237            AreEqual(Python.GetBuiltinModule(scriptEngine).GetVariable<bool>("True"), true);
 238            AreEqual(Python.ImportModule(scriptEngine, "nt").GetVariable<int>("F_OK"), 0);
 239            try {
 240                Python.ImportModule(scriptEngine, "non_existant_module");
 241                Assert(false);
 242            } catch (ImportException) {
 243            }
 244        }
 245
 246        private void TestRuntime(ScriptRuntime runtime, Dictionary<string, object> options) {
 247            // basic smoke tests that the runtime is alive and working
 248            runtime.Globals.SetVariable("hello", 42);
 249            Assert(runtime.GetEngine("py") != null);
 250
 251            if (options != null) {
 252                AreEqual(runtime.Setup.DebugMode, true);
 253                AreEqual(runtime.Setup.PrivateBinding, true);
 254            }
 255
 256            AreEqual(Python.GetSysModule(runtime).GetVariable<string>("platform"), "cli");
 257            AreEqual(Python.GetBuiltinModule(runtime).GetVariable<bool>("True"), true);
 258            AreEqual(Python.ImportModule(runtime, "nt").GetVariable<int>("F_OK"), 0);
 259            try {
 260                Python.ImportModule(runtime, "non_existant_module");
 261                Assert(false);
 262            } catch (ImportException) {
 263            }
 264        }
 265#endif
 266
 267        // Execute
 268        public void ScenarioExecute() {
 269            ClsPart clsPart = new ClsPart();
 270
 271            ScriptScope scope = _env.CreateScope();
 272
 273            scope.SetVariable(clspartName, clsPart);
 274
 275            // field: assign and get back
 276            _pe.CreateScriptSourceFromString("clsPart.Field = 100", SourceCodeKind.Statements).Execute(scope);
 277            _pe.CreateScriptSourceFromString("if 100 != clsPart.Field: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
 278            AreEqual(100, clsPart.Field);
 279
 280            // property: assign and get back
 281            _pe.CreateScriptSourceFromString("clsPart.Property = clsPart.Field", SourceCodeKind.Statements).Execute(scope);
 282            _pe.CreateScriptSourceFromString("if 100 != clsPart.Property: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
 283            AreEqual(100, clsPart.Property);
 284
 285            // method: Event not set yet
 286            _pe.CreateScriptSourceFromString("a = clsPart.Method(2)", SourceCodeKind.Statements).Execute(scope);
 287            _pe.CreateScriptSourceFromString("if -1 != a: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
 288
 289            // method: add python func as event handler
 290            _pe.CreateScriptSourceFromString("def f(x) : return x * x", SourceCodeKind.Statements).Execute(scope);
 291            _pe.CreateScriptSourceFromString("clsPart.Event += f", SourceCodeKind.Statements).Execute(scope);
 292            _pe.CreateScriptSourceFromString("a = clsPart.Method(2)", SourceCodeKind.Statements).Execute(scope);
 293            _pe.CreateScriptSourceFromString("if 4 != a: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
 294
 295            // ===============================================
 296
 297            // reset the same variable with instance of the same type
 298            scope.SetVariable(clspartName, new ClsPart());
 299            _pe.CreateScriptSourceFromString("if 0 != clsPart.Field: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
 300
 301            // add cls method as event handler
 302            scope.SetVariable("clsMethod", new IntIntDelegate(Negate));
 303            _pe.CreateScriptSourceFromString("clsPart.Event += clsMethod", SourceCodeKind.Statements).Execute(scope);
 304            _pe.CreateScriptSourceFromString("a = clsPart.Method(2)", SourceCodeKind.Statements).Execute(scope);
 305            _pe.CreateScriptSourceFromString("if -2 != a: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
 306
 307            // ===============================================
 308
 309            // reset the same variable with integer
 310            scope.SetVariable(clspartName, 1);
 311            _pe.CreateScriptSourceFromString("if 1 != clsPart: raise AssertionError('test failed')", SourceCodeKind.Statements).Execute(scope);
 312            AreEqual((int)scope.GetVariable(clspartName), 1);
 313
 314            ScriptSource su = _pe.CreateScriptSourceFromString("");
 315            AssertExceptionThrown<ArgumentNullException>(delegate() {
 316                su.Execute(null);
 317            });
 318        }
 319
 320        public void ScenarioEvaluateInAnonymousEngineModule() {
 321            ScriptScope scope1 = _env.CreateScope();
 322            ScriptScope scope2 = _env.CreateScope();
 323            ScriptScope scope3 = _env.CreateScope();
 324
 325            _pe.CreateScriptSourceFromString("x = 0", SourceCodeKind.Statements).Execute(scope1);
 326            _pe.CreateScriptSourceFromString("x = 1", SourceCodeKind.Statements).Execute(scope2);
 327
 328            scope3.SetVariable("x", 2);
 329
 330            AreEqual(0, _pe.CreateScriptSourceFromString("x").Execute<int>(scope1));
 331            AreEqual(0, (int)scope1.GetVariable("x"));
 332
 333            AreEqual(1, _pe.CreateScriptSourceFromString("x").Execute<int>(scope2));
 334            AreEqual(1, (int)scope2.GetVariable("x"));
 335
 336            AreEqual(2, _pe.CreateScriptSourceFromString("x").Execute<int>(scope3));
 337            AreEqual(2, (int)scope3.GetVariable("x"));
 338        }
 339
 340        public void ScenarioCP712() {
 341            ScriptScope scope1 = _env.CreateScope();
 342            _pe.CreateScriptSourceFromString("max(3, 4)", SourceCodeKind.InteractiveCode).Execute(scope1);
 343            //CompiledCode compiledCode = _pe.CreateScriptSourceFromString("max(3,4)", SourceCodeKind.InteractiveCode).Compile();
 344            //compiledCode.Execute(scope1);
 345            //AreEqual(4, scope1.GetVariable<int>("__builtins__._"));
 346            //TODO - this currently fails.
 347            //AreEqual(4, scope1.GetVariable<int>("_"));
 348        }
 349
 350        public void ScenarioEvaluateInPublishedEngineModule() {
 351            PythonContext pc = DefaultContext.DefaultPythonContext;
 352
 353            PythonModule publishedModule = pc.CreateModule();
 354            PythonModule otherModule = pc.CreateModule();
 355            pc.PublishModule("published_context_test", publishedModule);
 356
 357            pc.CreateSnippet("x = 0", SourceCodeKind.Statements).Execute(otherModule.Scope);
 358            pc.CreateSnippet("x = 1", SourceCodeKind.Statements).Execute(publishedModule.Scope);
 359
 360            object x;
 361
 362            // Ensure that the default EngineModule is not affected
 363            x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope);
 364            AreEqual(0, (int)x);
 365            // Ensure that the published context has been updated as expected
 366            x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(publishedModule.Scope);
 367            AreEqual(1, (int)x);
 368
 369            // Ensure that the published context is accessible from other contexts using sys.modules
 370            // TODO: do better:
 371            // pe.Import("sys", ScriptDomainManager.CurrentManager.DefaultModule);
 372            pc.CreateSnippet("from published_context_test import x", SourceCodeKind.Statements).Execute(otherModule.Scope);
 373            x = pc.CreateSnippet("x", SourceCodeKind.Expression).Execute(otherModule.Scope);
 374            AreEqual(1, (int)x);
 375        }
 376
 377
 378        class CustomDictionary : IDictionary<string, object> {
 379            // Make "customSymbol" always be accessible. This could have been accomplished just by
 380            // doing SetGlobal. However, this mechanism could be used for other extensibility
 381            // purposes like getting a callback whenever the symbol is read
 382            internal static readonly string customSymbol = "customSymbol";
 383            internal const int customSymbolValue = 100;
 384
 385            Dictionary<string, object> dict = new Dictionary<string, object>();
 386
 387            #region IDictionary<string,object> Members
 388
 389            public void Add(string key, object value) {
 390                if (key.Equals(customSymbol))
 391                    throw new UnboundNameException("Cannot assign to customSymbol");
 392                dict.Add(key, value);
 393            }
 394
 395            public bool ContainsKey(string key) {
 396                if (key.Equals(customSymbol))
 397                    return true;
 398                return dict.ContainsKey(key);
 399            }
 400
 401            public ICollection<string> Keys {
 402                get { throw new NotImplementedException("The method or operation is not implemented."); }
 403            }
 404
 405            public bool Remove(string key) {
 406                if (key.Equals(customSymbol))
 407                    throw new UnboundNameException("Cannot delete customSymbol");
 408                return dict.Remove(key);
 409            }
 410
 411            public bool TryGetValue(string key, out object value) {
 412                if (key.Equals(customSymbol)) {
 413                    value = customSymbolValue;
 414                    return true;
 415                }
 416
 417                return dict.TryGetValue(key, out value);
 418            }
 419
 420            public ICollection<object> Values {
 421                get { throw new NotImplementedException("The method or operation is not implemented."); }
 422            }
 423
 424            public object this[string key] {
 425                get {
 426                    if (key.Equals(customSymbol))
 427                        return customSymbolValue;
 428                    return dict[key];
 429                }
 430                set {
 431                    if (key.Equals(customSymbol))
 432                        throw new UnboundNameException("Cannot assign to customSymbol");
 433                    dict[key] = value;
 434                }
 435            }
 436
 437            #endregion
 438
 439            #region ICollection<KeyValuePair<string,object>> Members
 440
 441            public void Add(KeyValuePair<string, object> item) {
 442                throw new NotImplementedException("The method or operation is not implemented.");
 443            }
 444
 445            public void Clear() {
 446                throw new NotImplementedException("The method or operation is not implemented.");
 447            }
 448
 449            public bool Contains(KeyValuePair<string, object> item) {
 450                throw new NotImplementedException("The method or operation is not implemented.");
 451            }
 452
 453            public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) {
 454                throw new NotImplementedException("The method or operation is not implemented.");
 455            }
 456
 457            public int Count {
 458                get { throw new NotImplementedException("The method or operation is not implemented."); }
 459            }
 460
 461            public bool IsReadOnly {
 462                get { throw new NotImplementedException("The method or operation is not implemented."); }
 463            }
 464
 465            public bool Remove(KeyValuePair<string, object> item) {
 466                throw new NotImplementedException("The method or operation is not implemented.");
 467            }
 468
 469            #endregion
 470
 471            #region IEnumerable<KeyValuePair<string,object>> Members
 472
 473            public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
 474                throw new NotImplementedException("The method or operation is not implemented.");
 475            }
 476
 477            #endregion
 478
 479            #region IEnumerable Members
 480
 481            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
 482                throw new NotImplementedException("The method or operation is not implemented.");
 483            }
 484
 485            #endregion
 486        }
 487
 488        public void ScenarioCustomDictionary() {
 489            IAttributesCollection customGlobals = new PythonDictionary(new StringDictionaryStorage(new CustomDictionary()));
 490            
 491            ScriptScope customModule = _pe.Runtime.CreateScope(customGlobals);            
 492
 493            // Evaluate
 494            AreEqual(_pe.CreateScriptSourceFromString("customSymbol + 1").Execute<int>(customModule), CustomDictionary.customSymbolValue + 1);
 495
 496            // Execute
 497            _pe.CreateScriptSourceFromString("customSymbolPlusOne = customSymbol + 1", SourceCodeKind.Statements).Execute(customModule);
 498            AreEqual(_pe.CreateScriptSourceFromString("customSymbolPlusOne").Execute<int>(customModule), CustomDictionary.customSymbolValue + 1);
 499            AreEqual(_pe.GetVariable<int>(customModule, "customSymbolPlusOne"), CustomDictionary.customSymbolValue + 1);
 500
 501            // Compile
 502            CompiledCode compiledCode = _pe.CreateScriptSourceFromString("customSymbolPlusTwo = customSymbol + 2", SourceCodeKind.Statements).Compile();
 503
 504            compiledCode.Execute(customModule);
 505            AreEqual(_pe.CreateScriptSourceFromString("customSymbolPlusTwo").Execute<int>(customModule), CustomDictionary.customSymbolValue + 2);
 506            AreEqual(_pe.GetVariable<int>(customModule, "customSymbolPlusTwo"), CustomDictionary.customSymbolValue + 2);
 507
 508            // check overriding of Add
 509            try {
 510                _pe.CreateScriptSourceFromString("customSymbol = 1", SourceCodeKind.Statements).Execute(customModule);
 511                throw new Exception("We should not reach here");
 512            } catch (UnboundNameException) { }
 513
 514            try {
 515                _pe.CreateScriptSourceFromString(@"global customSymbol
 516customSymbol = 1", SourceCodeKind.Statements).Execute(customModule);
 517                throw new Exception("We should not reach here");
 518            } catch (UnboundNameException) { }
 519
 520            // check overriding of Remove
 521            try {
 522                _pe.CreateScriptSourceFromString("del customSymbol", SourceCodeKind.Statements).Execute(customModule);
 523                throw new Exception("We should not reach here");
 524            } catch (UnboundNameException) { }
 525
 526            try {
 527                _pe.CreateScriptSourceFromString(@"global customSymbol
 528del customSymbol", SourceCodeKind.Statements).Execute(customModule);
 529                throw new Exception("We should not reach here");
 530            } catch (UnboundNameException) { }
 531
 532            // vars()
 533            IDictionary vars = _pe.CreateScriptSourceFromString("vars()").Execute<IDictionary>(customModule);
 534            AreEqual(true, vars.Contains("customSymbol"));
 535
 536            // Miscellaneous APIs
 537            //IntIntDelegate d = pe.CreateLambda<IntIntDelegate>("customSymbol + arg", customModule);
 538            //AreEqual(d(1), CustomDictionary.customSymbolValue + 1);
 539        }
 540
 541        // Evaluate
 542        public void ScenarioEvaluate() {
 543            ScriptScope scope = _env.CreateScope();
 544            AreEqual(10, (int)_pe.CreateScriptSourceFromString("4+6").Execute(scope));
 545            AreEqual(10, _pe.CreateScriptSourceFromString("4+6").Execute<int>(scope));
 546
 547            AreEqual("abab", (string)_pe.CreateScriptSourceFromString("'ab' * 2").Execute(scope));
 548            AreEqual("abab", _pe.CreateScriptSourceFromString("'ab' * 2").Execute<string>(scope));
 549
 550            ClsPart clsPart = new ClsPart();
 551            scope.SetVariable(clspartName, clsPart);
 552            AreEqual(clsPart, _pe.CreateScriptSourceFromString("clsPart").Execute(scope) as ClsPart);
 553            AreEqual(clsPart, _pe.CreateScriptSourceFromString("clsPart").Execute<ClsPart>(scope));
 554
 555            _pe.CreateScriptSourceFromString("clsPart.Field = 100", SourceCodeKind.Statements).Execute(scope);
 556            AreEqual(100, (int)_pe.CreateScriptSourceFromString("clsPart.Field").Execute(scope));
 557            AreEqual(100, _pe.CreateScriptSourceFromString("clsPart.Field").Execute<int>(scope));
 558
 559            // Ensure that we can get back a delegate to a Python method
 560            _pe.CreateScriptSourceFromString("def IntIntMethod(a): return a * 100", SourceCodeKind.Statements).Execute(scope);
 561            IntIntDelegate d = _pe.CreateScriptSourceFromString("IntIntMethod").Execute<IntIntDelegate>(scope);
 562            AreEqual(d(2), 2 * 100);
 563        }
 564
 565        public void ScenarioCallableClassToDelegate() {
 566            ScriptSource src = _pe.CreateScriptSourceFromString(@"
 567class Test(object):
 568    def __call__(self):
 569        return 42
 570
 571inst = Test()
 572
 573class TestOC:
 574    def __call__(self):
 575        return 42
 576
 577instOC = TestOC()
 578", SourceCodeKind.Statements);
 579            ScriptScope scope = _pe.CreateScope();
 580            src.Execute(scope);
 581
 582            Func<int> t = scope.GetVariable<Func<int>>("inst");
 583            AreEqual(42, t());
 584
 585            t = scope.GetVariable<Func<int>>("instOC");
 586            AreEqual(42, t());
 587        }
 588
 589#if !SILVERLIGHT
 590        // ExecuteFile
 591        public void ScenarioExecuteFile() {
 592            ScriptSource tempFile1, tempFile2;
 593
 594            ScriptScope scope = _env.CreateScope();
 595
 596            using (StringWriter sw = new StringWriter()) {
 597                sw.WriteLine("var1 = (10, 'z')");
 598                sw.WriteLine("");
 599                sw.WriteLine("clsPart.Field = 100");
 600                sw.WriteLine("clsPart.Property = clsPart.Field * 5");
 601                sw.WriteLine("clsPart.Event += (lambda x: x*x)");
 602
 603                tempFile1 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
 604            }
 605
 606            ClsPart clsPart = new ClsPart();
 607            scope.SetVariable(clspartName, clsPart);
 608            tempFile1.Execute(scope);
 609
 610            using (StringWriter sw = new StringWriter()) {
 611                sw.WriteLine("if var1[0] != 10: raise AssertionError('test failed')");
 612                sw.WriteLine("if var1[1] != 'z': raise AssertionError('test failed')");
 613                sw.WriteLine("");
 614                sw.WriteLine("if clsPart.Property != clsPart.Field * 5: raise AssertionError('test failed')");
 615                sw.WriteLine("var2 = clsPart.Method(var1[0])");
 616                sw.WriteLine("if var2 != 10 * 10: raise AssertionError('test failed')");
 617
 618                tempFile2 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
 619            }
 620
 621            tempFile2.Execute(scope); 
 622        }
 623#endif
 624
 625#if !SILVERLIGHT
 626        // Bug: 542
 627        public void Scenario542() {
 628            ScriptSource tempFile1;
 629
 630            ScriptScope scope = _env.CreateScope();
 631
 632            using (StringWriter sw = new StringWriter()) {
 633                sw.WriteLine("def M1(): return -1");
 634                sw.WriteLine("def M2(): return +1");
 635
 636                sw.WriteLine("class C:");
 637                sw.WriteLine("    def M1(self): return -1");
 638                sw.WriteLine("    def M2(self): return +1");
 639
 640                sw.WriteLine("class C1:");
 641                sw.WriteLine("    def M(): return -1");
 642                sw.WriteLine("class C2:");
 643                sw.WriteLine("    def M(): return +1");
 644
 645                tempFile1 = _pe.CreateScriptSourceFromString(sw.ToString(), SourceCodeKind.File);
 646            }
 647
 648            tempFile1.Execute(scope);
 649
 650            AreEqual(-1, _pe.CreateScriptSourceFromString("M1()").Execute<int>(scope));
 651            AreEqual(+1, _pe.CreateScriptSourceFromString("M2()").Execute<int>(scope));
 652
 653            AreEqual(-1, (int)_pe.CreateScriptSourceFromString("M1()").Execute(scope));
 654            AreEqual(+1, (int)_pe.CreateScriptSourceFromString("M2()").Execute(scope));
 655
 656            _pe.CreateScriptSourceFromString("if M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
 657            _pe.CreateScriptSourceFromString("if M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
 658
 659
 660            _pe.CreateScriptSourceFromString("c = C()", SourceCodeKind.SingleStatement).Execute(scope);
 661            AreEqual(-1, _pe.CreateScriptSourceFromString("c.M1()").Execute<int>(scope));
 662            AreEqual(+1, _pe.CreateScriptSourceFromString("c.M2()").Execute<int>(scope));
 663
 664            AreEqual(-1, (int)_pe.CreateScriptSourceFromString("c.M1()").Execute(scope));
 665            AreEqual(+1, (int)_pe.CreateScriptSourceFromString("c.M2()").Execute(scope));
 666
 667            _pe.CreateScriptSourceFromString("if c.M1() != -1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
 668            _pe.CreateScriptSourceFromString("if c.M2() != +1: raise AssertionError('test failed')", SourceCodeKind.SingleStatement).Execute(scope);
 669
 670
 671            //AreEqual(-1, pe.EvaluateAs<int>("C1.M()"));
 672            //AreEqual(+1, pe.EvaluateAs<int>("C2.M()"));
 673
 674            //AreEqual(-1, (int)pe.Evaluate("C1.M()"));
 675            //AreEqual(+1, (int)pe.Evaluate("C2.M()"));
 676
 677            //pe.Execute(pe.CreateScriptSourceFromString("if C1.M() != -1: raise AssertionError('test failed')");
 678            //pe.Execute(pe.CreateScriptSourceFromString("if C2.M() != +1: raise AssertionError('test failed')");
 679        }
 680#endif
 681
 682        // Bug: 167 
 683        public void Scenario167() {
 684            ScriptScope scope = _env.CreateScope();
 685            _pe.CreateScriptSourceFromString("a=1\r\nb=-1", SourceCodeKind.Statements).Execute(scope);
 686            AreEqual(1, _pe.CreateScriptSourceFromString("a").Execute<int>(scope));
 687            AreEqual(-1, _pe.CreateScriptSourceFromString("b").Execute<int>(scope));
 688        }
 689#if !SILVERLIGHT
 690        // AddToPath
 691
 692        public void ScenarioAddToPath() { // runs first to avoid path-order issues            
 693            //pe.InitializeModules(ipc_path, ipc_path + "\\ipy.exe", pe.VersionString);
 694            string tempFile1 = Path.GetTempFileName();
 695
 696            try {
 697                File.WriteAllText(tempFile1, "from iptest.does_not_exist import *");
 698                ScriptScope scope = _pe.Runtime.CreateScope();
 699
 700                try {
 701                    _pe.CreateScriptSourceFromFile(tempFile1).Execute(scope);
 702                    throw new Exception("Scenario7");
 703                } catch (IronPython.Runtime.Exceptions.ImportException) { }
 704
 705                File.WriteAllText(tempFile1, "from iptest.assert_util import *");
 706                _pe.SetSearchPaths(new string[] { Common.ScriptTestDirectory });
 707
 708                _pe.CreateScriptSourceFromFile(tempFile1).Execute(scope);
 709                _pe.CreateScriptSourceFromString("AreEqual(5, eval('2 + 3'))", SourceCodeKind.Statements).Execute(scope);
 710            } finally {
 711                File.Delete(tempFile1);
 712            }
 713        }
 714
 715        // Options.DebugMode
 716#endif
 717
 718#if !SILVERLIGHT
 719        public void ScenarioPartialTrust() {
 720            // basic check of running a host in partial trust
 721            AppDomainSetup info = new AppDomainSetup();
 722            info.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
 723            info.ApplicationName = "Test";
 724            Evidence evidence = new Evidence();
 725            evidence.AddHost(new Zone(SecurityZone.Internet));
 726            AppDomain newDomain = AppDomain.CreateDomain("test", evidence, info);
 727            
 728            // create runtime in partial trust...
 729            ScriptRuntime runtime = Python.CreateRuntime(newDomain);
 730
 731            // get the Python engine...
 732            ScriptEngine engine = runtime.GetEngine("py");
 733
 734            // execute some simple code
 735            ScriptScope scope = engine.CreateScope();
 736            ScriptSource source = engine.CreateScriptSourceFromString("2 + 2");
 737            AreEqual(source.Execute<int>(scope), 4);
 738
 739            // import all of the built-in modules & make sure we can reflect on them...
 740            source = engine.CreateScriptSourceFromString(@"
 741import sys
 742for mod in sys.builtin_module_names:
 743    x = __import__(mod)
 744    dir(x)
 745", SourceCodeKind.Statements);
 746
 747            source.Execute(scope);
 748
 749            // define some classes & use the methods...
 750            source = engine.CreateScriptSourceFromString(@"
 751class x(object):
 752    def f(self): return 1 + 2
 753
 754a = x()
 755a.f()
 756
 757
 758class y: 
 759    def f(self): return 1 + 2
 760
 761b = y()
 762b.f()
 763", SourceCodeKind.Statements);
 764
 765
 766            source.Execute(scope);
 767
 768            // call a protected method on a derived class...
 769            source = engine.CreateScriptSourceFromString(@"
 770import clr
 771class x(object):
 772    def f(self): return 1 + 2
 773
 774a = x()
 775b = a.MemberwiseClone()
 776
 777if id(a) == id(b):
 778    raise Exception
 779", SourceCodeKind.Statements);
 780
 781
 782            source.Execute(scope);
 783
 784            AppDomain.Unload(newDomain);
 785        }
 786
 787        public void ScenarioStackFrameLineInfo() {
 788            const string lineNumber = "raise.py:line";
 789
 790            // TODO: clone setup?
 791            var scope = Python.CreateRuntime().CreateScope("py");
 792            var debugSetup = Python.CreateRuntimeSetup(null);
 793            debugSetup.DebugMode = true;
 794            var debugScope = new ScriptRuntime(debugSetup).CreateScope("py");
 795
 796            TestLineInfo(scope, lineNumber);
 797            TestLineInfo(debugScope, lineNumber);
 798            TestLineInfo(scope, lineNumber);
 799
 800            // Ensure that all APIs work
 801            AreEqual(scope.GetVariable<int>("x"), 1);
 802
 803            //IntIntDelegate d = pe.CreateLambda<IntIntDelegate>("arg + x");
 804            //AreEqual(d(100), 101);
 805            //d = pe.CreateMethod<IntIntDelegate>("var = arg + x\nreturn var");
 806            //AreEqual(d(100), 101);
 807        }
 808
 809        private void TestLineInfo(ScriptScope/*!*/ scope, string lineNumber) {
 810            try {
 811                scope.Engine.ExecuteFile(Common.InputTestDirectory + "\\raise.py", scope);
 812                throw new Exception("We should not get here");
 813            } catch (StringException e2) {
 814                if (scope.Engine.Runtime.Setup.DebugMode != e2.StackTrace.Contains(lineNumber))
 815                    throw new Exception("Debugging is enabled even though Options.DebugMode is not specified");
 816            }
 817        }
 818
 819#endif
 820
 821        // Compile and Run
 822        public void ScenarioCompileAndRun() {
 823            ClsPart clsPart = new ClsPart();
 824
 825            ScriptScope scope = _env.CreateScope();
 826
 827            scope.SetVariable(clspartName, clsPart);
 828            CompiledCode compiledCode = _pe.CreateScriptSourceFromString("def f(): clsPart.Field += 10", SourceCodeKind.Statements).Compile();
 829            compiledCode.Execute(scope);
 830
 831            compiledCode = _pe.CreateScriptSourceFromString("f()").Compile();
 832            compiledCode.Execute(scope);
 833            AreEqual(10, clsPart.Field);
 834            compiledCode.Execute(scope);
 835            AreEqual(20, clsPart.Field);
 836        }
 837
 838        public void ScenarioStreamRedirect() {
 839            MemoryStream stdout = new MemoryStream();
 840            MemoryStream stdin = new MemoryStream();
 841            MemoryStream stderr = new MemoryStream();
 842            Encoding encoding = Encoding.UTF8;
 843
 844            _pe.Runtime.IO.SetInput(stdin, encoding);
 845            _pe.Runtime.IO.SetOutput(stdout, encoding);
 846            _pe.Runtime.IO.SetErrorOutput(stderr, encoding);
 847 
 848            const string str = "This is stdout";
 849            byte[] bytes = encoding.GetBytes(str);
 850
 851            try {
 852                ScriptScope scope = _pe.Runtime.CreateScope();
 853                _pe.CreateScriptSourceFromString("import sys", SourceCodeKind.Statements).Execute(scope);
 854
 855                stdin.Write(bytes, 0, bytes.Length);
 856                stdin.Position = 0;
 857                _pe.CreateScriptSourceFromString("output = sys.__stdin__.readline()", SourceCodeKind.Statements).Execute(scope);
 858                AreEqual(str, _pe.CreateScriptSourceFromString("output").Execute<string>(scope));
 859
 860                _pe.CreateScriptSourceFromString("sys.__stdout__.write(output)", SourceCodeKind.Statements).Execute(scope);
 861                stdout.Flush();
 862                stdout.Position = 0;
 863
 864                // deals with BOM:
 865                using (StreamReader reader = new StreamReader(stdout, true)) {
 866                    string s = reader.ReadToEnd();
 867                    AreEqual(str, s);
 868                }
 869
 870                _pe.CreateScriptSourceFromString("sys.__stderr__.write(\"This is stderr\")", SourceCodeKind.Statements).Execute(scope);
 871
 872                stderr.Flush();
 873                stderr.Position = 0;
 874                
 875                // deals with BOM:
 876                using (StreamReader reader = new StreamReader(stderr, true)) {
 877                    string s = reader.ReadToEnd();
 878                    AreEqual("This is stderr", s);
 879                }
 880            } finally {
 881                _pe.Runtime.IO.RedirectToConsole();
 882            }
 883        }
 884
 885        public void Scenario12() {
 886            ScriptScope scope = _env.CreateScope();
 887
 888            _pe.CreateScriptSourceFromString(@"
 889class R(object):
 890    def __init__(self, a, b):
 891        self.a = a
 892        self.b = b
 893   
 894    def M(self):
 895        return self.a + self.b
 896
 897    sum = property(M, None, None, None)
 898
 899r = R(10, 100)
 900if r.sum != 110:
 901    raise AssertionError('Scenario 12 failed')
 902", SourceCodeKind.Statements).Execute(scope);
 903        }
 904
 905// TODO: rewrite 
 906#if FALSE
 907        public void ScenarioTrueDivision1() {
 908            TestOldDivision(pe, DefaultModule);
 909            ScriptScope module = pe.CreateModule("anonymous", ModuleOptions.TrueDivision);
 910            TestNewDivision(pe, module);
 911        }
 912
 913        public void ScenarioTrueDivision2() {
 914            TestOldDivision(pe, DefaultModule);
 915            ScriptScope module = pe.CreateModule("__future__", ModuleOptions.PublishModule);
 916            module.SetVariable("division", 1);
 917            pe.Execute(pe.CreateScriptSourceFromString("from __future__ import division", module));
 918            TestNewDivision(pe, module);
 919        }
 920
 921        public void ScenarioTrueDivision3() {
 922            TestOldDivision(pe, DefaultModule);
 923            ScriptScope future = pe.CreateModule("__future__", ModuleOptions.PublishModule);
 924            future.SetVariable("division", 1);
 925            ScriptScope td = pe.CreateModule("truediv", ModuleOptions.None);
 926            ScriptCode cc = ScriptCode.FromCompiledCode((CompiledCode)pe.CompileCode("from __future__ import division"));
 927            cc.Run(td);
 928            TestNewDivision(pe, td);  // we've polluted the DefaultModule by executing the code
 929        }
 930#if !SILVERLIGHT
 931        public void ScenarioTrueDivision4() {
 932            pe.AddToPath(Common.ScriptTestDirectory);
 933
 934            string modName = GetTemporaryModuleName();
 935            string file = System.IO.Path.Combine(Common.ScriptTestDirectory, modName + ".py");
 936            System.IO.File.WriteAllText(file, "result = 1/2");
 937
 938            PythonDivisionOptions old = PythonEngine.CurrentEngine.Options.DivisionOptions;
 939
 940            try {
 941                PythonEngine.CurrentEngine.Options.DivisionOptions = PythonDivisionOptions.Old;
 942                ScriptScope module = pe.CreateModule("anonymous", ModuleOptions.TrueDivision);
 943                pe.Execute(pe.CreateScriptSourceFromString("import " + modName, module));
 944                int res = pe.EvaluateAs<int>(modName + ".result", module);
 945                AreEqual(res, 0);
 946            } finally {
 947                PythonEngine.CurrentEngine.Options.DivisionOptions = old;
 948                try {
 949                    System.IO.File.Delete(file);
 950                } catch { }
 951            }
 952        }
 953
 954        private string GetTemporaryModuleName() {
 955            return "tempmod" + Path.GetRandomFileName().Replace('-', '_').Replace('.', '_');
 956        }
 957
 958        public void ScenarioTrueDivision5() {
 959            pe.AddToPath(Common.ScriptTestDirectory);
 960
 961            string modName = GetTemporaryModuleName();
 962            string file = System.IO.Path.Combine(Common.ScriptTestDirectory, modName + ".py");
 963            System.IO.File.WriteAllText(file, "from __future__ import division; result = 1/2");
 964
 965            try {
 966                ScriptScope module = ScriptDomainManager.CurrentManager.CreateModule(modName);
 967                pe.Execute(pe.CreateScriptSourceFromString("import " + modName, module));
 968                double res = pe.EvaluateAs<double>(modName + ".result", module);
 969                AreEqual(res, 0.5);
 970                AreEqual((bool)((PythonContext)DefaultContext.Default.LanguageContext).TrueDivision, false);
 971            } finally {
 972                try {
 973                    System.IO.File.Delete(file);
 974                } catch { }
 975            }
 976        }
 977        public void ScenarioSystemStatePrefix() {
 978            AreEqual(IronPythonTest.Common.RuntimeDirectory, pe.SystemState.prefix);
 979        }
 980#endif
 981
 982        private static void TestOldDivision(ScriptEngine pe, ScriptScope module) {
 983            pe.Execute(pe.CreateScriptSourceFromString("result = 1/2", module));
 984            AreEqual((int)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 0);
 985            AreEqual(pe.EvaluateAs<int>("1/2", module), 0);
 986            pe.Execute(pe.CreateScriptSourceFromString("exec 'result = 3/2'", module));
 987            AreEqual((int)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 1);
 988            AreEqual(pe.EvaluateAs<int>("eval('3/2')", module), 1);
 989        }
 990
 991        private static void TestNewDivision(ScriptEngine pe, ScriptScope module) {
 992            pe.Execute(pe.CreateScriptSourceFromString("result = 1/2", module));
 993            AreEqual((double)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 0.5);
 994            AreEqual(pe.EvaluateAs<double>("1/2", module), 0.5);
 995            pe.Execute(pe.CreateScriptSourceFromString("exec 'result = 3/2'", module));
 996            AreEqual((double)module.Scope.LookupName(DefaultContext.Default.LanguageContext, SymbolTable.StringToId("result")), 1.5);
 997            AreEqual(pe.EvaluateAs<double>("eval('3/2')", module), 1.5);
 998        }
 999#endif
1000        // More to come: exception related...
1001
1002        public static int Negate(int arg) { return -1 * arg; }
1003
1004        static void AreEqual<T>(T expected, T actual) {
1005            if (expected == null && actual == null) return;
1006
1007            if (!expected.Equals(actual)) {
1008                Console.WriteLine("Expected: {0} Got: {1} from {2}", expected, actual, new StackTrace(true));
1009                throw new Exception();
1010            }
1011        }
1012    }
1013}