public void ServiceThrowsOnRemoveTermWithoutName()
        {
            var service = new XmlTermsService(String.Empty);

            // Test null.
            try
            {
                service.RemoveTerm(new Term(null, String.Empty), Scheduler.Immediate);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsInstanceOfType(ex, typeof(ArgumentException));
                Assert.IsTrue(((ArgumentException)ex).ParamName == "term");
            }

            // Test whitespace.
            try
            {
                service.RemoveTerm(new Term(" ", String.Empty), Scheduler.Immediate);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsInstanceOfType(ex, typeof(ArgumentException));
                Assert.IsTrue(((ArgumentException)ex).ParamName == "term");
            }
        }
Пример #2
0
        /// <summary>
        /// Gets an observable that removes an existing term from the storage.
        /// </summary>
        /// <param name="term">A term to remove from the storage.</param>
        /// <param name="scheduler">A scheduler to invoke service operations on.</param>
        /// <returns>An observable sequence that removes the specified term and pushes
        /// it to subscribers.</returns>
        public IObservable <Term> RemoveTerm(Term term, IScheduler scheduler)
        {
            XmlTermsService.ApplyTermRules(term, "term");

            return(Observable
                   .Return(term, scheduler)
                   .Do(_ =>
            {
                var doc = this.LoadStorage();

                // Search for a node to remove.
                var xTerm = doc
                            .Descendants(TermXmlNames.TermElement)
                            .SingleOrDefault(el => el.Attribute(TermXmlNames.TermNameAttribute).Value == term.Name);
                if (xTerm == null)
                {
                    throw new InvalidOperationException(String.Format(
                                                            Resources.UnableToRemoveNonExistentTerm,
                                                            term.Name));
                }

                xTerm.Remove();

                this.SaveStorage(doc);
            }));
        }
        public void ServiceThrowsOnUpdateNullTerm()
        {
            // Check validation of old term.
            var service = new XmlTermsService(String.Empty);

            try
            {
                service.UpdateTerm(null, XmlTermsServiceFixture.SampleTerms[0], Scheduler.Immediate);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsInstanceOfType(ex, typeof(ArgumentNullException));
                Assert.IsTrue(((ArgumentNullException)ex).ParamName == "oldTerm");
            }

            // Check validation of new term.
            service = new XmlTermsService(String.Empty);
            try
            {
                service.UpdateTerm(XmlTermsServiceFixture.SampleTerms[0], null, Scheduler.Immediate);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsInstanceOfType(ex, typeof(ArgumentNullException));
                Assert.IsTrue(((ArgumentNullException)ex).ParamName == "newTerm");
            }
        }
        public void ServiceThrowsOnUpdateToTermWithoutName()
        {
            var service = new XmlTermsService(String.Empty);

            var nameless   = new Term(null, String.Empty);
            var whitespace = new Term(" ", String.Empty);

            // Test null.
            try
            {
                service.UpdateTerm(XmlTermsServiceFixture.SampleTerms[0], nameless, Scheduler.Immediate);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsInstanceOfType(ex, typeof(ArgumentException));
                Assert.IsTrue(((ArgumentException)ex).ParamName == "newTerm");
            }

            // Test whitespace.
            try
            {
                service.UpdateTerm(XmlTermsServiceFixture.SampleTerms[0], whitespace, Scheduler.Immediate);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsInstanceOfType(ex, typeof(ArgumentException));
                Assert.IsTrue(((ArgumentException)ex).ParamName == "newTerm");
            }
        }
        public void ObservableUpdatesAndPushesTerm()
        {
            var fileName = XmlTermsServiceFixture.TermsToFile(
                XmlTermsServiceFixture.SampleTerms,
                "ObservableUpdatesAndPushesTerm.xml");

            var service = new XmlTermsService(fileName);
            var oldTerm = XmlTermsServiceFixture.SampleTerms[0];
            var newTerm = new Term("new term0", "new def 0");

            Term pushed = null;

            service
            .UpdateTerm(oldTerm, newTerm, Scheduler.Immediate)
            .Subscribe(p => pushed = p);

            Assert.AreEqual(newTerm, pushed);

            // Check that old term is deleted.

            var xTerm = XDocument.Load(fileName)
                        .Descendants(TermXmlNames.TermElement)
                        .FirstOrDefault(x => x.Attribute(TermXmlNames.TermNameAttribute).Value == oldTerm.Name);

            Assert.IsNull(xTerm);

            // Check that new term is added.

            xTerm = XDocument.Load(fileName)
                    .Descendants(TermXmlNames.TermElement)
                    .FirstOrDefault(x => x.Attribute(TermXmlNames.TermNameAttribute).Value == newTerm.Name);

            Assert.IsNotNull(xTerm);
            Assert.AreEqual(newTerm.Definition, xTerm.Attribute(TermXmlNames.TermDefinitionAttribute).Value);
        }
