public async Task Given_SingleEntity_Should_TimeTravel()
        {
            var context = TestHelper.GetNewDbContext();
            var appleId = Guid.Parse("00000002-8803-4263-ada6-cd12a33d8872");

            context.Apples.Add(new Apple {
                Id = appleId, FruitStatus = FruitStatus.Ripe
            });
            await context.SaveChangesAsync();

            var ripeAppleTime = TestHelper.UtcNow;

            context = TestHelper.GetNewDbContext();
            var ripeApple = await context.Apples.SingleAsync(a => a.Id == appleId);

            ripeApple.FruitStatus = FruitStatus.Rotten;
            await context.SaveChangesAsync();

            context = TestHelper.GetNewDbContext();
            var currentApple = await context.Apples.AsNoTracking().SingleAsync(a => a.Id == appleId);

            currentApple.FruitStatus.Should().Be(FruitStatus.Rotten);

            using (TemporalQuery.AsOf(ripeAppleTime))
            {
                var timeTravelApple = await context.Apples.AsNoTracking().SingleAsync(a => a.Id == appleId);

                timeTravelApple.FruitStatus.Should().Be(FruitStatus.Ripe);
            }
        }
Exemple #2
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query)
        public override R query <R>(TemporalQuery <R> query)
        {
            if (query == TemporalQueries.ZoneId())
            {
                return((R)Zone);
            }
            else if (query == TemporalQueries.Chronology())
            {
                return((R)Chrono);
            }
            else if (query == TemporalQueries.LocalDate())
            {
                return((R)(Date != java.time.temporal.TemporalAccessor_Fields.Null ? LocalDate.From(Date) : java.time.temporal.TemporalAccessor_Fields.Null));
            }
            else if (query == TemporalQueries.LocalTime())
            {
                return((R)Time);
            }
            else if (query == TemporalQueries.Zone() || query == TemporalQueries.Offset())
            {
                return(query.QueryFrom(this));
            }
            else if (query == TemporalQueries.Precision())
            {
                return(java.time.temporal.TemporalAccessor_Fields.Null);                // not a complete date/time
            }
            // inline TemporalAccessor.super.query(query) as an optimization
            // non-JDK classes are not permitted to make this optimization
            return(query.QueryFrom(this));
        }
Exemple #3
0
        //-----------------------------------------------------------------------
        /// <summary>
        /// Queries this offset using the specified query.
        /// <para>
        /// This queries this offset using the specified query strategy object.
        /// The {@code TemporalQuery} object defines the logic to be used to
        /// obtain the result. Read the documentation of the query to understand
        /// what the result of this method will be.
        /// </para>
        /// <para>
        /// The result of this method is obtained by invoking the
        /// <seealso cref="TemporalQuery#queryFrom(TemporalAccessor)"/> method on the
        /// specified query passing {@code this} as the argument.
        ///
        /// </para>
        /// </summary>
        /// @param <R> the type of the result </param>
        /// <param name="query">  the query to invoke, not null </param>
        /// <returns> the query result, null may be returned (defined by the query) </returns>
        /// <exception cref="DateTimeException"> if unable to query (defined by the query) </exception>
        /// <exception cref="ArithmeticException"> if numeric overflow occurs (defined by the query) </exception>
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query)
        public override R query <R>(TemporalQuery <R> query)
        {
            if (query == TemporalQueries.Offset() || query == TemporalQueries.Zone())
            {
                return((R)this);
            }
            return(TemporalAccessor.this.query(query));
        }
Exemple #4
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query)
            public override R query <R>(TemporalQuery <R> query)
            {
                if (query == TemporalQueries.ZoneId())
                {
                    return((R)ZoneId.this);
                }
                return(TemporalAccessor.this.query(query));
            }
