< Summary - pva.SuperV

Information
Class: pva.SuperV.Engine.WipProject
Assembly: pva.SuperV.Engine
File(s): /home/runner/work/pva.SuperV/pva.SuperV/pva.SuperV.Engine/WipProject.cs
Tag: dotnet-ubuntu_18869653307
Line coverage
95%
Covered lines: 162
Uncovered lines: 7
Coverable lines: 169
Total lines: 336
Line coverage: 95.8%
Branch coverage
82%
Covered branches: 33
Total branches: 40
Branch coverage: 82.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_ToLoadInstances()100%11100%
.ctor()100%11100%
.ctor(...)100%11100%
.ctor(...)100%11100%
AddClass(...)100%22100%
AddClass(...)75%4477.77%
UpdateClass(...)50%7675%
RemoveClass(...)100%22100%
AddField(...)100%11100%
AddField(...)100%22100%
UpdateField(...)50%22100%
RemoveField(...)100%11100%
AddFieldFormatter(...)100%22100%
UpdateFieldFormatter(...)50%4481.81%
RemoveFieldFormatter(...)100%11100%
VerifyFieldFormatterNotUsed(...)100%66100%
AddFieldChangePostProcessing(...)100%11100%
UpdateFieldChangePostProcessing(...)100%11100%
RemoveFieldChangePostProcessing(...)100%11100%
GetId()100%11100%
AddHistoryRepository(...)100%22100%
UpdateHistoryRepository(...)100%22100%
RemoveHistoryRepository(...)100%11100%
VerifyHistoryRepositoryNotUsed(...)100%66100%
CloneAsRunnable()100%11100%
Unload()100%11100%

File(s)

/home/runner/work/pva.SuperV/pva.SuperV/pva.SuperV.Engine/WipProject.cs

