public void Watch_CompositeChangeToken_RegisterChangeCallbackCorrectlyTransmitsAllParameters()
        {
            // Arrange
            var firstChangeToken = new MockChangeToken { ActiveChangeCallbacks = true };
            var secondChangeToken = new MockChangeToken();
            var thirdChangeToken = new MockChangeToken { ActiveChangeCallbacks = true };
            var provider = new CompositeFileProvider(
                new MockFileProvider(
                    new KeyValuePair<string, IChangeToken>("pattern", firstChangeToken),
                    new KeyValuePair<string, IChangeToken>("2ndpattern", secondChangeToken)),
                new MockFileProvider(new KeyValuePair<string, IChangeToken>("pattern", thirdChangeToken)));

            // Act
            var changeToken = provider.Watch("pattern");

            // Assert
            Assert.NotNull(changeToken);
            Assert.True(changeToken.ActiveChangeCallbacks);
            Assert.False(changeToken.HasChanged);

            // Register callback
            Assert.Equal(0, firstChangeToken.Callbacks.Count);
            Assert.Equal(0, secondChangeToken.Callbacks.Count);
            Assert.Equal(0, thirdChangeToken.Callbacks.Count);
            var hasBeenCalled = false;
            object result = null;
            object state = new object();
            changeToken.RegisterChangeCallback(item =>
            {
                hasBeenCalled = true;
                result = item;
            }, state);
            Assert.Equal(1, firstChangeToken.Callbacks.Count);
            Assert.Same(state, firstChangeToken.Callbacks[0].Item2);
            Assert.Equal(0, secondChangeToken.Callbacks.Count);
            Assert.Equal(1, thirdChangeToken.Callbacks.Count);
            Assert.Same(state, thirdChangeToken.Callbacks[0].Item2);
            var expectedResult = new object();
            firstChangeToken.RaiseCallback(expectedResult);
            Assert.True(hasBeenCalled);
            Assert.Equal(expectedResult, result);
        }
        public void Watch_CompositeChangeToken_RegisterChangeCallbackReturnsACompositeDisposable()
        {
            // Arrange
            var firstChangeToken = new MockChangeToken { ActiveChangeCallbacks = true };
            var secondChangeToken = new MockChangeToken();
            var thirdChangeToken = new MockChangeToken { ActiveChangeCallbacks = false };
            var provider = new CompositeFileProvider(
                new MockFileProvider(
                    new KeyValuePair<string, IChangeToken>("pattern", firstChangeToken),
                    new KeyValuePair<string, IChangeToken>("2ndpattern", secondChangeToken)),
                new MockFileProvider(new KeyValuePair<string, IChangeToken>("pattern", thirdChangeToken)));

            // Act
            var changeToken = provider.Watch("pattern");

            // Assert
            Assert.NotNull(changeToken);
            Assert.True(changeToken.ActiveChangeCallbacks);
            Assert.False(changeToken.HasChanged);

            // Register callback
            Assert.Equal(0, firstChangeToken.Callbacks.Count);
            Assert.Equal(0, secondChangeToken.Callbacks.Count);
            Assert.Equal(0, thirdChangeToken.Callbacks.Count);
            object result = null;
            object state = new object();
            var disposable = changeToken.RegisterChangeCallback(item =>
            {
                result = item;
            }, state);
            Assert.Equal(1, firstChangeToken.Callbacks.Count);
            Assert.False(firstChangeToken.Callbacks[0].Item3.Disposed);
            Assert.Equal(0, secondChangeToken.Callbacks.Count);
            Assert.Equal(1, thirdChangeToken.Callbacks.Count);
            Assert.False(thirdChangeToken.Callbacks[0].Item3.Disposed);
            disposable.Dispose();
            Assert.Equal(1, firstChangeToken.Callbacks.Count);
            Assert.True(firstChangeToken.Callbacks[0].Item3.Disposed);
            Assert.Equal(0, secondChangeToken.Callbacks.Count);
            Assert.Equal(1, thirdChangeToken.Callbacks.Count);
            Assert.True(thirdChangeToken.Callbacks[0].Item3.Disposed);
        }
        public void Watch_CompositeChangeToken_HasChangedIsCorrectlyComputed()
        {
            // Arrange
            var firstChangeToken = new MockChangeToken();
            var secondChangeToken = new MockChangeToken();
            var thirdChangeToken = new MockChangeToken();
            var provider = new CompositeFileProvider(
                new MockFileProvider(
                    new KeyValuePair<string, IChangeToken>("pattern", firstChangeToken),
                    new KeyValuePair<string, IChangeToken>("2ndpattern", secondChangeToken)),
                new MockFileProvider(new KeyValuePair<string, IChangeToken>("pattern", thirdChangeToken)));

            // Act
            var changeToken = provider.Watch("pattern");

            // Assert
            Assert.NotNull(changeToken);
            Assert.False(changeToken.ActiveChangeCallbacks);
            Assert.False(changeToken.HasChanged);

            // HasChanged update
            // first change token
            firstChangeToken.HasChanged = true;
            Assert.True(changeToken.HasChanged);
            firstChangeToken.HasChanged = false;
            // second change token
            secondChangeToken.HasChanged = true;
            Assert.False(changeToken.HasChanged);
            secondChangeToken.HasChanged = false;
            // third change token
            thirdChangeToken.HasChanged = true;
            Assert.True(changeToken.HasChanged);
        }