Exemple #5
0
        //-----------------------------------------------------------------------
        /// <summary>
        /// Queries this month-day using the specified query.
        /// <para>
        /// This queries this month-day using the specified query strategy object.
        /// The {@code TemporalQuery} object defines the logic to be used to
        /// obtain the result. Read the documentation of the query to understand
        /// what the result of this method will be.
        /// </para>
        /// <para>
        /// The result of this method is obtained by invoking the
        /// <seealso cref="TemporalQuery#queryFrom(TemporalAccessor)"/> method on the
        /// specified query passing {@code this} as the argument.
        ///
        /// </para>
        /// </summary>
        /// @param <R> the type of the result </param>
        /// <param name="query">  the query to invoke, not null </param>
        /// <returns> the query result, null may be returned (defined by the query) </returns>
        /// <exception cref="DateTimeException"> if unable to query (defined by the query) </exception>
        /// <exception cref="ArithmeticException"> if numeric overflow occurs (defined by the query) </exception>
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query)
        public override R query <R>(TemporalQuery <R> query)
        {
            if (query == TemporalQueries.Chronology())
            {
                return((R)IsoChronology.INSTANCE);
            }
            return(TemporalAccessor.this.query(query));
        }
        /// <summary>
        /// Gets a value using a query.
        /// </summary>
        /// <param name="query">  the query to use, not null </param>
        /// <returns> the result, null if not found and optional is true </returns>
        /// <exception cref="DateTimeException"> if the type is not available and the section is not optional </exception>
        internal R getValue <R>(TemporalQuery <R> query)
        {
            R result = Temporal_Renamed.query(query);

            if (result == null && Optional == 0)
            {
                throw new DateTimeException("Unable to extract value: " + Temporal_Renamed.GetType());
            }
            return(result);
        }
        private static async Task AssertWormlessFruitStatusAtTime(
            FruitStatus expectedFruitStatus,
            DateTime appleTime,
            Guid appleId)
        {
            using (TemporalQuery.AsOf(appleTime))
            {
                var apple = await GetApple(appleId);

                apple
                .Should()
                .BeEquivalentTo(new { FruitStatus = expectedFruitStatus, Worms = Array.Empty <Worm>() },
                                options => options.ExcludingMissingMembers());
            }
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query)
            public override R query <R>(TemporalQuery <R> query)
            {
                if (query == TemporalQueries.Chronology())
                {
                    return((R)EffectiveChrono);
                }
                if (query == TemporalQueries.ZoneId())
                {
                    return((R)EffectiveZone);
                }
                if (query == TemporalQueries.Precision())
                {
                    return(Temporal.query(query));
                }
                return(query.QueryFrom(this));
            }
        public async Task Given_IncludedCollection_Should_TimeTravelIncludedCollection()
        {
            var context = TestHelper.GetNewDbContext();
            var appleId = Guid.Parse("00000003-8803-4263-ada6-cd12a33d8872");

            var apple = new Apple {
                Id = appleId, FruitStatus = FruitStatus.Rotten
            };

            apple.AddWorm("Gav");
            context.Apples.Add(apple);

            await context.SaveChangesAsync();

            var rottenAppleTime = TestHelper.UtcNow;

            context = TestHelper.GetNewDbContext();

            apple = await context.Apples.SingleAsync(a => a.Id == appleId);

            apple.AddWorm("G-Dog");
            apple.AddWorm("Gavin' A Laugh");

            await context.SaveChangesAsync();

            context = TestHelper.GetNewDbContext();

            var currentApple = await context.Apples
                               .Include(a => a.Worms)
                               .SingleAsync(a => a.Id == appleId);

            currentApple.Worms.Count.Should().Be(3);

            using (TemporalQuery.AsOf(rottenAppleTime))
            {
                // Let's use the same context for time travel
                var timeTravelApple = await context.Apples
                                      .Include(a => a.Worms)
                                      // All temporal queries must be .AsNoTracking()
                                      .AsNoTracking()
                                      .SingleAsync(a => a.Id == appleId);

                timeTravelApple.Worms.Count.Should().Be(1);
            }
        }
        private static async Task AssertWormsNavigationPropertyAtRottenAppleTime(DateTime rottenAppleTime, Guid appleId)
        {
            using (TemporalQuery.AsOf(rottenAppleTime))
            {
                using var localScope = ServiceProvider.CreateScope();
                var context = localScope.ServiceProvider.GetService <ApplicationDbContext>();

                var rottenAppleWorms = await context.Apples
                                       .Where(a => a.Id == appleId)
                                       .SelectMany(a => a.Worms)
                                       .Include(worm => worm.Weapons)
                                       .AsNoTracking().ToListAsync();

                rottenAppleWorms
                .Should()
                .BeEquivalentTo(new[] { new { Name = "Moe", Weapons = new[] { new { Name = "Bazooka" } } } },
                                options => options.ExcludingMissingMembers());
            }
        }
        public async Task TemporalQuery_Should_AllowAllTemporalEntitiesToTimeTravel()
        {
            var(appleId, unripeAppleTime, ripeAppleTime, rottenAppleTime) = await SimulateLifecycleOfMyApple();

            // Validate current state of my apple
            var currentApple = await GetApple(appleId);

            currentApple
            .Should()
            .BeEquivalentTo(
                new
            {
                FruitStatus = FruitStatus.Fuzzy,
                Worms       = new object[]
                {
                    new
                    {
                        Name    = "Hairy",
                        Weapons = new[]
                        {
                            new { Name = "Holy Hand Grenade" }, new { Name = "Super Banana Bomb" }
                        },
                        FriendsNames = new[] { "Joan", "Starr", "Curly" }
                    },
                    new { Name = "Curly" },
                    new
                    {
                        Name         = "Moe",
                        Weapons      = new[] { new { Name = "Bazooka Pie" } },
                        FriendsNames = new[] { "John" }
                    }
                }
            }, options => options.ExcludingMissingMembers());

            // Query the state of my apple a prior "system time" when the apple was rotten
            using (TemporalQuery.AsOf(rottenAppleTime))
            {
                var rottenApple = await GetApple(appleId);

                rottenApple
                .Should()
                .BeEquivalentTo(
                    new
                {
                    FruitStatus = FruitStatus.Rotten,
                    Worms       = new object[]
                    {
                        new
                        {
                            Name         = "Moe",
                            Weapons      = new[] { new { Name = "Bazooka" } },
                            FriendsNames = new[] { "John", "Ringo" }
                        }
                    }
                },
                    options => options.ExcludingMissingMembers());
            }


            await Task.WhenAll(new[]
            {
                AssertWormlessFruitStatusAtTime(FruitStatus.Ripe, ripeAppleTime, appleId),
                AssertWormlessFruitStatusAtTime(FruitStatus.Unripe, unripeAppleTime, appleId),
                AssertWormsNavigationPropertyAtRottenAppleTime(rottenAppleTime, appleId)
            });
        }