public async Task Issue11_NRE_When_Variable_Has_No_Initializer() { var fooContent = @" var i, length; i = 1; "; var fileProvider = new MemoryFileProvider(); var fooFile = new ModuleFile(fileProvider, "/foo.js") { Content = fooContent }; var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { fooFile }, CancellationToken.None); var fooLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/foo.js").Value.Content); Assert.Equal(new[] { "'use strict';", "var i, length;", "i = 1;", }, fooLines); }
public async Task Export_Default_Named() { var fooContent = @"import * as bar from './bar';"; var barContent = @"export default function myFunc() {}"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("/bar.js", barContent); var fooFile = new ModuleFile(fileProvider, null) { Content = fooContent }; var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { fooFile }, CancellationToken.None); var barLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/bar.js").Value.Content); Assert.Equal(new[] { "'use strict';", "__es$require.d(__es$exports, \"default\", function() { return myFunc; });", "function myFunc() {}", }, barLines); }
public void ParsingOptions() { var configJson = $@"{{ '{nameof(FileLoggerOptions.RootPath)}': '{Path.DirectorySeparatorChar.ToString().Replace(@"\", @"\\")}', '{nameof(FileLoggerOptions.BasePath)}': 'Logs', '{nameof(FileLoggerOptions.EnsureBasePath)}': true, '{nameof(FileLoggerOptions.FileEncodingName)}': 'utf-8', '{nameof(FileLoggerOptions.FallbackFileName)}': 'other.log', '{nameof(FileLoggerOptions.FileNameMappings)}': {{ 'Karambolo.Extensions.Logging.File': 'logger.log', 'Karambolo.Extensions.Logging.File.Test': 'test.log', }}, '{nameof(FileLoggerOptions.DateFormat)}': 'yyyyMMdd', '{nameof(FileLoggerOptions.CounterFormat)}': '000', '{nameof(FileLoggerOptions.MaxFileSize)}': 10, '{nameof(FileLoggerOptions.TextBuilderType)}': '{typeof(CustomLogEntryTextBuilder).AssemblyQualifiedName}', '{nameof(FileLoggerOptions.IncludeScopes)}': true, '{nameof(FileLoggerOptions.IncludeScopes)}': true, '{nameof(FileLoggerOptions.MaxQueueSize)}': 100, }}"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("config.json", configJson, Encoding.UTF8); var cb = new ConfigurationBuilder(); cb.AddJsonFile(fileProvider, "config.json", optional: false, reloadOnChange: false); IConfigurationRoot config = cb.Build(); var services = new ServiceCollection(); services.AddOptions(); services.Configure <FileLoggerOptions>(config); ServiceProvider serviceProvider = services.BuildServiceProvider(); FileLoggerOptions options = serviceProvider.GetService <IOptions <FileLoggerOptions> >().Value; Assert.True(options.FileAppender is PhysicalFileAppender); Assert.Equal(Path.GetPathRoot(Environment.CurrentDirectory), ((PhysicalFileAppender)options.FileAppender).FileProvider.Root); Assert.Equal("Logs", options.BasePath); Assert.True(options.EnsureBasePath); Assert.Equal(Encoding.UTF8, options.FileEncoding); Assert.Equal("other.log", options.FallbackFileName); Assert.Equal("test.log", options.MapToFileName(typeof(SettingsTest).FullName, "default.log")); Assert.Equal("logger.log", options.MapToFileName(typeof(FileLogger).FullName, "default.log")); Assert.Equal("default.log", options.MapToFileName("X.Y", "default.log")); Assert.Equal("yyyyMMdd", options.DateFormat); Assert.Equal("000", options.CounterFormat); Assert.Equal(10, options.MaxFileSize); Assert.Equal(typeof(CustomLogEntryTextBuilder), options.TextBuilder.GetType()); Assert.True(options.IncludeScopes); Assert.Equal(100, options.MaxQueueSize); }
public async Task LoggingToMemoryUsingCustomPathPlaceholderResolver() { const string appName = "myapp"; const string logsDirName = "Logs"; var fileProvider = new MemoryFileProvider(); var cts = new CancellationTokenSource(); var context = new TestFileLoggerContext(cts.Token, completionTimeout: Timeout.InfiniteTimeSpan); context.SetTimestamp(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc)); var services = new ServiceCollection(); services.AddOptions(); services.AddLogging(b => b.AddFile(context, o => { o.FileAppender = new MemoryFileAppender(fileProvider); o.BasePath = logsDirName; o.Files = new[] { new LogFileOptions { Path = "<appname>-<counter:000>.log" } }; o.PathPlaceholderResolver = (placeholderName, inlineFormat, context) => placeholderName == "appname" ? appName : null; })); FileLoggerProvider[] providers; using (ServiceProvider sp = services.BuildServiceProvider()) { providers = context.GetProviders(sp).ToArray(); Assert.Equal(1, providers.Length); ILogger <LoggingTest> logger1 = sp.GetService <ILogger <LoggingTest> >(); logger1.LogInformation("This is a nice logger."); logger1.LogWarning(1, "This is a smart logger."); cts.Cancel(); // ensuring that all entries are processed await context.GetCompletion(sp); Assert.True(providers.All(provider => provider.Completion.IsCompleted)); } var logFile = (MemoryFileInfo)fileProvider.GetFileInfo($"{logsDirName}/{appName}-000.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); }
public async Task Feature_AsyncAwait_And_DynamicImport() { var fooContent = @"import * as bar from './bar'; (async () => await bar.myAsyncFunc3())(); "; var barContent = @" export const myAsyncLambda = async () => await import('x'); export const myAsyncFunc1 = async function() { return await myAsyncLambda(); } export async function myAsyncFunc2() { return await myAsyncFunc1(); } async function myAsyncFunc3() { return await myAsyncFunc2(); } export { myAsyncFunc3 } "; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("/bar.js", barContent); var fooFile = new ModuleFile(fileProvider, "/foo.js") { Content = fooContent }; var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { fooFile }, CancellationToken.None); var fooLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/foo.js").Value.Content); Assert.Equal(new[] { "'use strict';", "var __es$module_0 = __es$require(\"/bar.js\");", "(async () => await __es$module_0.myAsyncFunc3())();", }, fooLines); var barLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/bar.js").Value.Content); Assert.Equal(new[] { "'use strict';", "__es$require.d(__es$exports, \"myAsyncLambda\", function() { return myAsyncLambda; });", "__es$require.d(__es$exports, \"myAsyncFunc1\", function() { return myAsyncFunc1; });", "__es$require.d(__es$exports, \"myAsyncFunc2\", function() { return myAsyncFunc2; });", "__es$require.d(__es$exports, \"myAsyncFunc3\", function() { return myAsyncFunc3; });", "const myAsyncLambda = async () => await import('x');", "const myAsyncFunc1 = async function() { return await myAsyncLambda(); }", "async function myAsyncFunc2() { return await myAsyncFunc1(); }", "async function myAsyncFunc3() { return await myAsyncFunc2(); }", }, barLines); }
public async Task Reexport_Everything() { var fooContent = @"import * as bar from './bar';"; var barContent = @"export * from './baz'"; var bazContent = @"export var [myVar1, { a: myVar2, b: { c: myVar3, ...rest1} }, ...rest2] = [1, { a: 2, b: { c: 3.14 } }];"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("/bar.js", barContent); fileProvider.CreateFile("/baz.js", bazContent); var fooFile = new ModuleFile(fileProvider, null) { Content = fooContent }; var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { fooFile }, CancellationToken.None); var barLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/bar.js").Value.Content); Assert.Equal(new[] { "'use strict';", "var __es$module_0 = __es$require(\"/baz.js\");", "__es$require.d(__es$exports, \"myVar1\", function() { return __es$module_0.myVar1; });", "__es$require.d(__es$exports, \"myVar2\", function() { return __es$module_0.myVar2; });", "__es$require.d(__es$exports, \"myVar3\", function() { return __es$module_0.myVar3; });", "__es$require.d(__es$exports, \"rest1\", function() { return __es$module_0.rest1; });", "__es$require.d(__es$exports, \"rest2\", function() { return __es$module_0.rest2; });", }, barLines); var bazLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/baz.js").Value.Content); Assert.Equal(new[] { "'use strict';", "__es$require.d(__es$exports, \"myVar1\", function() { return myVar1; });", "__es$require.d(__es$exports, \"myVar2\", function() { return myVar2; });", "__es$require.d(__es$exports, \"myVar3\", function() { return myVar3; });", "__es$require.d(__es$exports, \"rest1\", function() { return rest1; });", "__es$require.d(__es$exports, \"rest2\", function() { return rest2; });", "var [myVar1, { a: myVar2, b: { c: myVar3, ...rest1} }, ...rest2] = [1, { a: 2, b: { c: 3.14 } }];", }, bazLines); }
public void ParsingOptions() { var configJson = $@"{{ '{nameof(FileLoggerOptions.BasePath)}': 'Logs', '{nameof(FileLoggerOptions.EnsureBasePath)}': true, '{nameof(FileLoggerOptions.FileEncodingName)}': 'utf-8', '{nameof(FileLoggerOptions.FileNameMappings)}': {{ 'Karambolo.Extensions.Logging.File': 'logger.log', 'Karambolo.Extensions.Logging.File.Test': 'test.log', }}, '{nameof(FileLoggerOptions.DateFormat)}': 'yyyyMMdd', '{nameof(FileLoggerOptions.CounterFormat)}': '000', '{nameof(FileLoggerOptions.MaxFileSize)}': 10, '{nameof(FileLoggerOptions.TextBuilderType)}': '{typeof(CustomLogEntryTextBuilder).AssemblyQualifiedName}', '{nameof(FileLoggerOptions.IncludeScopes)}': true, '{nameof(FileLoggerOptions.IncludeScopes)}': true, '{nameof(FileLoggerOptions.MaxQueueSize)}': 100, }}"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("config.json", configJson, Encoding.UTF8); var cb = new ConfigurationBuilder(); cb.AddJsonFile(fileProvider, "config.json", optional: false, reloadOnChange: false); var config = cb.Build(); var services = new ServiceCollection(); services.AddOptions(); services.Configure <FileLoggerOptions>(config); var serviceProvider = services.BuildServiceProvider(); var options = serviceProvider.GetService <IOptions <FileLoggerOptions> >().Value; Assert.Equal("Logs", options.BasePath); Assert.Equal(true, options.EnsureBasePath); Assert.Equal(Encoding.UTF8, options.FileEncoding); Assert.Equal("test.log", options.MapToFileName(typeof(SettingsTest).FullName, "default.log")); Assert.Equal("logger.log", options.MapToFileName(typeof(FileLogger).FullName, "default.log")); Assert.Equal("default.log", options.MapToFileName("X.Y", "default.log")); Assert.Equal("yyyyMMdd", options.DateFormat); Assert.Equal("000", options.CounterFormat); Assert.Equal(10, options.MaxFileSize); Assert.Equal(typeof(CustomLogEntryTextBuilder), options.TextBuilder.GetType()); Assert.Equal(true, options.IncludeScopes); Assert.Equal(100, options.MaxQueueSize); }
public async Task Reexport_Clause() { var fooContent = @"import * as bar from './bar';"; var barContent = @"export { default, default as defaultAlias, rest, rest as restAlias } from './baz'"; var bazContent = @"var [myVar1, {a: myVar2, b: [myVar3, ...rest]}] = [1, {a: 2, b: [3.14]}]; export { myVar1 as default, rest };"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("/bar.js", barContent); fileProvider.CreateFile("/baz.js", bazContent); var fooFile = new ModuleFile(fileProvider, null) { Content = fooContent }; var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { fooFile }, CancellationToken.None); var barLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/bar.js").Value.Content); Assert.Equal(new[] { "'use strict';", "var __es$module_0 = __es$require(\"/baz.js\");", "__es$require.d(__es$exports, \"default\", function() { return __es$module_0.default; });", "__es$require.d(__es$exports, \"defaultAlias\", function() { return __es$module_0.default; });", "__es$require.d(__es$exports, \"rest\", function() { return __es$module_0.rest; });", "__es$require.d(__es$exports, \"restAlias\", function() { return __es$module_0.rest; });", }, barLines); var bazLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/baz.js").Value.Content); Assert.Equal(new[] { "'use strict';", "__es$require.d(__es$exports, \"default\", function() { return myVar1; });", "__es$require.d(__es$exports, \"rest\", function() { return rest; });", "var [myVar1, {a: myVar2, b: [myVar3, ...rest]}] = [1, {a: 2, b: [3.14]}];", }, bazLines); }
public async Task Export_Named_Clause() { var fooContent = @"import * as bar from './bar';"; var barContent = @"var myVar1 = '1'; let myVar2 = 2; const MY_CONST = 3.14; function myFunc() { return myVar1; } function* myGeneratorFunc() { yield myVar2; } class MyClass { method() { return myFunc(); } } export { myVar1, myVar2 as var2, MY_CONST, myFunc, myGeneratorFunc, MyClass as default }"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("/bar.js", barContent); var fooFile = new ModuleFile(fileProvider, null) { Content = fooContent }; var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { fooFile }, CancellationToken.None); var barLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/bar.js").Value.Content); Assert.Equal(new[] { "'use strict';", "__es$require.d(__es$exports, \"myVar1\", function() { return myVar1; });", "__es$require.d(__es$exports, \"var2\", function() { return myVar2; });", "__es$require.d(__es$exports, \"MY_CONST\", function() { return MY_CONST; });", "__es$require.d(__es$exports, \"myFunc\", function() { return myFunc; });", "__es$require.d(__es$exports, \"myGeneratorFunc\", function() { return myGeneratorFunc; });", "__es$require.d(__es$exports, \"default\", function() { return MyClass; });", "var myVar1 = '1';", "let myVar2 = 2;", "const MY_CONST = 3.14;", "function myFunc() { return myVar1; }", "function* myGeneratorFunc() { yield myVar2; }", "class MyClass { method() { return myFunc(); } }", }, barLines); }
public async Task Import_CircularReference() { var fooContent = @"export var fooVar = 1; import { barVar } from './bar'; console.log({fooVar, barVar})"; var barContent = @"export var barVar = 2; import { fooVar } from './foo'; console.log({fooVar, barVar})"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("/foo.js", fooContent); fileProvider.CreateFile("/bar.js", barContent); var fooFile = new ModuleFile(fileProvider, "/foo.js"); var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { fooFile }, CancellationToken.None); var fooLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/foo.js").Value.Content); Assert.Equal(new[] { "'use strict';", "var __es$module_0 = __es$require(\"/bar.js\");", "__es$require.d(__es$exports, \"fooVar\", function() { return fooVar; });", "var fooVar = 1;", "console.log({fooVar, barVar: __es$module_0.barVar})", }, fooLines); var barLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "/bar.js").Value.Content); Assert.Equal(new[] { "'use strict';", "var __es$module_0 = __es$require(\"/foo.js\");", "__es$require.d(__es$exports, \"barVar\", function() { return barVar; });", "var barVar = 2;", "console.log({fooVar: __es$module_0.fooVar, barVar})", }, barLines); }
public async Task Import_Namespace() { var fooContent = @"import defaultExport, * as bar from './bar'; console.log(defaultExport); var myVar1 = bar.myVar1; console.log(myVar1 + bar.myVar2); "; var barContent = @"export var myVar1 = '1'; export let myVar2 = 2; export default 3.14;"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("/bar.js", barContent); var fooFile = new ModuleFile(fileProvider, null) { Content = fooContent }; var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { fooFile }, CancellationToken.None); var fooLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "<root0>").Value.Content); Assert.Equal(new[] { "'use strict';", "var __es$module_0 = __es$require(\"/bar.js\");", "console.log(__es$module_0.default);", "var myVar1 = __es$module_0.myVar1;", "console.log(myVar1 + __es$module_0.myVar2);", }, fooLines); }
public async Task ReloadOptionsSettingsMultipleProviders() { var fileProvider = new MemoryFileProvider(); var fileAppender = new MemoryFileAppender(fileProvider); dynamic settings = new JObject(); dynamic globalFilters = settings[nameof(LoggerFilterRule.LogLevel)] = new JObject(); globalFilters[LogFileOptions.DefaultCategoryName] = LogLevel.None.ToString(); settings[FileLoggerProvider.Alias] = new JObject(); dynamic fileFilters = settings[FileLoggerProvider.Alias][nameof(LoggerFilterRule.LogLevel)] = new JObject(); fileFilters[LogFileOptions.DefaultCategoryName] = LogLevel.Warning.ToString(); dynamic oneFile = new JObject(); oneFile.Path = "one.log"; settings[FileLoggerProvider.Alias][nameof(FileLoggerOptions.Files)] = new JArray(oneFile); settings[OtherFileLoggerProvider.Alias] = new JObject(); dynamic otherFileFilters = settings[OtherFileLoggerProvider.Alias][nameof(LoggerFilterRule.LogLevel)] = new JObject(); otherFileFilters[LogFileOptions.DefaultCategoryName] = LogLevel.Information.ToString(); dynamic otherFile = new JObject(); otherFile.Path = "other.log"; settings[OtherFileLoggerProvider.Alias][nameof(FileLoggerOptions.Files)] = new JArray(otherFile); var configJson = ((JObject)settings).ToString(); fileProvider.CreateFile("config.json", configJson); IConfigurationRoot config = new ConfigurationBuilder() .AddJsonFile(fileProvider, "config.json", optional: false, reloadOnChange: true) .Build(); var context = new TestFileLoggerContext(default, completionTimeout: Timeout.InfiniteTimeSpan);
public async Task ReloadOptionsSettings() { var configJson = $@"{{ ""{FileLoggerProvider.Alias}"": {{ ""{nameof(FileLoggerOptions.IncludeScopes)}"" : true, ""{nameof(FileLoggerOptions.Files)}"": [ {{ ""{nameof(LogFileOptions.Path)}"": ""test.log"", }}], ""{nameof(LoggerFilterRule.LogLevel)}"": {{ ""{LogFileOptions.DefaultCategoryName}"": ""{LogLevel.Trace}"" }} }} }}"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("config.json", configJson, Encoding.UTF8); var cb = new ConfigurationBuilder(); cb.AddJsonFile(fileProvider, "config.json", optional: false, reloadOnChange: true); IConfigurationRoot config = cb.Build(); var completeCts = new CancellationTokenSource(); var context = new TestFileLoggerContext(completeCts.Token, completionTimeout: Timeout.InfiniteTimeSpan); context.SetTimestamp(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc)); var services = new ServiceCollection(); services.AddOptions(); services.AddLogging(b => { b.AddConfiguration(config); b.AddFile(context); }); var fileAppender = new MemoryFileAppender(fileProvider); services.Configure <FileLoggerOptions>(o => o.FileAppender ??= fileAppender); FileLoggerProvider[] providers; using (ServiceProvider sp = services.BuildServiceProvider()) { providers = context.GetProviders(sp).ToArray(); Assert.Equal(1, providers.Length); var resetTasks = new List <Task>(); foreach (FileLoggerProvider provider in providers) { provider.Reset += (s, e) => resetTasks.Add(e); } ILoggerFactory loggerFactory = sp.GetService <ILoggerFactory>(); ILogger <SettingsTest> logger1 = loggerFactory.CreateLogger <SettingsTest>(); using (logger1.BeginScope("SCOPE")) { logger1.LogTrace("This is a nice logger."); using (logger1.BeginScope("NESTED SCOPE")) { logger1.LogInformation("This is a smart logger."); // changing switch and scopes inclusion configJson = $@"{{ ""{FileLoggerProvider.Alias}"": {{ ""{nameof(FileLoggerOptions.Files)}"": [ {{ ""{nameof(LogFileOptions.Path)}"": ""test.log"", }}], ""{nameof(LoggerFilterRule.LogLevel)}"": {{ ""{LogFileOptions.DefaultCategoryName}"": ""{LogLevel.Information}"" }} }} }}"; Assert.Equal(0, resetTasks.Count); fileProvider.WriteContent("config.json", configJson); // reload is triggered twice due to a bug in the framework (https://github.com/aspnet/Logging/issues/874) Assert.Equal(1 * 2, resetTasks.Count); // ensuring that reset has been finished and the new settings are effective await Task.WhenAll(resetTasks); logger1 = loggerFactory.CreateLogger <SettingsTest>(); logger1.LogInformation("This one shouldn't include scopes."); logger1.LogTrace("This one shouldn't be included at all."); } } completeCts.Cancel(); // ensuring that all entries are processed await context.GetCompletion(sp); Assert.True(providers.All(provider => provider.Completion.IsCompleted)); } var logFile = (MemoryFileInfo)fileProvider.GetFileInfo("test.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); var lines = logFile.ReadAllText(out Encoding encoding).Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, encoding); Assert.Equal(new[] { $"trce: {typeof(SettingsTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" => SCOPE", $" This is a nice logger.", $"info: {typeof(SettingsTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" => SCOPE => NESTED SCOPE", $" This is a smart logger.", $"info: {typeof(SettingsTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This one shouldn't include scopes.", "" }, lines); }
public void ParsingOptions() { var configJson = $@"{{ ""{nameof(FileLoggerOptions.RootPath)}"": ""{Path.DirectorySeparatorChar.ToString().Replace(@"\", @"\\")}"", ""{nameof(FileLoggerOptions.BasePath)}"": ""Logs"", ""{nameof(FileLoggerOptions.FileAccessMode)}"": ""{LogFileAccessMode.OpenTemporarily}"", ""{nameof(FileLoggerOptions.FileEncodingName)}"": ""utf-8"", ""{nameof(FileLoggerOptions.Files)}"": [ {{ ""{nameof(LogFileOptions.Path)}"": ""logger.log"", ""{nameof(LogFileOptions.MinLevel)}"": {{ ""Karambolo.Extensions.Logging.File"": ""{LogLevel.Warning}"", ""{LogFileOptions.DefaultCategoryName}"": ""{LogLevel.None}"", }}, }}, {{ ""{nameof(LogFileOptions.Path)}"": ""test.log"", ""{nameof(LogFileOptions.MinLevel)}"": {{ ""Karambolo.Extensions.Logging.File.Test"": ""{LogLevel.Debug}"", ""{LogFileOptions.DefaultCategoryName}"": ""{LogLevel.None}"", }}, }}], ""{nameof(FileLoggerOptions.DateFormat)}"": ""yyyyMMdd"", ""{nameof(FileLoggerOptions.CounterFormat)}"": ""000"", ""{nameof(FileLoggerOptions.MaxFileSize)}"": 10, ""{nameof(FileLoggerOptions.TextBuilderType)}"": ""{typeof(CustomLogEntryTextBuilder).AssemblyQualifiedName}"", ""{nameof(FileLoggerOptions.IncludeScopes)}"": true, ""{nameof(FileLoggerOptions.MaxQueueSize)}"": 100, }}"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("config.json", configJson); var cb = new ConfigurationBuilder(); cb.AddJsonFile(fileProvider, "config.json", optional: false, reloadOnChange: false); IConfigurationRoot config = cb.Build(); var services = new ServiceCollection(); services.AddOptions(); services.Configure <FileLoggerOptions>(config); ServiceProvider serviceProvider = services.BuildServiceProvider(); IFileLoggerSettings settings = serviceProvider.GetService <IOptions <FileLoggerOptions> >().Value; Assert.True(settings.FileAppender is PhysicalFileAppender); Assert.Equal(Path.GetPathRoot(Environment.CurrentDirectory), ((PhysicalFileAppender)settings.FileAppender).FileProvider.Root); Assert.Equal("Logs", settings.BasePath); Assert.Equal(LogFileAccessMode.OpenTemporarily, settings.FileAccessMode); Assert.Equal(Encoding.UTF8, settings.FileEncoding); Assert.Equal(2, settings.Files.Length); ILogFileSettings fileSettings = Array.Find(settings.Files, f => f.Path == "logger.log"); Assert.NotNull(fileSettings); Assert.Equal(LogLevel.None, fileSettings.GetMinLevel(typeof(string).ToString())); Assert.Equal(LogLevel.Warning, fileSettings.GetMinLevel(typeof(FileLogger).ToString())); Assert.Equal(LogLevel.Warning, fileSettings.GetMinLevel(typeof(SettingsTest).ToString())); fileSettings = Array.Find(settings.Files, f => f.Path == "test.log"); Assert.NotNull(fileSettings); Assert.Equal(LogLevel.None, fileSettings.GetMinLevel(typeof(string).ToString())); Assert.Equal(LogLevel.None, fileSettings.GetMinLevel(typeof(FileLogger).ToString())); Assert.Equal(LogLevel.Debug, fileSettings.GetMinLevel(typeof(SettingsTest).ToString())); Assert.Equal("yyyyMMdd", settings.DateFormat); Assert.Equal("000", settings.CounterFormat); Assert.Equal(10, settings.MaxFileSize); Assert.Equal(typeof(CustomLogEntryTextBuilder), settings.TextBuilder.GetType()); Assert.True(settings.IncludeScopes); Assert.Equal(100, settings.MaxQueueSize); }
private async Task LoggingToMemoryWithoutDICore(LogFileAccessMode accessMode) { const string logsDirName = "Logs"; var fileProvider = new MemoryFileProvider(); var filterOptions = new LoggerFilterOptions { MinLevel = LogLevel.Trace }; var options = new FileLoggerOptions { FileAppender = new MemoryFileAppender(fileProvider), BasePath = logsDirName, FileAccessMode = accessMode, FileEncoding = Encoding.UTF8, MaxQueueSize = 100, DateFormat = "yyMMdd", CounterFormat = "000", MaxFileSize = 10, Files = new[] { new LogFileOptions { Path = "<date>/<date:MM>/logger.log", DateFormat = "yyyy", MinLevel = new Dictionary <string, LogLevel> { ["Karambolo.Extensions.Logging.File"] = LogLevel.None, [LogFileOptions.DefaultCategoryName] = LogLevel.Information, } }, new LogFileOptions { Path = "test-<date>-<counter>.log", MinLevel = new Dictionary <string, LogLevel> { ["Karambolo.Extensions.Logging.File"] = LogLevel.Information, [LogFileOptions.DefaultCategoryName] = LogLevel.None, } }, }, TextBuilder = new CustomLogEntryTextBuilder(), IncludeScopes = true, }; var completeCts = new CancellationTokenSource(); var context = new TestFileLoggerContext(completeCts.Token, completionTimeout: Timeout.InfiniteTimeSpan); context.SetTimestamp(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc)); var ex = new Exception(); var provider = new FileLoggerProvider(context, Options.Create(options)); try { using (var loggerFactory = new LoggerFactory(new[] { provider }, filterOptions)) { ILogger <LoggingTest> logger1 = loggerFactory.CreateLogger <LoggingTest>(); logger1.LogInformation("This is a nice logger."); using (logger1.BeginScope("SCOPE")) { logger1.LogWarning(1, "This is a smart logger."); logger1.LogTrace("This won't make it."); using (logger1.BeginScope("NESTED SCOPE")) { ILogger logger2 = loggerFactory.CreateLogger("X"); logger2.LogWarning("Some warning."); logger2.LogError(0, ex, "Some failure!"); } } } } finally { #if NETCOREAPP3_0 await provider.DisposeAsync(); #else await Task.CompletedTask; provider.Dispose(); #endif } Assert.True(provider.Completion.IsCompleted); var logFile = (MemoryFileInfo)fileProvider.GetFileInfo($"{logsDirName}/test-{context.GetTimestamp().ToLocalTime():yyMMdd}-000.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); var lines = logFile.ReadAllText(out Encoding encoding).Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, encoding); Assert.Equal(new[] { $"[info]: {typeof(LoggingTest)}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is a nice logger.", "" }, lines); logFile = (MemoryFileInfo)fileProvider.GetFileInfo($"{logsDirName}/test-{context.GetTimestamp().ToLocalTime():yyMMdd}-001.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); lines = logFile.ReadAllText(out encoding).Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, encoding); Assert.Equal(new[] { $"[warn]: {typeof(LoggingTest)}[1] @ {context.GetTimestamp().ToLocalTime():o}", $" => SCOPE", $" This is a smart logger.", "" }, lines); logFile = (MemoryFileInfo)fileProvider.GetFileInfo( $"{logsDirName}/{context.GetTimestamp().ToLocalTime():yyyy}/{context.GetTimestamp().ToLocalTime():MM}/logger.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); lines = logFile.ReadAllText(out encoding).Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, encoding); Assert.Equal(new[] { $"[warn]: X[0] @ {context.GetTimestamp().ToLocalTime():o}", $" => SCOPE => NESTED SCOPE", $" Some warning.", $"[fail]: X[0] @ {context.GetTimestamp().ToLocalTime():o}", $" => SCOPE => NESTED SCOPE", $" Some failure!", } .Concat(ex.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None)) .Append(""), lines); }
public void LoggingToMemoryUsingFactory() { var fileProvider = new MemoryFileProvider(); var settings = new FileLoggerSettings { FileAppender = new MemoryFileAppender(fileProvider), BasePath = LogsDirName, EnsureBasePath = true, FileEncoding = Encoding.UTF8, MaxQueueSize = 100, DateFormat = "yyyyMMdd", CounterFormat = "000", MaxFileSize = 10, Switches = new Dictionary <string, LogLevel> { { FileLoggerSettingsBase.DefaultCategoryName, LogLevel.Information } }, FileNameMappings = new Dictionary <string, string> { { "Karambolo.Extensions.Logging.File.Test", "test.log" }, { "Karambolo.Extensions.Logging.File", "logger.log" }, }, TextBuilder = new CustomLogEntryTextBuilder(), IncludeScopes = true, }; var cts = new CancellationTokenSource(); var context = new TestFileLoggerContext(cts.Token); var completionTasks = new List <Task>(); context.Complete += (s, e) => completionTasks.Add(e); context.SetTimestamp(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc)); var ex = new Exception(); using (var loggerFactory = new LoggerFactory()) { loggerFactory.AddFile(context, settings); ILogger <LoggingTest> logger1 = loggerFactory.CreateLogger <LoggingTest>(); logger1.LogInformation("This is a nice logger."); using (logger1.BeginScope("SCOPE")) { logger1.LogWarning(1, "This is a smart logger."); logger1.LogTrace("This won't make it."); using (logger1.BeginScope("NESTED SCOPE")) { ILogger logger2 = loggerFactory.CreateLogger("X"); logger2.LogError(0, ex, "Some failure!"); } } // ensuring that all entries are processed cts.Cancel(); Assert.Single(completionTasks); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); } var logFile = (MemoryFileInfo)fileProvider.GetFileInfo($@"{LogsDirName}\test-{context.GetTimestamp().ToLocalTime():yyyyMMdd}-000.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); var lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, logFile.Encoding); Assert.Equal(new[] { $"[info]: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is a nice logger.", "" }, lines); logFile = (MemoryFileInfo)fileProvider.GetFileInfo($@"{LogsDirName}\test-{context.GetTimestamp().ToLocalTime():yyyyMMdd}-001.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, logFile.Encoding); Assert.Equal(new[] { $"[warn]: {typeof(LoggingTest).FullName}[1] @ {context.GetTimestamp().ToLocalTime():o}", $" => SCOPE", $" This is a smart logger.", "" }, lines); logFile = (MemoryFileInfo)fileProvider.GetFileInfo( $@"{LogsDirName}\{Path.ChangeExtension(FallbackFileName, null)}-{context.GetTimestamp().ToLocalTime():yyyyMMdd}-000{Path.GetExtension(FallbackFileName)}"); Assert.True(logFile.Exists && !logFile.IsDirectory); lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, logFile.Encoding); Assert.Equal(new[] { $"[fail]: X[0] @ {context.GetTimestamp().ToLocalTime():o}", $" => SCOPE => NESTED SCOPE", $" Some failure!", } .Concat(ex.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None)) .Append(""), lines); }
public void ReloadSettings() { var fileProvider = new MemoryFileProvider(); var cts = new CancellationTokenSource(); var settings = new FileLoggerSettings { FileAppender = new MemoryFileAppender(fileProvider), Switches = new Dictionary <string, LogLevel> { { FileLoggerSettingsBase.DefaultCategoryName, LogLevel.Information } }, ChangeToken = new CancellationChangeToken(cts.Token) }; var context = new TestFileLoggerContext(); var completionTasks = new List <Task>(); context.Complete += (s, e) => completionTasks.Add(e); context.SetTimestamp(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc)); var otherFileAppender = new MemoryFileAppender(); using (var loggerFactory = new LoggerFactory()) { loggerFactory.AddFile(context, settings); ILogger <LoggingTest> logger1 = loggerFactory.CreateLogger <LoggingTest>(); logger1.LogInformation("This is a nice logger."); // changing text format settings.TextBuilder = new CustomLogEntryTextBuilder(); var newCts = new CancellationTokenSource(); settings.ChangeToken = new CancellationChangeToken(newCts.Token); cts.Cancel(); cts = newCts; Assert.Single(completionTasks); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); logger1.LogInformation("This is a smart logger."); // changing base path, file encoding and filename mapping settings.BasePath = "Logs"; settings.EnsureBasePath = true; settings.FileEncoding = Encoding.Unicode; settings.FileNameMappings = new Dictionary <string, string> { { typeof(LoggingTest).FullName, "test.log" } }; newCts = new CancellationTokenSource(); settings.ChangeToken = new CancellationChangeToken(newCts.Token); cts.Cancel(); cts = newCts; Assert.Equal(2, completionTasks.Count); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); logger1.LogWarning("This goes to another file."); // changing file appender and fallback filename settings.FileAppender = otherFileAppender; settings.FallbackFileName = "test.log"; settings.FileNameMappings = null; newCts = new CancellationTokenSource(); settings.ChangeToken = new CancellationChangeToken(newCts.Token); cts.Cancel(); cts = newCts; Assert.Equal(3, completionTasks.Count); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); logger1.LogWarning("This goes to another file provider."); // ensuring that the entry is processed cts.Cancel(); Assert.Equal(4, completionTasks.Count); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); } var logFile = (MemoryFileInfo)fileProvider.GetFileInfo(LoggingTest.FallbackFileName); Assert.True(logFile.Exists && !logFile.IsDirectory); var lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, logFile.Encoding); Assert.Equal(new[] { $"info: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is a nice logger.", $"[info]: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is a smart logger.", "" }, lines); logFile = (MemoryFileInfo)fileProvider.GetFileInfo($@"Logs\test.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.Unicode, logFile.Encoding); Assert.Equal(new[] { $"[warn]: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This goes to another file.", "" }, lines); logFile = (MemoryFileInfo)otherFileAppender.FileProvider.GetFileInfo($@"Logs\test.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.Unicode, logFile.Encoding); Assert.Equal(new[] { $"[warn]: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This goes to another file provider.", "" }, lines); }
public void ReloadOptionsSettings() { var configJson = $@"{{ '{nameof(ConfigurationFileLoggerSettings.IncludeScopes)}' : true, '{ConfigurationFileLoggerSettings.LogLevelSectionName}': {{ '{FileLoggerSettingsBase.DefaultCategoryName}': '{LogLevel.Trace}', }} }}"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("config.json", configJson, Encoding.UTF8); var cb = new ConfigurationBuilder(); cb.AddJsonFile(fileProvider, "config.json", optional: false, reloadOnChange: true); var config = cb.Build(); var settings = new ConfigurationFileLoggerSettings(config); var cts = new CancellationTokenSource(); var context = new TestFileLoggerContext(cts.Token); var completionTasks = new List <Task>(); context.Complete += (s, e) => completionTasks.Add(e); context.SetTimestamp(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc)); var services = new ServiceCollection(); services.AddOptions(); services.AddLogging(b => b.AddFile(context)); services.Configure <FileLoggerOptions>(config); using (var serviceProvider = services.BuildServiceProvider()) { var loggerFactory = serviceProvider.GetService <ILoggerFactory>(); var logger1 = loggerFactory.CreateLogger <LoggingTest>(); using (logger1.BeginScope("SCOPE")) { logger1.LogInformation("This is a nice logger."); using (logger1.BeginScope("NESTED SCOPE")) { logger1.LogInformation("This is a smart logger."); // changing switch and scopes inclusion configJson = $@"{{ '{ConfigurationFileLoggerSettings.LogLevelSectionName}': {{ '{FileLoggerSettingsBase.DefaultCategoryName}': '{LogLevel.Information}', }} }}"; fileProvider.WriteContent("config.json", configJson); Assert.Equal(1, completionTasks.Count); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); logger1 = loggerFactory.CreateLogger <LoggingTest>(); logger1.LogInformation("This one shouldn't include scopes."); logger1.LogTrace("This one shouldn't be included at all."); } } // ensuring that the entry is processed completionTasks.Clear(); cts.Cancel(); Assert.Equal(1, completionTasks.Count); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); } var logFile = (MemoryFileInfo)context.FileProvider.GetFileInfo($@"fallback.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); var lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, logFile.Encoding); Assert.Equal(lines, new[] { $"info: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" => SCOPE", $" This is a nice logger.", $"info: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" => SCOPE => NESTED SCOPE", $" This is a smart logger.", $"info: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This one shouldn't include scopes.", "" }); }
public void ReloadConfigurationSettings() { var configJson = $@"{{ '{nameof(ConfigurationFileLoggerSettings.MaxFileSize)}' : 10000, '{ConfigurationFileLoggerSettings.LogLevelSectionName}': {{ '{FileLoggerSettingsBase.DefaultCategoryName}': '{LogLevel.Information}', }} }}"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("config.json", configJson, Encoding.UTF8); var cb = new ConfigurationBuilder(); cb.AddJsonFile(fileProvider, "config.json", optional: false, reloadOnChange: true); var config = cb.Build(); var settings = new ConfigurationFileLoggerSettings(config); var cts = new CancellationTokenSource(); var context = new TestFileLoggerContext(cts.Token); var completionTasks = new List <Task>(); context.Complete += (s, e) => completionTasks.Add(e); context.SetTimestamp(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Utc)); using (var loggerFactory = new LoggerFactory()) { loggerFactory.AddFile(context, settings); var logger1 = loggerFactory.CreateLogger <LoggingTest>(); logger1.LogInformation("This is a nice logger."); // changing date format, counter format and max file size configJson = $@"{{ '{nameof(ConfigurationFileLoggerSettings.DateFormat)}' : 'yyyyMMdd', '{nameof(ConfigurationFileLoggerSettings.MaxFileSize)}' : 1, '{nameof(ConfigurationFileLoggerSettings.CounterFormat)}' : '00', '{ConfigurationFileLoggerSettings.LogLevelSectionName}': {{ '{FileLoggerSettingsBase.DefaultCategoryName}': '{LogLevel.Information}', }} }}"; fileProvider.WriteContent("config.json", configJson); Assert.Equal(1, completionTasks.Count); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); logger1.LogInformation("This is a smart logger."); // ensuring that the entry is processed completionTasks.Clear(); cts.Cancel(); Assert.Equal(1, completionTasks.Count); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); } var logFile = (MemoryFileInfo)context.FileProvider.GetFileInfo($@"fallback-0.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); var lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, logFile.Encoding); Assert.Equal(lines, new[] { $"info: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is a nice logger.", "" }); logFile = (MemoryFileInfo)context.FileProvider.GetFileInfo($@"fallback-{context.GetTimestamp().ToLocalTime():yyyyMMdd}-00.log"); Assert.True(logFile.Exists && !logFile.IsDirectory); lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, logFile.Encoding); Assert.Equal(lines, new[] { $"info: {typeof(LoggingTest).FullName}[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is a smart logger.", "" }); }
public void ReloadOptionsSettingsMultipleProviders() { var fileProvider = new MemoryFileProvider(); var fileAppender = new MemoryFileAppender(fileProvider); dynamic settings = new JObject(); dynamic globalFilters = settings[ConfigurationFileLoggerSettings.LogLevelSectionName] = new JObject(); globalFilters[FileLoggerSettingsBase.DefaultCategoryName] = LogLevel.None.ToString(); settings[FileLoggerProvider.Alias] = new JObject(); dynamic fileFilters = settings[FileLoggerProvider.Alias][ConfigurationFileLoggerSettings.LogLevelSectionName] = new JObject(); fileFilters[FileLoggerSettingsBase.DefaultCategoryName] = LogLevel.Warning.ToString(); settings[OtherFileLoggerProvider.Alias] = new JObject(); settings[OtherFileLoggerProvider.Alias][nameof(FileLoggerOptions.FallbackFileName)] = "fallback.log"; dynamic otherFileFilters = settings[OtherFileLoggerProvider.Alias][ConfigurationFileLoggerSettings.LogLevelSectionName] = new JObject(); otherFileFilters[FileLoggerSettingsBase.DefaultCategoryName] = LogLevel.Information.ToString(); var settingsJson = ((JObject)settings).ToString(); fileProvider.CreateFile("config.json", settingsJson); IConfigurationRoot config = new ConfigurationBuilder() .AddJsonFile(fileProvider, "config.json", optional: false, reloadOnChange: true) .Build(); var context = new TestFileLoggerContext(); var completionTasks = new List <Task>(); context.Complete += (s, e) => completionTasks.Add(e); var services = new ServiceCollection(); services.AddOptions(); services.AddLogging(lb => { lb.AddConfiguration(config); lb.AddFile(context, o => o.FileAppender = o.FileAppender ?? fileAppender); lb.AddFile <OtherFileLoggerProvider>(context, o => o.FileAppender = o.FileAppender ?? fileAppender); }); using (ServiceProvider sp = services.BuildServiceProvider()) { ILoggerFactory loggerFactory = sp.GetRequiredService <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger("X"); logger.LogInformation("This is an info."); logger.LogWarning("This is a warning."); fileFilters[FileLoggerSettingsBase.DefaultCategoryName] = LogLevel.Information.ToString(); otherFileFilters[FileLoggerSettingsBase.DefaultCategoryName] = LogLevel.Warning.ToString(); settingsJson = ((JObject)settings).ToString(); fileProvider.WriteContent("config.json", settingsJson); // reload is triggered twice due to a bug in the framework (https://github.com/aspnet/Logging/issues/874) Assert.Equal(2 * 2, completionTasks.Count); Task.WhenAll(completionTasks).GetAwaiter().GetResult(); logger.LogInformation("This is another info."); logger.LogWarning("This is another warning."); } var logFile = (MemoryFileInfo)fileProvider.GetFileInfo(LoggingTest.FallbackFileName); Assert.True(logFile.Exists && !logFile.IsDirectory); var lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, logFile.Encoding); Assert.Equal(new[] { $"warn: X[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is a warning.", $"info: X[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is another info.", $"warn: X[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is another warning.", "" }, lines); logFile = (MemoryFileInfo)fileProvider.GetFileInfo((string)settings[OtherFileLoggerProvider.Alias].FallbackFileName); Assert.True(logFile.Exists && !logFile.IsDirectory); lines = logFile.Content.Split(new[] { Environment.NewLine }, StringSplitOptions.None); Assert.Equal(Encoding.UTF8, logFile.Encoding); Assert.Equal(new[] { $"info: X[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is an info.", $"warn: X[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is a warning.", $"warn: X[0] @ {context.GetTimestamp().ToLocalTime():o}", $" This is another warning.", "" }, lines); }
public async Task Import_Multiple_Imports() { var foo1Content = @"import { myVar1 as var1, myVar2 as var2 } from './bar'; import { default as bazFunc } from './baz'; console.log(bazFunc(var1, var2));"; var foo2Content = @"import * as bar from './bar'; import bazFunc from './baz'; class MyClass { myMethod(bar) { console.log(bazFunc(bar.myVar1, bar.myVar2)); } } new MyClass().myMethod(bar); "; var barContent = @"export var myVar1 = '1'; export let myVar2 = 2; export default 3.14;"; var bazContent = @"export default function MyFunc(a, b) { return a + b; }"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("/bar.js", barContent); fileProvider.CreateFile("/baz.js", bazContent); var foo1File = new ModuleFile(fileProvider, null) { Content = foo1Content }; var foo2File = new ModuleFile(fileProvider, null) { Content = foo2Content }; var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { foo1File, foo2File }, CancellationToken.None); var foo1Lines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "<root0>").Value.Content); Assert.Equal(new[] { "'use strict';", "var __es$module_0 = __es$require(\"/bar.js\");", "var __es$module_1 = __es$require(\"/baz.js\");", "console.log(__es$module_1.default(__es$module_0.myVar1, __es$module_0.myVar2));", }, foo1Lines); var foo2Lines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "<root1>").Value.Content); Assert.Equal(new[] { "'use strict';", "var __es$module_0 = __es$require(\"/bar.js\");", "var __es$module_1 = __es$require(\"/baz.js\");", "class MyClass", "{", " myMethod(bar) {", " console.log(__es$module_1.default(bar.myVar1, bar.myVar2));", " }", "}", "new MyClass().myMethod(__es$module_0);", }, foo2Lines); }
public async Task Import_SpecialPropertiesAndMethods() { var fooContent = @"import { someKey } from './bar'; let o = { someKey, [someKey]: 0 }; o = { someKey() {}, [someKey]() {} }; o = { *someKey() {}, *[someKey]() {} }; o = { get someKey() {}, get [someKey]() {} }; o = { set someKey(_) {}, set [someKey](_) {} }; class C1 { [someKey]() {} get someKey() {} set someKey(_) {} get [someKey]() {} set [someKey](_) {} } class C2 { *someKey() {} *[someKey]() {} } class C3 { static someKey() {} static [someKey]() {} }"; var barContent = @"export const propKey = 'propKey';"; var fileProvider = new MemoryFileProvider(); fileProvider.CreateFile("/bar.js", barContent); var fooFile = new ModuleFile(fileProvider, null) { Content = fooContent }; var moduleBundler = new ModuleBundler(); await moduleBundler.BundleCoreAsync(new[] { fooFile }, CancellationToken.None); var fooLines = GetNonEmptyLines(moduleBundler.Modules.Single(kvp => kvp.Key.FilePath == "<root0>").Value.Content); Assert.Equal(new[] { "'use strict';", "var __es$module_0 = __es$require(\"/bar.js\");", "let o = { someKey: __es$module_0.someKey, [__es$module_0.someKey]: 0 };", "o = { someKey() {}, [__es$module_0.someKey]() {} };", "o = { *someKey() {}, *[__es$module_0.someKey]() {} };", "o = { get someKey() {}, get [__es$module_0.someKey]() {} };", "o = { set someKey(_) {}, set [__es$module_0.someKey](_) {} };", "class C1 { ", " [__es$module_0.someKey]() {}", " get someKey() {}", " set someKey(_) {}", " get [__es$module_0.someKey]() {}", " set [__es$module_0.someKey](_) {}", "}", "class C2 {", " *someKey() {}", " *[__es$module_0.someKey]() {} ", "}", "class C3 {", " static someKey() {}", " static [__es$module_0.someKey]() {} ", "}", }, fooLines); }