From 3f54b57dd47f6d7722491130b748ff5c398c3074 Mon Sep 17 00:00:00 2001 From: Baudin Date: Mon, 23 Dec 2019 07:44:09 +0100 Subject: [PATCH] Fixing the problems with the test of the Applications --- ApplicationTests/ApplicationTests.csproj | 5 + ApplicationTests/BaseApplicationTest.cs | 41 ++++ ApplicationTests/CreateModuleInProject.cs | 51 ++-- ApplicationTests/DeleteModuleInproject.cs | 42 ++++ ApplicationTests/ModuleStream_tests.cs | 4 +- ApplicationTests/MoveModuleInProject.cs | 35 +++ ApplicationTests/ParseMultipleFiles.cs | 58 ++--- ApplicationTests/ProjectFileWatcher.cs | 51 +--- ApplicationTests/SchoolExampleTest.cs | 87 +++++++ ApplicationTests/xunit.runner.json | 4 + CLI/CLI.csproj | 1 + CLI/Commands/Commands.Serve.cs | 5 +- CLI/Commands/Commands.Watch.cs | 7 +- CLI/Controllers/JsonDataController.cs | 3 +- CLI/Controllers/LexiconDataController.cs | 5 +- CLI/Controllers/ModuleController.cs | 35 ++- CLI/Controllers/RemoteController.cs | 3 +- CLI/Controllers/TopologyController.cs | 4 +- CLI/Database.cs | 2 +- CLI/Project.cs | 207 ----------------- CLI/WebServer.cs | 56 ++++- CLI/wwwroot/build/bundle.css | 4 +- CLI/wwwroot/build/bundle.css.map | 10 +- CLI/wwwroot/build/bundle.js | 2 +- CLI/wwwroot/build/bundle.js.map | 2 +- CLI/wwwroot/global.css | 58 ++--- .../FileProject.Network.cs | 6 +- .../FileProject.Watch.cs | 28 +-- Project/FileProject.cs | 217 ++++++++++++++++++ Project/IProject.cs | 28 +++ {CLI => Project}/ImportResolver.cs | 4 +- {CLI => Project}/Models/Topology.cs | 2 +- {CLI => Project}/Module.cs | 44 +++- {CLI => Project}/ModuleStream.cs | 18 +- {CLI => Project}/ModuleStreamMessage.cs | 5 +- Project/Project.csproj | 25 ++ .../ProjectFilesWatcher.cs | 2 +- {CLI => Project}/Transpiler.cs | 6 +- ZDragon.NET.sln | 6 + 39 files changed, 747 insertions(+), 426 deletions(-) create mode 100644 ApplicationTests/BaseApplicationTest.cs create mode 100644 ApplicationTests/DeleteModuleInproject.cs create mode 100644 ApplicationTests/MoveModuleInProject.cs create mode 100644 ApplicationTests/SchoolExampleTest.cs create mode 100644 ApplicationTests/xunit.runner.json delete mode 100644 CLI/Project.cs rename CLI/Project.Network.cs => Project/FileProject.Network.cs (96%) rename CLI/Project.Watch.cs => Project/FileProject.Watch.cs (69%) create mode 100644 Project/FileProject.cs create mode 100644 Project/IProject.cs rename {CLI => Project}/ImportResolver.cs (96%) rename {CLI => Project}/Models/Topology.cs (98%) rename {CLI => Project}/Module.cs (83%) rename {CLI => Project}/ModuleStream.cs (81%) rename {CLI => Project}/ModuleStreamMessage.cs (95%) create mode 100644 Project/Project.csproj rename CLI/ProjectWatcher.cs => Project/ProjectFilesWatcher.cs (99%) rename {CLI => Project}/Transpiler.cs (95%) diff --git a/ApplicationTests/ApplicationTests.csproj b/ApplicationTests/ApplicationTests.csproj index bd8d908..f8065c9 100644 --- a/ApplicationTests/ApplicationTests.csproj +++ b/ApplicationTests/ApplicationTests.csproj @@ -24,4 +24,9 @@ + + + PreserveNewest + + diff --git a/ApplicationTests/BaseApplicationTest.cs b/ApplicationTests/BaseApplicationTest.cs new file mode 100644 index 0000000..5ece634 --- /dev/null +++ b/ApplicationTests/BaseApplicationTest.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Project; +using Xunit.Abstractions; + +namespace ApplicationTests +{ + public class BaseFileWatcherTest : IDisposable + { + protected readonly ITestOutputHelper output; + protected readonly string dir; + protected readonly FileProject project; + + public BaseFileWatcherTest(ITestOutputHelper _output, string _dir) + { + dir = Path.GetFullPath(_dir, Directory.GetCurrentDirectory()); + Console.WriteLine("STARTING: " + dir); + if (Directory.Exists(dir)) + { + Directory.Delete(dir, true); + } + Directory.CreateDirectory(dir); + output = _output; + project = new FileProject(dir); + project.Watch(); + } + + public void Dispose() + { + project.Dispose(); + Directory.Delete(dir, true); + Console.WriteLine("CLEANUP: " + dir); + } + + protected string path(string add) + { + return Path.GetFullPath(add, dir); + } + } +} diff --git a/ApplicationTests/CreateModuleInProject.cs b/ApplicationTests/CreateModuleInProject.cs index 715fd7f..5c6a32a 100644 --- a/ApplicationTests/CreateModuleInProject.cs +++ b/ApplicationTests/CreateModuleInProject.cs @@ -1,54 +1,33 @@ using System; using System.Diagnostics; using System.IO; +using System.Threading.Tasks; using CLI; +using Project; using Xunit; +using Xunit.Abstractions; namespace ApplicationTests { - public class CreateModuleInProject: IDisposable + public class CreateModuleInProject : BaseFileWatcherTest { - readonly string dir = Path.GetFullPath("CreateModuleInProject", Directory.GetCurrentDirectory()); - readonly Project project; - public CreateModuleInProject() + public CreateModuleInProject(ITestOutputHelper output) : base(output, "CreateModuleInProject") { } + + [Fact] + public async Task CreateModule() { try { - Directory.Delete(dir, true); + var module = await project.CreateModule("Test"); + Assert.True(File.Exists(path("Test.car"))); + Assert.NotNull(module); + Assert.Equal("Test", module.Name); + Assert.Equal(this.path("Test.car"), module.FilePath); } - catch (Exception) + catch (Exception ex) { - Debug.WriteLine("Delete Directory failed in unit test."); + Console.WriteLine(dir + ": " + ex.Message); } - Directory.CreateDirectory(dir); - project = new Project(dir); - } - - [Fact] - public void CreateModule() - { - project.CreateModule("Test"); - Assert.True(File.Exists(path("Test.car"))); - - /* - * Modules are not automatically parsed and added to the project - * when they are created. This gives you the option of using the - * CLI as a very very simple "build my files" type of solution. - */ - var module = project.FindModule("Test"); - Assert.Null(module); - } - - - public void Dispose() - { - project.Dispose(); - //Directory.Delete(dir, true); - } - - private string path(string add) - { - return Path.GetFullPath(add, dir); } } } diff --git a/ApplicationTests/DeleteModuleInproject.cs b/ApplicationTests/DeleteModuleInproject.cs new file mode 100644 index 0000000..362a14b --- /dev/null +++ b/ApplicationTests/DeleteModuleInproject.cs @@ -0,0 +1,42 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using CLI; +using Project; +using Xunit; +using Xunit.Abstractions; + +namespace ApplicationTests +{ + public class DeleteModuleInproject : BaseFileWatcherTest + { + public DeleteModuleInproject(ITestOutputHelper output) : base(output, "DeleteModuleInproject") { } + + [Fact] + public async Task CreateModule() + { + try + { + var module = await project.CreateModule("Test"); + var filePath = module.FilePath.Clone().ToString(); + var outPath = module.OutPath.Clone().ToString(); + + Assert.True(File.Exists(path("Test.car"))); + Assert.NotNull(module); + Assert.Equal("Test", module.Name); + Assert.Equal(this.path("Test.car"), module.FilePath); + + var deleteResult = await project.DeleteModule("Test"); + + await Task.Delay(100); + Assert.True(deleteResult); + Assert.False(File.Exists(filePath)); + Assert.False(Directory.Exists(outPath)); + } catch (Exception ex) + { + Console.WriteLine(dir + ": " + ex.Message); + } + } + } +} diff --git a/ApplicationTests/ModuleStream_tests.cs b/ApplicationTests/ModuleStream_tests.cs index e774c72..520dd4f 100644 --- a/ApplicationTests/ModuleStream_tests.cs +++ b/ApplicationTests/ModuleStream_tests.cs @@ -1,6 +1,6 @@ using System; using System.Threading.Tasks; -using CLI; +using Project; using Xunit; namespace ApplicationTests @@ -12,6 +12,7 @@ public class ModuleStream_tests : IDisposable public ModuleStream_tests() { + Console.WriteLine("STARTING: ModuleStream"); moduleStream = new ModuleStream(); } @@ -37,6 +38,7 @@ public Task CreateModuleStream() public void Dispose() { moduleStream.Dispose(); + Console.WriteLine("CLEANUP: ModuleStream"); } } } diff --git a/ApplicationTests/MoveModuleInProject.cs b/ApplicationTests/MoveModuleInProject.cs new file mode 100644 index 0000000..a60e2bd --- /dev/null +++ b/ApplicationTests/MoveModuleInProject.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace ApplicationTests +{ + public class MoveModuleInProject : BaseFileWatcherTest + { + public MoveModuleInProject(ITestOutputHelper output) : base(output, "MoveModuleInProject") { } + + [Fact] + public async Task MoveModule() + { + try + { + var module = await project.CreateModule("Test"); + Assert.True(File.Exists(path("Test.car"))); + Assert.NotNull(module); + Assert.Equal("Test", module.Name); + Assert.Equal(this.path("Test.car"), module.FilePath); + + var newModule = await project.MoveModule(module.Name, "Other"); + var oldModule = project.FindModule("Test"); + Assert.Null(oldModule); + Assert.NotNull(newModule); + } + catch (Exception ex) + { + Console.WriteLine(dir + ": " + ex.Message); + } + } + } +} diff --git a/ApplicationTests/ParseMultipleFiles.cs b/ApplicationTests/ParseMultipleFiles.cs index c969258..424a7a6 100644 --- a/ApplicationTests/ParseMultipleFiles.cs +++ b/ApplicationTests/ParseMultipleFiles.cs @@ -1,60 +1,42 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading.Tasks; -using CLI; +using Project; using Xunit; using Xunit.Abstractions; namespace ApplicationTests { - public class ParseMultipleFiles : IDisposable + public class ParseMultipleFiles : BaseFileWatcherTest { - - private readonly string dir = Path.GetFullPath("ParseMultipleFiles", Directory.GetCurrentDirectory()); - private readonly Project project; - public ParseMultipleFiles() + + public ParseMultipleFiles(ITestOutputHelper output) : base(output, "ParseMultipleFiles") { } + + [Fact] + public async Task Execute() { try { - Directory.Delete(dir, true); - } catch (Exception) { - Debug.WriteLine("Delete Directory failed in unit test."); - } - Directory.CreateDirectory(dir); - File.WriteAllText(path("First.car"), @"# The first document + var tasks = new List(); + tasks.Add(project.CreateModule("First", @"# The first document type Person -"); - File.WriteAllText(path("Second.car"), @" +")); + tasks.Add(project.CreateModule("Second", @" open Person # The second document type School -"); - - project = new Project(dir); - } - - [Fact] -#pragma warning disable IDE0051 // Remove unused private members - private void CreateModule() -#pragma warning restore IDE0051 // Remove unused private members - { - Assert.Equal(2, project.Modules.Count); - var second = project.FindModule("Second"); - Assert.Equal(3, second.Generator.AST.Count); - } - - - public void Dispose() - { - project.Dispose(); - Directory.Delete(dir, true); +")); + await Task.WhenAll(tasks.ToArray()); + Assert.Equal(2, project.Modules.Count); + } + catch (Exception ex) + { + Console.WriteLine(dir + ": " + ex.Message); + } } - private string path(string add) - { - return Path.GetFullPath(add, dir); - } } } diff --git a/ApplicationTests/ProjectFileWatcher.cs b/ApplicationTests/ProjectFileWatcher.cs index 96f2380..15b3b60 100644 --- a/ApplicationTests/ProjectFileWatcher.cs +++ b/ApplicationTests/ProjectFileWatcher.cs @@ -3,56 +3,29 @@ using System.IO; using System.Threading.Tasks; using CLI; +using Project; using Xunit; using Xunit.Abstractions; namespace ApplicationTests { - public class ProjectFileWatcher: IDisposable + public class ProjectFileWatcher : BaseFileWatcherTest { - private readonly ITestOutputHelper output; - private readonly string dir = Path.GetFullPath("ProjectFileWatcher", Directory.GetCurrentDirectory()); - private readonly Project project; - public ProjectFileWatcher(ITestOutputHelper output) + + public ProjectFileWatcher(ITestOutputHelper output) : base(output, "ProjectFileWatcher") { } + + [Fact] + public async Task CreateModule() { try { - Directory.Delete(dir, true); - } catch (Exception) { - Debug.WriteLine("Delete Directory failed in unit test."); + await project.CreateModule("Test"); + Assert.True(File.Exists(path("Test.car"))); } - Directory.CreateDirectory(dir); - - this.output = output; - project = new Project(dir); - Task.Run(() => + catch (Exception ex) { - project.Watch(); - }); - - - } - - [Fact] -#pragma warning disable IDE0051 // Remove unused private members - private void CreateModule() -#pragma warning restore IDE0051 // Remove unused private members - { - project.CreateModule("Test"); - Assert.True(File.Exists(path("Test.car"))); - } - - - public void Dispose() - { - output.WriteLine("q"); - project.Dispose(); - Directory.Delete(dir, true); - } - - private string path(string add) - { - return Path.GetFullPath(add, dir); + Console.WriteLine(dir + ": " + ex.Message); + } } } } diff --git a/ApplicationTests/SchoolExampleTest.cs b/ApplicationTests/SchoolExampleTest.cs new file mode 100644 index 0000000..1e6a51f --- /dev/null +++ b/ApplicationTests/SchoolExampleTest.cs @@ -0,0 +1,87 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Xunit; +using Xunit.Abstractions; + +namespace ApplicationTests +{ + public class SchoolExampleTest : BaseFileWatcherTest + { + public SchoolExampleTest(ITestOutputHelper output) : base(output, "SchoolExample") { } + + private async Task Init() + { + await project.CreateModule("School", @" +# School + +This is a paragraph! + +type School + +type Student + +type Teacher +"); + } + + [Fact] + public async Task InitModule() + { + try + { + await Init(); + var module = project.FindModule("School"); + Assert.True(File.Exists(path("School.car"))); + Assert.NotNull(module); + Assert.Equal("School", module.Name); + Assert.Equal(this.path("School.car"), module.FilePath); + } + catch (Exception ex) + { + Console.WriteLine(dir + ": " + ex.Message); + } + } + + [Fact] + public async Task CompileSchoolModule() + { + await Init(); + project.ParseAllModules(); + var ast = project.GetAstForModule("School"); + Assert.True(ast.Count > 0); + } + + [Fact] + public async Task RenameSchoolModule() + { + await Init(); + await project.MoveModule("School", "Foo.Bar"); + Assert.False(File.Exists(path("School.car")), "School.car file still exists."); + Assert.True(File.Exists(path("Foo/Bar.car")), "Foo/Bar.car file does not exits"); + + Assert.Null(project.FindModule("School")); + Assert.NotNull(project.FindModule("Foo.Bar")); + } + + [Fact] + public async Task AddStudentModule() + { + await Init(); + var studentModule = await project.CreateModule("Student"); + var schoolModule = project.FindModule("School"); + + Assert.NotNull(studentModule); + Assert.NotNull(schoolModule); + } + + [Fact] + public async Task DeleteSchoolModule() + { + await Init(); + await project.DeleteModule("School"); + var schoolModule = project.FindModule("School"); + Assert.Null(schoolModule); + } + } +} diff --git a/ApplicationTests/xunit.runner.json b/ApplicationTests/xunit.runner.json new file mode 100644 index 0000000..7b7ad2a --- /dev/null +++ b/ApplicationTests/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "parallelizeTestCollections": false +} \ No newline at end of file diff --git a/CLI/CLI.csproj b/CLI/CLI.csproj index 9fd5e16..a29fd39 100644 --- a/CLI/CLI.csproj +++ b/CLI/CLI.csproj @@ -18,6 +18,7 @@ + diff --git a/CLI/Commands/Commands.Serve.cs b/CLI/Commands/Commands.Serve.cs index b32950e..14c294a 100644 --- a/CLI/Commands/Commands.Serve.cs +++ b/CLI/Commands/Commands.Serve.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Threading.Tasks; +using CLI.Signals; using Microsoft.Extensions.CommandLineUtils; namespace CLI.Commands @@ -31,7 +32,9 @@ To quit the application press 'q' true => fileOption.Value() }; - var project = new Project(directory); + var project = new Project.FileProject(directory); + SignalSingleton.ExitSignal.Subscribe(project.Dispose); + WebServer.Start(project.OutPath); // Wait for the user to quit the program. diff --git a/CLI/Commands/Commands.Watch.cs b/CLI/Commands/Commands.Watch.cs index e9b667b..6b673db 100644 --- a/CLI/Commands/Commands.Watch.cs +++ b/CLI/Commands/Commands.Watch.cs @@ -29,16 +29,15 @@ public static void CreateWatchCommand(CommandLineApplication app) command.OnExecute(() => { - Console.WriteLine(@" -To quit the application press 'q' -"); + Console.WriteLine("\nTo quit the application press 'q'"); var directory = fileOption.HasValue() switch { false => Directory.GetCurrentDirectory(), true => fileOption.Value() }; - var project = new Project(directory); + var project = new Project.FileProject(directory); + SignalSingleton.ExitSignal.Subscribe(project.Dispose); Task? webserverTask = null; if (serve.HasValue()) diff --git a/CLI/Controllers/JsonDataController.cs b/CLI/Controllers/JsonDataController.cs index 666ae48..8c2340d 100644 --- a/CLI/Controllers/JsonDataController.cs +++ b/CLI/Controllers/JsonDataController.cs @@ -3,6 +3,7 @@ using System.Dynamic; using System.Linq; using Bogus; +using Project; using Compiler.AST; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; @@ -18,7 +19,7 @@ public class JsonDataController : ControllerBase public IActionResult GetData(string module, string type, [FromQuery]bool list) { - Module = Project.Current?.Modules.First(m => m.Name == module); + Module = Project.FileProject.Current?.Modules.First(m => m.Name == module); var result = list ? new Faker().Make(10, () => Generate(type)) : Generate(type); if (result is null) { diff --git a/CLI/Controllers/LexiconDataController.cs b/CLI/Controllers/LexiconDataController.cs index ec2cf87..a378b2b 100644 --- a/CLI/Controllers/LexiconDataController.cs +++ b/CLI/Controllers/LexiconDataController.cs @@ -3,6 +3,7 @@ using CLI.Models; using LiteDB; using Microsoft.AspNetCore.Mvc; +using Project; namespace CLI.Controllers { @@ -41,7 +42,7 @@ public void Delete([FromBody]LexiconEntry entry) [HttpGet("/api/lexicon/config")] public IActionResult ConfigurationData() { - var project = Project.Current; + var project = FileProject.Current; if (project is null) return NotFound(); #pragma warning disable CS8602 // Dereference of a possibly null reference. else return Ok(project.CarConfig.LexiconConfig); @@ -52,7 +53,7 @@ public IActionResult ConfigurationData() [HttpGet("/api/lexicon/remote")] public IActionResult GetRemoteLexiconData() { - var config = Project.Current?.CarConfig; + var config = FileProject.Current?.CarConfig; if (config is null) return NotFound(); else { diff --git a/CLI/Controllers/ModuleController.cs b/CLI/Controllers/ModuleController.cs index b569a54..ba3cccd 100644 --- a/CLI/Controllers/ModuleController.cs +++ b/CLI/Controllers/ModuleController.cs @@ -7,6 +7,7 @@ using Mapper.Application; using Mapper.HTML; using Microsoft.AspNetCore.Mvc; +using Project; namespace CLI.Controllers { @@ -16,28 +17,26 @@ public class ModuleController : ControllerBase [HttpGet("/api/modules")] public IEnumerable GetModules() { - return Project.Current?.Modules.Select(m => m.Name) ?? Enumerable.Empty(); + return FileProject.Current?.Modules.Select(m => m.Name) ?? Enumerable.Empty(); } [HttpPost("/api/modules/{name}")] - public IActionResult CreateModule(string name) + public async Task CreateModuleAsync(string name) { - var module = Project.Current?.FindModule(name); - if (module != null) + var checkModule = FileProject.Current?.FindModule(name); + if (checkModule != null) { return BadRequest($"Module: {name}, already exists and cannot be created."); } +#pragma warning disable CS8602 // Dereference of a possibly null reference. + var module = await FileProject.Current?.CreateModule(name); +#pragma warning restore CS8602 // Dereference of a possibly null reference. + + if (module is null) return BadRequest($"Failed to created module {name}."); - Project.Current?.CreateModule(name); return Ok(new List { - new Descriptor(name) - { - Module = name, - Description = "Your newly created module!", - Name = name, - DescriptorType = DescriptorType.Module.ToString("g") - } + module.ToDescriptor("Your newly created module") }); } @@ -45,7 +44,7 @@ public IActionResult CreateModule(string name) public IEnumerable Search(string param) { - var moduleDescriptions = Project.Current?.Modules.Select(m => + var moduleDescriptions = FileProject.Current?.Modules.Select(m => { return new Descriptor(m.Name) { @@ -61,7 +60,7 @@ public IEnumerable Search(string param) return moduleDescriptions; } - var descriptors = Project + var descriptors = FileProject .Current? .Modules .SelectMany(m => m.GetDescriptions()); @@ -77,7 +76,7 @@ public IEnumerable Search(string param) public IActionResult RenderDescriptor([FromQuery]Descriptor descriptor) { - var module = Project.Current?.Modules.FirstOrDefault(m => m.Name == descriptor.Module); + var module = Project.FileProject.Current?.Modules.FirstOrDefault(m => m.Name == descriptor.Module); var node = module?.Transpiler.AST.FirstOrDefault(a => a is INamable && ((INamable)a).Name == descriptor.Name); if (node is null) return NotFound(descriptor); @@ -90,7 +89,7 @@ public IActionResult RenderDescriptor([FromQuery]Descriptor descriptor) [HttpGet("/api/module/{module}")] public IActionResult GetModuleText(string module) { - var m = Project.Current?.FindModule(module); + var m = FileProject.Current?.FindModule(module); if (m is null) return NotFound(); return Ok(m.Code); @@ -99,7 +98,7 @@ public IActionResult GetModuleText(string module) [HttpPost("/api/module/{module}")] public async Task SaveModuleTextAsync(string module) { - var m = Project.Current?.FindModule(module); + var m = FileProject.Current?.FindModule(module); if (m is null) @@ -122,7 +121,7 @@ public async Task SaveModuleTextAsync(string module) [HttpGet("/api/module/{module}/errors")] public IActionResult GetModuleErrors(string module) { - var m = Project.Current?.FindModule(module); + var m = FileProject.Current?.FindModule(module); if (m is null) return NotFound(); return Ok(m.Generator.Errors); } diff --git a/CLI/Controllers/RemoteController.cs b/CLI/Controllers/RemoteController.cs index 86406df..cf5b714 100644 --- a/CLI/Controllers/RemoteController.cs +++ b/CLI/Controllers/RemoteController.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using CLI.Models; using Microsoft.AspNetCore.Mvc; +using Project; namespace CLI.Controllers { @@ -12,7 +13,7 @@ public class RemoteController : ControllerBase [HttpGet("/api/remote/module/{module}")] public async Task GetModuleText(string module) { - var project = Project.Current; + var project = FileProject.Current; if (project is null) return NotFound(); var url = project.CarConfig?.Remote + "/api/module/" + module; diff --git a/CLI/Controllers/TopologyController.cs b/CLI/Controllers/TopologyController.cs index 21815eb..4d21ed6 100644 --- a/CLI/Controllers/TopologyController.cs +++ b/CLI/Controllers/TopologyController.cs @@ -10,7 +10,7 @@ public class TopologyController: ControllerBase [HttpGet("/api/topology")] public IActionResult GetTopology() { - var topology = Project.Current?.GetTopology(true); + var topology = Project.FileProject.Current?.GetTopology(true); if (topology is null) return NoContent(); else return Ok(topology); } @@ -18,7 +18,7 @@ public IActionResult GetTopology() [HttpGet("/api/topology/modules")] public IActionResult GetTopologyModules() { - var topology = Project.Current?.GetTopology(false); + var topology = Project.FileProject.Current?.GetTopology(false); if (topology is null) return NoContent(); else return Ok(topology); } diff --git a/CLI/Database.cs b/CLI/Database.cs index f235462..e8c40d4 100644 --- a/CLI/Database.cs +++ b/CLI/Database.cs @@ -9,7 +9,7 @@ namespace CLI { public static class Database { - private static string path = Path.Combine(Project.Current?.OutPath ?? "", "Lexicon.db"); + private static string path = Path.Combine(Project.FileProject.Current?.OutPath ?? "", "Lexicon.db"); private static ConnectionString ConnectionString() { var connectionString = new ConnectionString(path); diff --git a/CLI/Project.cs b/CLI/Project.cs deleted file mode 100644 index 52e92db..0000000 --- a/CLI/Project.cs +++ /dev/null @@ -1,207 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using CLI.Signals; -using Compiler.AST; -using Configuration; - -namespace CLI -{ - public partial class Project : IDisposable - { - - public static Project? Current { get; private set; } - - /// - /// The Directory in which the project is created. This is the root path, - /// the path where the zdragon.json file is located. - /// - public string BasePath { get; } = ""; - - /// - /// Where the assets, the results are published to. - /// - public string OutPath { get; } = ""; - - /// - /// Where the zdragon.json file is located. - /// - public string ConfigPath { get; } = ""; - - - public CarConfig CarConfig { get; private set; } - public ObservableCollection Modules { get; } = new ObservableCollection(); - - public Project(string path) - { - this.BasePath = path; - this.OutPath = Path.GetFullPath($"out", this.BasePath); - this.ConfigPath = Path.GetFullPath("zdragon.json", this.BasePath); - this.CarConfig = CarConfig.Load(this.ConfigPath); - - Directory.CreateDirectory(OutPath); - - var allfiles = Directory.GetFiles(path, "*.car", SearchOption.AllDirectories); - foreach (var file in allfiles) - { - var module = new Module(file, path, this); - Modules.Add(module); - module.Parse(); - } - - CreateAssets(); - - Project.Current = this; - - SignalSingleton.ExitSignal.Subscribe(() => - { - Console.WriteLine("Disposing of the project..."); - Project.Current = null; - foreach (Module m in this.Modules) - { - m.Dispose(); - } - this.Dispose(); - }); - - Task.Run(Parse); - } - - public void Parse() - { - foreach (var module in this.Modules) - { - module.Parse(); - module.SaveModuleOutput(false); - } - } - - private void CreateAssets() - { - Helpers.ReadAndWriteAsset("mermaid.min.js", this.OutPath); - Helpers.ReadAndWriteAsset("mermaid.min.js.map", this.OutPath); - } - - public void CreateModule(string name) - { - - var fileName = String.Join("/", name.Split(".").Select(UppercaseFirst)) + ".car"; - var modulePath = System.IO.Path.GetFullPath(fileName, this.BasePath); - var directoryName = System.IO.Path.GetDirectoryName(modulePath); - Directory.CreateDirectory(directoryName); - try - { - using (var fs = new FileStream(modulePath, FileMode.CreateNew, FileAccess.Write, FileShare.ReadWrite)) - { - using (var sr = new StreamWriter(fs)) - { - sr.Write($@" -# {name} - -Have fun with your module! - - -"); - sr.Flush(); - sr.Close(); - sr.Dispose(); - } - fs.Close(); - fs.Dispose(); - - return; - } - throw new IOException("ReadModule failed with unknown exception."); - } - catch (IOException ioe) - { - Console.WriteLine("ReadModuleText: Caught Exception reading file [{0}]", ioe); - throw ioe; - } - } - - internal List GetAstForModule(string moduleName) - { - var module = Modules.FirstOrDefault(m => m.Name == moduleName); - if (module is null) - { - return new List(); - } - else - { - if (module.Generator is null) - { - module.Parse(); - } - return module?.Generator?.AST ?? new List(); - } - } - - public Module? FindModule(string name) - { - return this.Modules.FirstOrDefault(m => m.Name == name); - } - - - - public void Dispose() - { - - } - - private static class Helpers - { - public static string ReadAsset(string name) - { - var assembly = Assembly.GetExecutingAssembly(); - var resourceName = "CLI.Assets." + name; - - using (var stream = assembly.GetManifestResourceStream(resourceName)) - { - if (!(stream is null)) - { - using (var reader = new StreamReader(stream)) - { - var result = reader.ReadToEnd(); - reader.Close(); - reader.Dispose(); - return result; - } - } - else - { - return ""; - } - } - } - - public static void WriteAsset(string path, string content) - { - File.WriteAllText(path, content); - } - - public static void ReadAndWriteAsset(string assetName, string outPath) - { - var outName = System.IO.Path.GetFullPath(assetName, outPath); - Helpers.WriteAsset(outName, Helpers.ReadAsset(assetName)); - } - } - - static string UppercaseFirst(string s) - { - // Check for empty string. - if (string.IsNullOrEmpty(s)) - { - return string.Empty; - } - // Return char and concat substring. - return char.ToUpper(s[0]) + s.Substring(1); - } - } - -} diff --git a/CLI/WebServer.cs b/CLI/WebServer.cs index 6a2cef0..96d88d2 100644 --- a/CLI/WebServer.cs +++ b/CLI/WebServer.cs @@ -1,11 +1,13 @@ using System.Diagnostics; using System.IO; +using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Project; namespace CLI { @@ -14,13 +16,19 @@ public static class WebServer public static string RootPath = ""; public static Task Start(string rootPath) { - var portNumber = Project.Current?.CarConfig?.PortNumber ?? "5000"; + var portNumber = FileProject.Current?.CarConfig?.PortNumber ?? "5000"; RootPath = rootPath; Task.Run(async () => { await Task.Delay(1500); WebServer.OpenBrowser($"http://localhost:{portNumber}/index.html"); }); + + if (FileProject.Current != null) + { + WebServer.CreateAssets(FileProject.Current.OutPath); + } + return Task.Run(() => { System.Console.WriteLine($@" @@ -64,5 +72,51 @@ public static void OpenBrowser(string url) } } + + private static void CreateAssets(string outPath) + { + Helpers.ReadAndWriteAsset("mermaid.min.js", outPath); + Helpers.ReadAndWriteAsset("mermaid.min.js.map", outPath); + } + + private static class Helpers + { + public static string ReadAsset(string name) + { + var assembly = Assembly.GetExecutingAssembly(); + var resourceName = "CLI.Assets." + name; + + using (var stream = assembly.GetManifestResourceStream(resourceName)) + { + if (!(stream is null)) + { + using (var reader = new StreamReader(stream)) + { + var result = reader.ReadToEnd(); + reader.Close(); + reader.Dispose(); + return result; + } + } + else + { + return ""; + } + } + } + + public static void WriteAsset(string path, string content) + { + File.WriteAllText(path, content); + } + + public static void ReadAndWriteAsset(string assetName, string outPath) + { + var outName = System.IO.Path.GetFullPath(assetName, outPath); + Helpers.WriteAsset(outName, Helpers.ReadAsset(assetName)); + } + } } + + } \ No newline at end of file diff --git a/CLI/wwwroot/build/bundle.css b/CLI/wwwroot/build/bundle.css index 685ff8a..64a4712 100644 --- a/CLI/wwwroot/build/bundle.css +++ b/CLI/wwwroot/build/bundle.css @@ -1,8 +1,8 @@ main.svelte-1kds1eb{text-align:center;padding:1em;max-width:240px;margin:0 auto}@media(min-width: 640px){main.svelte-1kds1eb{max-width:none}} +.errors.svelte-1l9twu{position:fixed;right:1rem;top:6rem}.error.svelte-1l9twu{min-width:300px;max-width:700px}.error.svelte-1l9twu pre.svelte-1l9twu{overflow-wrap:break-word}.editor-container.svelte-1l9twu{margin-top:1rem}.editor-container.svelte-1l9twu,#editor.svelte-1l9twu{height:calc(100% - 4rem)} +tr.svelte-1aug0lv:hover{cursor:pointer} textarea.svelte-nhavks{width:750px;min-height:250px} .preview.svelte-9zwial{height:calc(100% - 60px)}iframe.svelte-9zwial{width:100%;margin:2rem 0;height:100%;border:none} -tr.svelte-1aug0lv:hover{cursor:pointer} -.errors.svelte-1l9twu{position:fixed;right:1rem;top:6rem}.error.svelte-1l9twu{min-width:300px;max-width:700px}.error.svelte-1l9twu pre.svelte-1l9twu{overflow-wrap:break-word}.editor-container.svelte-1l9twu{margin-top:1rem}.editor-container.svelte-1l9twu,#editor.svelte-1l9twu{height:calc(100% - 4rem)} .topology.svelte-sq8u03{height:calc(100% - 4rem)}#topology.svelte-sq8u03{height:100%}#topology>.svelte-sq8u03:focus{outline:none !important}.options-form.svelte-sq8u03{position:fixed;right:10px;bottom:10px} ul.svelte-wjec8i{list-style:none;text-align:left} .descriptor.svelte-86a2ch{border:1px solid lightgray;font-size:14px;padding:1;margin:0;width:450px;margin-bottom:1rem;margin-left:50%;transform:translateX(-50%)}.descriptor.svelte-86a2ch:hover{cursor:pointer}.descriptor.svelte-86a2ch h2.svelte-86a2ch{background:#3083db;color:white;padding:0.5em;font-size:1em;margin:0;position:relative}.descriptor.svelte-86a2ch .description.svelte-86a2ch{color:gray;padding:0 1rem}.pill.svelte-86a2ch{background:orange;border:1 px solid rgb(172, 114, 6);color:white;border-radius:50%;font-size:10px;text-transform:lowercase;padding:0.5em 1em 0.6em 1em;position:absolute;left:10px;top:50%;transform:translateY(-50%)}.pill.type.svelte-86a2ch{background:purple}.pill.field.svelte-86a2ch{background:darkgreen} diff --git a/CLI/wwwroot/build/bundle.css.map b/CLI/wwwroot/build/bundle.css.map index 4c32a26..3e58bf1 100644 --- a/CLI/wwwroot/build/bundle.css.map +++ b/CLI/wwwroot/build/bundle.css.map @@ -3,10 +3,10 @@ "file": "bundle.css", "sources": [ "../../../web/src/App.svelte", + "../../../web/src/Editor.svelte", + "../../../web/src/Lexicon.svelte", "../../../web/src/LexiconAdmin.svelte", "../../../web/src/Preview.svelte", - "../../../web/src/Lexicon.svelte", - "../../../web/src/Editor.svelte", "../../../web/src/ModuleTopology.svelte", "../../../web/src/FileTree.svelte", "../../../web/src/SearchResult.svelte", @@ -14,15 +14,15 @@ ], "sourcesContent": [ "\n\n\n\n
\n\n navigator.navigate('index')}>\n Home\n \n navigator.navigate('module-topology')}>\n Topology\n \n navigator.navigate('lexicon')}>\n Lexicon\n \n {#if navigator.module}\n navigator.navigate('editor')}>\n Editor\n \n navigator.navigate('preview')}>\n Preview\n \n {/if}\n
\n\n{#if route === 'index'}\n \n{:else if route === 'lexicon'}\n \n{:else if route === 'add-lexicon'}\n \n{:else if route === 'edit-lexicon'}\n \n{:else if route === 'lexicon-admin'}\n \n{:else if route === 'preview'}\n \n{:else if route === 'editor'}\n \n{:else if route === 'config'}\n \n{:else if route === 'module-topology'}\n \n{:else if route === 'module-create'}\n \n{:else}\n \n{/if}\n", + "\n\n\n\n
\n Save\n
\n
\n
\n
\n\n{#if errors && errors.length > 0}\n
\n {#each errors as error}\n
\n
{error.title}
\n
{error.message}
\n
\n {/each}\n
\n{/if}\n\n", + "\n\n\n\n
\n

Search your lexicon!

\n
\n {\n navigator.navigate('add-lexicon');\n }}>\n Create\n \n

Search your lexicon:

\n e.code === 'Enter' && onkeyup(e.target.value)}\n on:change={e => findData(e.target.value)} />\n
\n
\n\n \n \n \n \n \n \n {#each data as d}\n navigator.navigate('edit-lexicon', d.id)}>\n \n \n \n \n {/each}\n \n
DomainNameDescription
{d.domain}{d.name}{d.description}
\n", "\n\n\n\n

Domains

\n

Please give the domains you would like to restrict your lexicon to.

\n