Пример #6
0
        /// <summary>
        /// Gets an observable that adds a new term to the storage.
        /// </summary>
        /// <param name="term">A term to add to the storage.</param>
        /// <param name="scheduler">A scheduler to invoke service operations on.</param>
        /// <returns>An observable sequence that adds the specified term and pushes
        /// it to subscribers.</returns>
        public IObservable <Term> AddTerm(Term term, IScheduler scheduler)
        {
            XmlTermsService.ApplyTermRules(term, "term");

            return(Observable
                   .Return(term, scheduler)
                   .Do(_ =>
            {
                var doc = this.LoadStorage();

                // Check whether a term with the same name already exists.
                // A client must use UpdateTerm in this case.
                if (doc
                    .Descendants(TermXmlNames.TermElement)
                    .Any(el => el.Attribute(TermXmlNames.TermNameAttribute).Value == term.Name))
                {
                    throw new InvalidOperationException(String.Format(
                                                            Resources.UnableToAddTermAlreadyExists,
                                                            term.Name));
                }

                var xTerm = new XElement(
                    TermXmlNames.TermElement,
                    new XAttribute(TermXmlNames.TermNameAttribute, term.Name));

                if (!String.IsNullOrEmpty(term.Definition))
                {
                    xTerm.Add(new XAttribute(TermXmlNames.TermDefinitionAttribute, term.Definition));
                }

                doc.Root.Add(xTerm);

                this.SaveStorage(doc);
            }));
        }
        public void ObservableThrowsWhenFileDoesntExist()
        {
            var service = new XmlTermsService(String.Empty);

            ReactiveAssert.Throws <InvalidTermsStorageException>(
                () =>
            {
                service
                .LoadTerms(Scheduler.Immediate)
                .Subscribe();
            });
        }
Пример #8
0
        /// <summary>
        /// Gets an observable that updates an existing term in the storage.
        /// </summary>
        /// <param name="oldTerm">An old value of term to update in the storage.</param>
        /// <param name="newTerm">A new value of term.</param>
        /// <param name="scheduler">A scheduler to invoke service operations on.</param>
        /// <returns>An observable sequence that updates the specified term and pushes
        /// it to subscribers.</returns>
        public IObservable <Term> UpdateTerm(Term oldTerm, Term newTerm, IScheduler scheduler)
        {
            XmlTermsService.ApplyTermRules(oldTerm, "oldTerm");
            XmlTermsService.ApplyTermRules(newTerm, "newTerm");

            return(Observable
                   .Return(newTerm, scheduler)
                   .Do(_ =>
            {
                var doc = this.LoadStorage();

                // Check whether an old term already exists.
                // If it is not, the client must use AddTerm.
                var xTerm = doc
                            .Descendants(TermXmlNames.TermElement)
                            .SingleOrDefault(el => el.Attribute(TermXmlNames.TermNameAttribute).Value == oldTerm.Name);
                if (xTerm == null)
                {
                    throw new InvalidOperationException(String.Format(
                                                            Resources.UnableToUpdateNonExistentTerm,
                                                            oldTerm.Name));
                }

                // Check whether a new term already exists if names are different.
                if (oldTerm.Name != newTerm.Name)
                {
                    var newTermExists = doc
                                        .Descendants(TermXmlNames.TermElement)
                                        .Any(el => el.Attribute(TermXmlNames.TermNameAttribute).Value == newTerm.Name);
                    if (newTermExists)
                    {
                        throw new InvalidOperationException(String.Format(
                                                                Resources.UnableToUpdateToAnotherExistentTerm,
                                                                newTerm.Name));
                    }
                }

                xTerm.Attribute(TermXmlNames.TermNameAttribute).Value = newTerm.Name;

                if (!String.IsNullOrEmpty(newTerm.Definition))
                {
                    xTerm.SetAttributeValue(TermXmlNames.TermDefinitionAttribute, newTerm.Definition);
                }
                else
                {
                    xTerm.Attribute(TermXmlNames.TermDefinitionAttribute).Remove();
                }

                this.SaveStorage(doc);
            }));
        }
        public void ObservableLoadsNoTermsFromEmptyValidXml()
        {
            var service = new XmlTermsService(XmlTermsServiceFixture.TermsToFile(
                                                  Enumerable.Empty <Term>(),
                                                  "ObservableLoadsNoTermsFromEmptyValidXml.xml"));

            var serviceTerms = new List <Term>();

            service
            .LoadTerms(Scheduler.Immediate)
            .Subscribe(terms => serviceTerms.AddRange(terms));

            ReactiveAssert.AreElementsEqual(Enumerable.Empty <Term>(), serviceTerms);
        }
        public void ServiceThrowsOnRecreateNothing()
        {
            var service = new XmlTermsService(String.Empty);

            try
            {
                service.RecreateStorage(null, Scheduler.Immediate);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsInstanceOfType(ex, typeof(ArgumentNullException));
                Assert.IsTrue(((ArgumentNullException)ex).ParamName == "terms");
            }
        }
        public void ObservableThrowsOnAddExistingTerm()
        {
            var service = new XmlTermsService(XmlTermsServiceFixture.TermsToFile(
                                                  XmlTermsServiceFixture.SampleTerms,
                                                  "ObservableThrowsOnAddExistingTerm.xml"));

            Exception ex = null;

            service
            .AddTerm(XmlTermsServiceFixture.SampleTerms[0], Scheduler.Immediate)
            .Subscribe(_ => { }, ex2 => ex = ex2, () => { });

            Assert.IsInstanceOfType(ex, typeof(InvalidOperationException));
            Assert.IsTrue(ex.Message.Contains("already exists"));
        }
