Exemple #1
0
        public void Success_QCPipelineAttached()
        {
            // Setup
            var qualityStrategyExpected = QualityStrategy.LinearIncrease;
            var item = new Item("NewItem", 1, 3, qualityStrategyExpected, ShelfLifeStrategy.Stable);
            var qualityFactoryMock = new Mock <IQualityAlgorithmFactory>(MockBehavior.Strict);
            var qcList             = new List <IQualityAlgorithm>()
            {
                new QualityNeverNegativeAlgorithm()
            };

            // Create a mock that expects the sort of strategy that is represented in the item above
            var expectedReturn = new LinearIncreaseAlgorithm();

            qualityFactoryMock.Setup(f => f.Create(qualityStrategyExpected))
            .Returns(expectedReturn);

            var factory = new QualityPipelineFactory(qualityFactoryMock.Object, qcList);

            // Execution
            var result = factory.CreatePipeline(item);

            // Assert
            // Since we haven't provided any QC steps, we should have a single element
            Assert.AreEqual(1 + qcList.Count, result.Count);
            Assert.AreEqual(expectedReturn, result[0]);

            for (var i = 0; i < qcList.Count; i++)
            {
                Assert.AreEqual(qcList[i], result[1 + i]);
            }
        }
Exemple #2
0
        public void Failure_ItemIsNull()
        {
            // Setup
            var qualityFactoryMock = new Mock <IQualityAlgorithmFactory>();
            var factory            = new QualityPipelineFactory(qualityFactoryMock.Object, null);

            // Execution and assert
            Assert.ThrowsException <ArgumentNullException>(() => factory.CreatePipeline(null));
        }
Exemple #3
0
        public void Success_NullListOfQualityControlChecksDoesNotRaiseException()
        {
            // Setup
            var qualityFactoryMock = new Mock <IQualityAlgorithmFactory>();

            // Execution
            var factory = new QualityPipelineFactory(qualityFactoryMock.Object, null);

            // Assert
            Assert.IsNotNull(factory);   // Not really needed
        }
Exemple #4
0
        public void Failure_FactoryThrowsArgumentException()
        {
            // Setup
            var item = new Item("NewItem", 1, 3, QualityStrategy.Stable, ShelfLifeStrategy.Stable);
            var qualityFactoryMock = new Mock <IQualityAlgorithmFactory>();

            qualityFactoryMock.Setup(f => f.Create(It.IsAny <QualityStrategy>()))
            .Throws(new ArgumentException());
            var factory = new QualityPipelineFactory(qualityFactoryMock.Object, null);

            // Execution and assert
            // We'd expect this to result in a GildedRoseException exception
            Assert.ThrowsException <GildedRoseException>(() => factory.CreatePipeline(item));
        }
Exemple #5
0
        public void Failure_FactoryThrowsGildedRoseException()
        {
            // Setup
            var item = new Item("NewItem", 1, 3, QualityStrategy.Stable, ShelfLifeStrategy.Stable);
            var qualityFactoryMock = new Mock <IQualityAlgorithmFactory>();
            var expectedException  = new GildedRoseException();

            qualityFactoryMock.Setup(f => f.Create(It.IsAny <QualityStrategy>()))
            .Throws(expectedException);
            var factory = new QualityPipelineFactory(qualityFactoryMock.Object, null);

            // Execution and assert
            // We'd expect this to result in the original exception being rethrown
            var theException = Assert.ThrowsException <GildedRoseException>(() => factory.CreatePipeline(item));

            Assert.AreEqual(expectedException, theException);
        }
Exemple #6
0
        public void Success_CorrectPipelineReturned()
        {
            // Setup
            var qualityStrategyExpected = QualityStrategy.Stable;
            var item = new Item("NewItem", 1, 3, qualityStrategyExpected, ShelfLifeStrategy.Stable);
            var qualityFactoryMock = new Mock <IQualityAlgorithmFactory>(MockBehavior.Strict);

            // Create a mock that expects the sort of strategy that is represented in the item above
            var expectedReturn = new StableQualityAlgorithm();

            qualityFactoryMock.Setup(f => f.Create(qualityStrategyExpected))
            .Returns(expectedReturn);

            var factory = new QualityPipelineFactory(qualityFactoryMock.Object, null);

            // Execution
            var result = factory.CreatePipeline(item);

            // Assert
            // Since we haven't provided any QC steps, we should have a single element
            Assert.AreEqual(1, result.Count);
            Assert.AreEqual(expectedReturn, result[0]);
        }