#LineLine coverage
 1using pva.Helpers.Extensions;
 2using pva.SuperV.Engine.Exceptions;
 3using pva.SuperV.Engine.FieldFormatters;
 4using pva.SuperV.Engine.HistoryStorage;
 5using pva.SuperV.Engine.Processing;
 6
 7namespace pva.SuperV.Engine
 8{
 9    /// <summary>
 10    /// WIP (Work In Progress) project. It allows adding/changing/removing <see cref="Class"/>, <see cref="FieldDefiniti
 11    /// </summary>
 12    /// <seealso cref="pva.SuperV.Engine.Project" />
 13    public class WipProject : Project
 14    {
 15        /// <summary>
 16        /// To be loaded instances when the project is converted to a <see cref="RunnableProject"/> through <see cref="P
 17        /// </summary>
 94818        public Dictionary<string, Instance> ToLoadInstances { get; } = new(StringComparer.OrdinalIgnoreCase);
 19
 20        /// <summary>
 21        /// Initializes a new instance of the <see cref="WipProject"/> class. Only used for deserialization.
 22        /// </summary>
 123        public WipProject()
 124        {
 125        }
 26
 27        /// <summary>
 28        /// Initializes a new instance of the <see cref="WipProject"/> class.
 29        /// </summary>
 30        /// <param name="projectName">Name of the project.</param>
 23931        public WipProject(string projectName)
 23932        {
 23933            Name = projectName;
 23634            Version = GetNextVersion();
 23635        }
 36
 37        /// <summary>
 38        /// Initializes a new instance of the <see cref="WipProject"/> class from a <see cref="RunnableProject"/>.
 39        /// </summary>
 40        /// <param name="runnableProject">The runnable project.</param>
 3641        public WipProject(RunnableProject runnableProject)
 3642        {
 3643            Name = runnableProject.Name;
 3644            Description = runnableProject.Description;
 3645            Version = GetNextVersion();
 3646            Classes = new(runnableProject.Classes.Count);
 3647            runnableProject.Classes
 14448                .ForEach((k, v) => Classes.Add(k, v.Clone()));
 3649            FieldFormatters = new(runnableProject.FieldFormatters);
 3650            HistoryStorageEngineConnectionString = runnableProject.HistoryStorageEngineConnectionString;
 3651            HistoryStorageEngine = HistoryStorageEngineFactory.CreateHistoryStorageEngine(runnableProject.HistoryStorage
 3652            HistoryRepositories = new(runnableProject.HistoryRepositories);
 3653            HistoryRepositories.Values.ForEach(repository
 7254                => repository.HistoryStorageEngine = HistoryStorageEngine);
 3655            ToLoadInstances = new(runnableProject.Instances, StringComparer.OrdinalIgnoreCase);
 3656        }
 57
 58        /// <summary>
 59        /// Adds a new class to the project.
 60        /// </summary>
 61        /// <param name="className">Name of the class.</param>
 62        /// <returns>The newly created <see cref="Class"/>.</returns>
 63        /// <exception cref="pva.SuperV.Engine.Exceptions.EntityAlreadyExistException"></exception>
 64        public Class AddClass(string className)
 36265        {
 36266            if (Classes.ContainsKey(className))
 167            {
 168                throw new EntityAlreadyExistException("Class", className);
 69            }
 70
 36171            Class clazz = new(className);
 36172            Classes.Add(className, clazz);
 36173            return clazz;
 36174        }
 75
 76        /// <summary>
 77        /// Adds a new class with inheritance to the project.
 78        /// </summary>
 79        /// <param name="className">Name of the class.</param>
 80        /// <param name="baseClassName">Name of the base class.</param>
 81        /// <returns>The newly created <see cref="Class"/>.</returns>
 82        /// <exception cref="pva.SuperV.Engine.Exceptions.EntityAlreadyExistException"></exception>
 83        public Class AddClass(string className, string? baseClassName)
 14884        {
 14885            Class? baseClass = baseClassName is null ? null : GetClass(baseClassName);
 14886            if (Classes.ContainsKey(className))
 087            {
 088                throw new EntityAlreadyExistException("Class", className);
 89            }
 90
 14891            Class clazz = new(className, baseClass);
 14892            Classes.Add(className, clazz);
 14893            return clazz;
 14894        }
 95
 96        /// <summary>
 97        /// Updates a class.
 98        /// </summary>
 99        /// <param name="className">Name of class to be updated</param>
 100        /// <param name="baseClassName">Base class name</param>
 101        /// <returns>Updated class.</returns>
 102        /// <exception cref="UnknownEntityException"></exception>
 103        public Class UpdateClass(string className, string? baseClassName)
 1104        {
 1105            if (Classes.TryGetValue(className, out Class? clazz))
 1106            {
 1107                Class? baseClass = null;
 1108                if (!String.IsNullOrEmpty(baseClassName) && !Classes.TryGetValue(className, out baseClass))
 0109                {
 0110                    throw new UnknownEntityException("Class", baseClassName);
 111                }
 1112                clazz.BaseClassName = baseClassName;
 1113                clazz.BaseClass = baseClass;
 1114                return clazz;
 115            }
 0116            throw new UnknownEntityException("Class", className);
 1117        }
 118
 119        /// <summary>
 120        /// Removes a class from project.
 121        /// </summary>
 122        /// <param name="className">Name of the class.</param>
 123        public void RemoveClass(string className)
 3124        {
 3125            if (Classes.Remove(className, out var clazz))
 2126            {
 2127                ToLoadInstances.Values
 1128                    .Where(instance => instance.Class.Name!.Equals(clazz.Name))
 2129                    .ToList()
 3130                    .ForEach(instance => ToLoadInstances.Remove(instance.Name));
 2131            }
 3132        }
 133
 134        /// <summary>
 135        /// Adds a field to a class.
 136        /// </summary>
 137        /// <typeparam name="T"></typeparam>
 138        /// <param name="className">Name of the class.</param>
 139        /// <param name="field">The field.</param>
 140        /// <returns></returns>
 141        public IFieldDefinition AddField(string className, IFieldDefinition field)
 2612142        {
 2612143            Class clazz = GetClass(className);
 2612144            return clazz.AddField(field);
 2611145        }
 146
 147        /// <summary>
 148        /// Adds a field to a class with a specific field formatter.
 149        /// </summary>
 150        /// <typeparam name="T"></typeparam>
 151        /// <param name="className">Name of the class.</param>
 152        /// <param name="field">The field.</param>
 153        /// <param name="formatterName">Name of the formatter.</param>
 154        /// <returns></returns>
 155        public IFieldDefinition AddField(string className, IFieldDefinition field, string? formatterName)
 292156        {
 292157            Class clazz = GetClass(className);
 292158            FieldFormatter? formatter = GetFormatter(formatterName);
 291159            formatter?.ValidateAllowedType(field.Type);
 290160            return clazz.AddField(field, formatter);
 290161        }
 162
 163        public IFieldDefinition UpdateField(string className, string fieldName, IFieldDefinition field, string? formatte
 4164        {
 4165            Class clazz = GetClass(className);
 4166            FieldFormatter? formatter = GetFormatter(formatterName);
 4167            formatter?.ValidateAllowedType(field.Type);
 4168            return clazz.UpdateField(fieldName, field, formatter);
 2169        }
 170
 171        /// <summary>
 172        /// Removes a field from a class.
 173        /// </summary>
 174        /// <param name="className">Name of the class.</param>
 175        /// <param name="fieldName">Name of the field.</param>
 176        public void RemoveField(string className, string fieldName)
 2177        {
 2178            Class clazz = GetClass(className);
 2179            clazz.RemoveField(fieldName);
 1180        }
 181
 182        /// <summary>
 183        /// Adds a field formatter to project to be later used for a specific field formatting (<see cref="AddField{T}(s
 184        /// </summary>
 185        /// <param name="fieldFormatter">The field formatter.</param>
 186        /// <exception cref="pva.SuperV.Engine.Exceptions.EntityAlreadyExistException"></exception>
 187        public void AddFieldFormatter(FieldFormatter fieldFormatter)
 199188        {
 199189            if (FieldFormatters.ContainsKey(fieldFormatter.Name!))
 1190            {
 1191                throw new EntityAlreadyExistException("Field formatter", fieldFormatter.Name);
 192            }
 193
 198194            FieldFormatters.Add(fieldFormatter.Name!, fieldFormatter);
 198195        }
 196
 197        public void UpdateFieldFormatter(string fieldFormatterName, FieldFormatter fieldFormatter)
 2198        {
 2199            FieldFormatter? existingFormatter = GetFormatter(fieldFormatterName);
 2200            if (existingFormatter != null)
 2201            {
 2202                if (existingFormatter.GetType() == fieldFormatter.GetType())
 2203                {
 2204                    FieldFormatters[fieldFormatterName] = fieldFormatter;
 2205                    return;
 206                }
 0207                throw new WrongFieldTypeException(fieldFormatterName, existingFormatter.GetType(), fieldFormatter.GetTyp
 208            }
 0209            throw new UnknownEntityException("Field formatter", fieldFormatterName);
 2210        }
 211
 212
 213        /// <summary>
 214        /// Removes a field formatter.
 215        /// </summary>
 216        /// <param name="fieldFormatterName">Name of the field formatter.</param>
 217        public bool RemoveFieldFormatter(string fieldFormatterName)
 5218        {
 5219            VerifyFieldFormatterNotUsed(fieldFormatterName);
 3220            return FieldFormatters.Remove(fieldFormatterName);
 3221        }
 222
 223        private void VerifyFieldFormatterNotUsed(string fieldFormatterName)
 5224        {
 5225            Classes.Values.ForEach(clazz =>
 9226            {
 9227                List<String> fieldsUsingFormatter = [.. clazz.FieldDefinitions.Values
 48228                    .Where(field => field.Formatter is not null && field.Formatter.Name.Equals(fieldFormatterName))
 11229                    .Select(field => field.Name)];
 9230                if (fieldsUsingFormatter.Count > 0)
 2231                {
 2232                    throw new EntityInUseException("Field formatter", fieldFormatterName, clazz.Name, fieldsUsingFormatt
 5233                }
 12234            });
 3235        }
 236
 237        /// <summary>
 238        /// Adds a field change post processing on a field..
 239        /// </summary>
 240        /// <param name="className">Name of the class.</param>
 241        /// <param name="fieldName">Name of the field.</param>
 242        /// <param name="fieldValueProcessing">The field value processing.</param>
 243        public void AddFieldChangePostProcessing(string className, string fieldName, IFieldValueProcessing fieldValuePro
 440244        {
 440245            Class clazz = GetClass(className);
 440246            clazz.AddFieldChangePostProcessing(fieldName, fieldValueProcessing);
 440247        }
 248
 249        public void UpdateFieldChangePostProcessing(string className, string fieldName, string processingName, IFieldVal
 1250        {
 1251            Class clazz = GetClass(className);
 1252            clazz.UpdateFieldChangePostProcessing(fieldName, processingName, fieldProcessing);
 1253        }
 254
 255        public void RemoveFieldChangePostProcessing(string className, string fieldName, string processingName)
 1256        {
 1257            Class clazz = GetClass(className);
 1258            clazz.RemoveFieldChangePostProcessing(fieldName, processingName);
 1259        }
 260
 261        public override string GetId()
 987262        {
 987263            return $"{Name!}-WIP";
 987264        }
 265
 266        /// <summary>
 267        /// Adds a history repository to project./>.
 268        /// </summary>
 269        /// <param name="historyRepository">The history repository.</param>
 270        /// <exception cref="pva.SuperV.Engine.Exceptions.EntityAlreadyExistException"></exception>
 271        public void AddHistoryRepository(HistoryRepository historyRepository)
 155272        {
 155273            if (HistoryRepositories.ContainsKey(historyRepository.Name))
 1274            {
 1275                throw new EntityAlreadyExistException("History repository", historyRepository.Name);
 276            }
 277
 154278            historyRepository.HistoryStorageEngine = HistoryStorageEngine;
 154279            HistoryRepositories.Add(historyRepository.Name, historyRepository);
 154280        }
 281
 282        public void UpdateHistoryRepository(string historyRepositoryName, HistoryRepository historyRepository)
 2283        {
 2284            if (HistoryRepositories.TryGetValue(historyRepositoryName, out HistoryRepository? _))
 1285            {
 1286                HistoryRepositories[historyRepositoryName] = historyRepository;
 1287                return;
 288            }
 1289            throw new UnknownEntityException("History repository", historyRepositoryName);
 1290        }
 291
 292        /// <summary>
 293        /// Removes a history repository.
 294        /// </summary>
 295        /// <param name="historyRepositoryName">Name of the history repository.</param>
 296        public void RemoveHistoryRepository(string historyRepositoryName)
 3297        {
 3298            VerifyHistoryRepositoryNotUsed(historyRepositoryName);
 2299            HistoryRepositories.Remove(historyRepositoryName);
 2300        }
 301
 302        private void VerifyHistoryRepositoryNotUsed(string historyRepositoryName)
 3303        {
 3304            Classes.Values.ForEach(clazz =>
 5305            {
 5306                List<String> fieldsUsingHistoryRepository = [.. clazz.FieldDefinitions.Values
 27307                    .Where(field => field.ValuePostChangeProcessings
 27308                        .OfType<IHistorizationProcessing>()
 28309                        .Any(historyValueProcessing => historyValueProcessing.IsUsingRepository(historyRepositoryName)))
 6310                    .Select(field => field.Name)];
 5311                if (fieldsUsingHistoryRepository.Count > 0)
 1312                {
 1313                    throw new EntityInUseException("History Repository", historyRepositoryName, clazz.Name, fieldsUsingH
 3314                }
 7315            });
 2316        }
 317
 318
 319        /// <summary>
 320        /// Clones as <see cref="RunnableProject"/>.
 321        /// </summary>
 322        /// <returns><see cref="RunnableProject"/></returns>
 323        public RunnableProject CloneAsRunnable()
 126324            => new(this);
 325
 326        /// <summary>
 327        /// Unloads the project.
 328        /// </summary>
 329        public override void Unload()
 272330        {
 274331            ToLoadInstances.Values.ForEach(instance => instance.Dispose());
 272332            ToLoadInstances.Clear();
 272333            base.Unload();
 272334        }
 335    }
 336}