Пример #12
0
 /// <summary>
 /// Gets an observable sequence that retrieves terms from the storage.
 /// </summary>
 /// <param name="scheduler">A scheduler to invoke service operations on.</param>
 /// <returns>An observable sequence of portions of terms.</returns>
 public IObservable <IEnumerable <Term> > LoadTerms(IScheduler scheduler)
 {
     return(Observable
            .Return(Unit.Default, scheduler)
            .SelectMany(_ => this.LoadStorage().Descendants(TermXmlNames.TermElement))
            .Select(node => new Term(
                        node.Attribute(TermXmlNames.TermNameAttribute).Value,
                        node.Attribute(TermXmlNames.TermDefinitionAttribute).Value))
            .Do(term => XmlTermsService.ApplyTermRules(term, "term"))
            .Catch((Exception ex) => Observable.Throw <Term>(
                       XmlTermsService.WrapIntoInvalidStorageException(
                           ex,
                           String.Format(Resources.InvalidXmlStorageToLoad, this._fileName))))
            .ToArray());
 }
        public void ObservableThrowsOnRemoveNonExistentTerm()
        {
            var service = new XmlTermsService(XmlTermsServiceFixture.TermsToFile(
                                                  XmlTermsServiceFixture.SampleTerms,
                                                  "ObservableThrowsOnRemoveNonExistentTerm.xml"));
            var newTerm = new Term("nonExistentTerm", String.Empty);

            Exception ex = null;

            service
            .RemoveTerm(newTerm, Scheduler.Immediate)
            .Subscribe(_ => { }, ex2 => ex = ex2, () => { });

            Assert.IsInstanceOfType(ex, typeof(InvalidOperationException));
            Assert.IsTrue(ex.Message.Contains("doesn't exist"));
        }
        public void ObservableRecreatesNewStorage()
        {
            var filePath = Path.Combine(XmlTermsServiceFixture.DeploymentDirectory, "ObservableRecreatesNewStorage.xml");
            var service  = new XmlTermsService(filePath);

            service
            .RecreateStorage(XmlTermsServiceFixture.SampleTerms, Scheduler.Immediate)
            .Subscribe();

            var storedTerms = new List <Term>();

            service
            .LoadTerms(Scheduler.Immediate)
            .Subscribe(terms => storedTerms.AddRange(terms));

            ReactiveAssert.AreElementsEqual(XmlTermsServiceFixture.SampleTerms, storedTerms);
        }
        public void ObservableThrowsFromInvalidXml()
        {
            var service = new XmlTermsService(XmlTermsServiceFixture.TermsToFile(
                                                  new Term[]
            {
                XmlTermsServiceFixture.SampleTerms[0],
                new Term(null, String.Empty),
            },
                                                  "ObservableThrowsFromInvalidXml.xml"));

            ReactiveAssert.Throws <InvalidTermsStorageException>(
                () =>
            {
                service
                .LoadTerms(Scheduler.Immediate)
                .Subscribe();
            });
        }
        public void ObservableShouldntPushTermsFromInvalidXml()
        {
            var mix = new Term[]
            {
                XmlTermsServiceFixture.SampleTerms[0],
                new Term(null, null),
                XmlTermsServiceFixture.SampleTerms[1],
            };

            var service = new XmlTermsService(
                XmlTermsServiceFixture.TermsToFile(mix, "ObservableShouldntPushTermsFromInvalidXml.xml"));

            bool onNextInvoked = false;

            service
            .LoadTerms(Scheduler.Immediate)
            .Subscribe(terms => onNextInvoked = true, _ => { }, () => { });

            Assert.IsFalse(onNextInvoked);
        }
        public void ObservableAddsAndPushesNewTerm()
        {
            var fileName = XmlTermsServiceFixture.TermsToFile(
                XmlTermsServiceFixture.SampleTerms,
                "ObservableAddsAndPushesNewTerm.xml");

            var service = new XmlTermsService(fileName);
            var term    = new Term("newTerm", "newDef");

            Term pushed = null;

            service.AddTerm(term, Scheduler.Immediate).Subscribe(p => pushed = p);

            Assert.AreEqual(term, pushed);

            var xTerm = XDocument.Load(fileName)
                        .Descendants(TermXmlNames.TermElement)
                        .FirstOrDefault(x => x.Attribute(TermXmlNames.TermNameAttribute).Value.Equals(term.Name));

            Assert.IsNotNull(xTerm);
            Assert.AreEqual(term.Definition, xTerm.Attribute(TermXmlNames.TermDefinitionAttribute).Value);
        }
        public void ObservableRemovesAndPushesTerm()
        {
            var fileName = XmlTermsServiceFixture.TermsToFile(
                XmlTermsServiceFixture.SampleTerms,
                "ObservableRemovesTerm.xml");

            var service = new XmlTermsService(fileName);
            var term    = XmlTermsServiceFixture.SampleTerms[0];

            Term pushed = null;

            service
            .RemoveTerm(term, Scheduler.Immediate)
            .Subscribe(p => pushed = p);

            Assert.AreEqual(term, pushed);

            var xTerm = XDocument.Load(fileName)
                        .Descendants(TermXmlNames.TermElement)
                        .FirstOrDefault(x => x.Attribute(TermXmlNames.TermNameAttribute).Value == term.Name);

            Assert.IsNull(xTerm);
        }
