Skip to content

Instantly share code, notes, and snippets.

@praschl
Last active March 1, 2016 19:51
Show Gist options
  • Select an option

  • Save praschl/a25095a8f6169428faa0 to your computer and use it in GitHub Desktop.

Select an option

Save praschl/a25095a8f6169428faa0 to your computer and use it in GitHub Desktop.
Shows a problem in RavenDb 3 with queries for nullable Values, when the queried value is a property of an item in a collection of the aggregate root
// required references:
// Microsoft.VisualStudio.QualityTools.UnitTestFramework
// Raven.Abstractions (3.0)
// Raven.Client.Lightweight (3.0)
// Raven.Database (3.0)
// System
// Sstem.ComponentModel.Composition
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Raven.Client;
using Raven.Client.Document;
using Raven.Client.Embedded;
namespace NullableValueTests
{
public class MyAggregate
{
public MyAggregate(params MyValue[] myValues)
{
MyValues = myValues.ToArray();
}
// assigned by ravendb when materializing
public Guid Id { get; }
public IReadOnlyList<MyValue> MyValues { get; }
}
public class MyValue
{
public MyValue(string name, long? value)
{
Name = name;
Value = value;
}
public string Name { get; }
public long? Value { get; }
}
[TestClass]
public class EmbeddedInMemory : NullableTests
{
[TestInitialize]
public void TestInitialize()
{
DocumentStore = new EmbeddableDocumentStore
{
Conventions =
{
DefaultQueryingConsistency = ConsistencyOptions.AlwaysWaitForNonStaleResultsAsOfLastWrite
},
RunInMemory = true
};
Initialize();
}
}
// same problem with embedded file
//[TestClass]
//public class EmbeddedFile : NullableTests
//{
// [TestInitialize]
// public void TestInitialize()
// {
// DocumentStore = new EmbeddableDocumentStore
// {
// DataDirectory = "Data_" + Guid.NewGuid(),
// Conventions =
// {
// DefaultQueryingConsistency = ConsistencyOptions.AlwaysWaitForNonStaleResultsAsOfLastWrite
// }
// };
// Initialize();
// }
//}
// and same problem with a hosted ravendb.
//[TestClass]
//public class HostedDatabase : NullableTests
//{
// [TestInitialize]
// public void TestInitialize()
// {
// DocumentStore = new DocumentStore
// {
// Url = "http://localhost:8080",
// DefaultDatabase = "NullableTests",
// Conventions =
// {
// DefaultQueryingConsistency = ConsistencyOptions.AlwaysWaitForNonStaleResultsAsOfLastWrite
// }
// };
// Initialize();
// }
//}
public abstract class NullableTests
{
private IDocumentSession _session;
protected IDocumentStore DocumentStore;
protected long DeadFood = 0xDEADF00D;
protected long DeadBeef = 0xDEADBEEF;
protected void Initialize()
{
DocumentStore.Initialize();
Clear();
using (var session = DocumentStore.OpenSession())
{
session.Store(new MyAggregate(new MyValue("One", DeadFood)));
session.Store(new MyAggregate(new MyValue("Two", null)));
session.Store(new MyAggregate(new MyValue("Three", DeadBeef)));
session.Store(new MyAggregate(new MyValue("Four", null)));
session.Store(new MyAggregate(new MyValue("Five", null)));
session.SaveChanges();
}
_session = DocumentStore.OpenSession();
}
private void Clear()
{
// clear the test database (if running file or hosted)
while (true)
{
using (var session = DocumentStore.OpenSession())
{
var items = session.Query<MyAggregate>().Take(100).ToList();
if (items.Count == 0)
break;
foreach (var myAggregate in items)
{
session.Delete(myAggregate);
}
session.SaveChanges();
}
}
}
[TestCleanup]
public void Cleanup()
{
DocumentStore?.Dispose();
}
[TestMethod]
public void Get_All()
{
var items = _session.Query<MyAggregate>().ToList();
var count = items.Count(i => i.MyValues.Any(d => d.Value == DeadFood));
Assert.AreEqual(1, count);
count = items.Count(i => i.MyValues.Any(d => d.Value.HasValue));
Assert.AreEqual(2, count);
count = items.Count(i => i.MyValues.Any(d => !d.Value.HasValue));
Assert.AreEqual(3, count);
}
[TestMethod]
public void Get_Those_With_Given_Value()
{
var items = _session.Query<MyAggregate>().FirstOrDefault(a => a.MyValues.Any(d => d.Value == DeadBeef));
Assert.IsNotNull(items);
Assert.AreEqual("Three", items.MyValues.First().Name);
}
[TestMethod]
public void Get_Those_Which_Are_Not_Null()
{
var items = _session.Query<MyAggregate>().Where(a => a.MyValues.Any(d => d.Value != null)).ToList();
Assert.AreEqual(2, items.Count);
}
// next three tests fail
[TestMethod]
public void Get_Those_Which_Have_Value()
{
// this test is not even consistent with Get_Those_Which_Are_Not_Null
// this one fails, while the other succeeds although having a value and being not null should be the same.
var items = _session.Query<MyAggregate>().Where(a => a.MyValues.Any(d => d.Value.HasValue)).ToList();
Assert.AreEqual(2, items.Count);
}
[TestMethod]
public void Get_Those_Which_Are_Null()
{
var items = _session.Query<MyAggregate>().Where(a => a.MyValues.Any(d => d.Value == null)).ToList();
Assert.AreEqual(3, items.Count);
}
[TestMethod]
public void Get_Those_Which_Do_Not_Have_Value()
{
var items = _session.Query<MyAggregate>().Where(a => a.MyValues.Any(d => !d.Value.HasValue)).ToList();
Assert.AreEqual(3, items.Count);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment