public async Task HourShifter_ShiftsDateTakenExifValue() { Options options = new Options { Hours = 1, CurrentDirectoryOnly = false, Quiet = true }; IFileLoader fileLoader = new FileLoader(options, Directory.GetCurrentDirectory()); IHourShifter hourShifter = new HourShifter.HourShifter(options, fileLoader); ProgramBootstrap programBootstrap = new ProgramBootstrap(hourShifter); DateTime originalDateTime = await getJpgDateTaken(sampleJpgFile); Assert.Multiple(async() => { int?exitCode = null; Assert.That(async() => { exitCode = await programBootstrap.Run(); }, Throws.Nothing); DateTime newDateTime = await getJpgDateTaken(sampleJpgFile); Assert.That(originalDateTime != newDateTime); Assert.That(originalDateTime.AddHours(1) == newDateTime); Assert.That(exitCode.HasValue); Assert.That(exitCode.Value, Is.Zero); }); }
public App() { System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; /* * .net core (and .net 5) changed the way assembly and type resolving work. * Preferred way to implement "plugins" is using custom AssemblyLoadContext per plugin * however, current Prism implementation is not AssemblyLoadContext friendly * Therefore this workaround make assembly loading work more or less like in .net framework * All assemblies are loaded to the default context and any type can be found via Type.GetType() * * The disadvantage is that assemblies cannot conflict with each other. If using AssemblyLoadContext * there would be no problem with for instance different versions of a package. */ Dictionary <string, string> assemblyToRequesting = new(); string?executingAssemblyLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { if (args.Name.EndsWith("resources") || args.RequestingAssembly == null) { return(null); } AssemblyName?name = new(args.Name); string?requestingAssemblyPath = executingAssemblyLocation + "/" + args.RequestingAssembly.GetName().Name + ".dll"; if (!File.Exists(requestingAssemblyPath)) { if (!assemblyToRequesting.TryGetValue(args.RequestingAssembly.GetName().Name ?? "", out requestingAssemblyPath)) { return(null); } } assemblyToRequesting.Add(name.Name ?? "", requestingAssemblyPath); AssemblyDependencyResolver?dependencyPathResolver = new(requestingAssemblyPath); string?path = dependencyPathResolver.ResolveAssemblyToPath(name); if (path == null) { return(null); } if (AssemblyLoadContext.Default.Assemblies.FirstOrDefault(t => t.GetName() == name) != null) { return(AssemblyLoadContext.Default.Assemblies.FirstOrDefault(t => t.GetName() == name)); } return(AssemblyLoadContext.Default.LoadFromAssemblyPath(path)); }; if (ProgramBootstrap.TryLaunchUpdaterIfNeeded()) { Current.Shutdown(); } }
public void ProgramBootstrap_Run_ReturnsFailure() { Mock <IHourShifter> mock = new Mock <IHourShifter>(); mock .Setup(m => m.Shift().Result) .Throws(new Exception()) .Verifiable(); ProgramBootstrap programBootstrap = new ProgramBootstrap(mock.Object); Assert.Multiple(() => { int?exitCode = null; Assert.That(async() => { exitCode = await programBootstrap.Run(); }, Throws.Nothing); Assert.That(exitCode.HasValue); Assert.That(exitCode.Value, Is.EqualTo(Constants.FAILURE_EXIT_CODE)); mock.Verify(m => m.Shift(), Times.Once); }); }
// Initialization code. Don't use any Avalonia, third-party APIs or any // SynchronizationContext-reliant code before AppMain is called: things aren't initialized // yet and stuff might break. public static void Main(string[] args) { FixCurrentDirectory(); if (ProgramBootstrap.TryLaunchUpdaterIfNeeded()) { return; } System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; var app = BuildAvaloniaApp(); try { app.StartWithClassicDesktopLifetime(args); } catch (Exception e) { FatalErrorHandler.ExceptionOccured(e); } }
// Initialization code. Don't use any Avalonia, third-party APIs or any // SynchronizationContext-reliant code before AppMain is called: things aren't initialized // yet and stuff might break. public static void Main(string[] args) { FixCurrentDirectory(); if (ProgramBootstrap.TryLaunchUpdaterIfNeeded()) { return; } System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; SafeFireAndForgetExtensions.SetDefaultExceptionHandling(Console.WriteLine); GlobalApplication.Arguments.Init(args); var app = BuildAvaloniaApp(); try { app.StartWithClassicDesktopLifetime(args); } catch (Exception e) { FatalErrorHandler.ExceptionOccured(e); } }