Пример #19
0
        /// <summary>
        /// Gets an observable that recreates storage with the specified terms.
        /// </summary>
        /// <param name="terms">A terms to add to a new storage.</param>
        /// <param name="scheduler">A scheduler to invoke service operations on.</param>
        /// <returns>An observable sequence that recreates storage.</returns>
        public IObservable <Unit> RecreateStorage(IEnumerable <Term> terms, IScheduler scheduler)
        {
            if (terms == null)
            {
                throw new ArgumentNullException("terms");
            }

            return(Observable
                   .Return(Unit.Default, scheduler)
                   .Do(_ =>
            {
                var doc = new XDocument(new XElement(TermXmlNames.TermsElement));

                foreach (var term in terms)
                {
                    XmlTermsService.ApplyTermRules(term, "terms");

                    var xTerm = new XElement(
                        TermXmlNames.TermElement,
                        new XAttribute(TermXmlNames.TermNameAttribute, term.Name));

                    if (!String.IsNullOrEmpty(term.Definition))
                    {
                        xTerm.Add(new XAttribute(TermXmlNames.TermDefinitionAttribute, term.Definition));
                    }

                    doc.Root.Add(xTerm);
                }

                this.SaveStorage(doc);
            })
                   .Catch((Exception ex) => Observable.Throw <Unit>(
                              XmlTermsService.WrapIntoInvalidStorageException(
                                  ex,
                                  String.Format(Resources.InvalidXmlStorageToSave, this._fileName)))));
        }
        public void ObservableThrowsOnRecreateInvalidTerms()
        {
            var service = new XmlTermsService(String.Empty);

            // Test null.

            var invalidTerms = new Term[]
            {
                XmlTermsServiceFixture.SampleTerms[0],
                new Term(null, String.Empty),
            };

            Exception ex = null;

            service
            .RecreateStorage(invalidTerms, Scheduler.Immediate)
            .Subscribe(_ => { }, ex2 => ex = ex2, () => { });

            Assert.IsInstanceOfType(ex, typeof(InvalidTermsStorageException));

            // Test whitespace.

            invalidTerms = new Term[]
            {
                XmlTermsServiceFixture.SampleTerms[0],
                new Term(" ", String.Empty),
            };

            ex = null;

            service
            .RecreateStorage(invalidTerms, Scheduler.Immediate)
            .Subscribe(_ => { }, ex2 => ex = ex2, () => { });

            Assert.IsInstanceOfType(ex, typeof(InvalidTermsStorageException));
        }