Exemple #7
0
        /// <summary>
        /// The main program entry point
        /// </summary>
        /// <param name="args">Command line arguments</param>
        static async Task <int> Main(string[] args)
        {
            // We require two arguments, one for the input file and the other for the output file. If we don't have these
            // we must stop
            if (args.Length != 2)
            {
                Console.WriteLine("Usage: GuildedRose InputFileName OutputFileName");
                Console.WriteLine("The program will parse the input file, modify the contents and output the result to " +
                                  "the output file");
                return(-1);
            }

            // Creates a mapping between the quality control strategy and the implementation. This uses
            // type and not a direct instantiation to prevent to prevent more complicated classes interfering with
            // each other should this algorithm ultimately be paralleled.
            var qualityAlgorithmFactory = new QualityAlgorithmFactory(new Dictionary <QualityStrategy, Type>()
            {
                { QualityStrategy.Stable, typeof(StableQualityAlgorithm) },
                { QualityStrategy.LinearDecrease, typeof(LinearDecreaseAlgorithm) },
                { QualityStrategy.LinearIncrease, typeof(LinearIncreaseAlgorithm) },
                { QualityStrategy.RapidDecrease, typeof(RapidDecreaseAlgorithm) },
                { QualityStrategy.IncreasingUntilSellBy, typeof(IncreasingValueUntilSellByAlgorithm) },
            });

            // Creates a mapping between the shelf life strategy and the implementation.
            var shelfLifeAlgorithmFactory = new ShelfLifeAlgorithmFactory(new Dictionary <ShelfLifeStrategy, Type>()
            {
                { ShelfLifeStrategy.Stable, typeof(StableShelfLifeAlgorithm) },
                { ShelfLifeStrategy.LinearDecrease, typeof(LinearDecreaseShelfLifeAlgorithm) }
            });

            // Creates a mapping between an item of stock and it's corresponding stock management strategy.
            var itemFactory = new ItemFactory(new Dictionary <string, StockManagementStrategy>()
            {
                {
                    "Aged Brie",
                    new StockManagementStrategy(QualityStrategy.LinearIncrease, ShelfLifeStrategy.LinearDecrease)
                },
                {
                    "Backstage passes",
                    new StockManagementStrategy(QualityStrategy.IncreasingUntilSellBy, ShelfLifeStrategy.LinearDecrease)
                },
                { "Sulfuras", new StockManagementStrategy(QualityStrategy.Stable, ShelfLifeStrategy.Stable) },
                {
                    "Normal Item",
                    new StockManagementStrategy(QualityStrategy.LinearDecrease, ShelfLifeStrategy.LinearDecrease)
                },
                {
                    "Conjured",
                    new StockManagementStrategy(QualityStrategy.RapidDecrease, ShelfLifeStrategy.LinearDecrease)
                }
            });

            // Define a list of quality control steps that must be run every time
            var qualityControl = new List <IQualityAlgorithm>()
            {
                new QualityNeverNegativeAlgorithm(),
                new QualityNeverAboveThresholdAlgorithm(50)
            };

            // And now the object that creates the factory for the item.
            var qualityFactory = new QualityPipelineFactory(qualityAlgorithmFactory, qualityControl);

            // Create an object that can parse the text. If multiple formats are required this could be created via
            // a factory object. For now, we only have one format
            var stringParse = new SpaceSeparatedParser();

            // Create the processing object that performs the main business logic
            var itemProcessor = new ItemProcessor(qualityFactory, shelfLifeAlgorithmFactory);

            // Create the object that can convert between our parsed item and the real inventory item
            var itemToInventoryParse = new ParsedItemToInventoryItemConverter(itemFactory);

            try
            {
                // Open the input file
                await using var inputStream = new FileStream(args[0], FileMode.Open);

                // Create the output file
                await using var outputStream       = new FileStream(args[1], FileMode.Create);
                await using var outputStreamWriter = new StreamWriter(outputStream);

                // Create the object that performs the final output
                var outputProcessor = new OutputProcessor(outputStreamWriter);

                // Run the pipeline by awaiting on the observable
                await create_observable_stream(inputStream, stringParse, itemToInventoryParse, itemProcessor, outputProcessor);

                Console.WriteLine("File processed.");

                // The file was processed successfully. We do not consider any parsing errors as significant (since
                // the output file has been marked accordingly).
                return(0);
            }
            catch (Exception ex)
            {
                Console.WriteLine(
                    $"The process could not be completed because an error occurred. Exception: {ex.Message}");
                return(-1);
            }
        }