public void TestCachingReferenceResolver()
        {
            var resolver = new CachingReferenceResolver();

            var s1 = new Sub {
                Id = 1, X = 1
            };
            var s2 = new Sub {
                Id = 2, X = 2
            };
            var s3 = new Sub {
                Id = 3, X = 3
            };

            var d = new Data {
                Name = "foo", Subs = new List <Sub> {
                    s1, s2
                }
            };

            var json = JsonConvert.SerializeObject(d, Formatting.None, new JsonSerializerSettings {
                ReferenceResolverProvider = () => resolver
            });
            var jobject = JsonConvert.DeserializeObject(json) as JObject;

            Assert.AreEqual("foo", jobject.Value <string>("Name"));

            // make sure non-annotated Data class doesn't get Ids
            Assert.IsNull(jobject.Value <string>("$id"));

            var subs  = jobject.Value <JArray>("Subs");
            var s1_j  = subs[0];
            var s2_j  = subs[1];
            var guid1 = s1_j.Value <string>("$id");
            var guid2 = s2_j.Value <string>("$id");

            Assert.AreEqual(s1.Id, s1_j.Value <int>("Id"));
            Assert.AreEqual(s1.X, s1_j.Value <float>("X"));

            Assert.AreEqual(s2.Id, s2_j.Value <int>("Id"));
            Assert.AreEqual(s2.X, s2_j.Value <float>("X"));

            d = new Data {
                Name = "bar", Subs = new List <Sub> {
                    s2, s3
                }
            };
            json = JsonConvert.SerializeObject(d, Formatting.None, new JsonSerializerSettings {
                ReferenceResolverProvider = () => resolver
            });
            jobject = JsonConvert.DeserializeObject(json) as JObject;

            Assert.AreEqual("bar", jobject.Value <string>("Name"));
            subs = jobject.Value <JArray>("Subs");
            s2_j = subs[0];
            var s3_j = subs[1];

            Assert.AreEqual(guid2, s2_j.Value <string>("$ref"));

            Assert.AreEqual(s3.Id, s3_j.Value <int>("Id"));
            Assert.AreEqual(s3.X, s3_j.Value <float>("X"));

            Thread.Sleep(TimeSpan.FromSeconds(1.5));

            d = new Data {
                Name = "zoo", Subs = new List <Sub> {
                    s1
                }
            };
            json = JsonConvert.SerializeObject(d, Formatting.None, new JsonSerializerSettings {
                ReferenceResolverProvider = () => resolver
            });
            jobject = JsonConvert.DeserializeObject(json) as JObject;

            Assert.AreEqual("zoo", jobject.Value <string>("Name"));
            subs = jobject.Value <JArray>("Subs");
            s1_j = subs[0];

            Assert.AreEqual(s1_j.Value <string>("$ref"), guid1);
        }
        public void TestCachingReferenceResolver_Size()
        {
            var resolver = new CachingReferenceResolver(2);

            var s1 = new Sub {
                Id = 1, X = 1
            };
            var s2 = new Sub {
                Id = 2, X = 2
            };
            var s3 = new Sub {
                Id = 3, X = 3
            };

            var d = new Data {
                Name = "foo", Subs = new List <Sub> {
                    s1, s2
                }
            };

            var json = JsonConvert.SerializeObject(d, Formatting.None, new JsonSerializerSettings {
                ReferenceResolverProvider = () => resolver
            });
            var jobject = JsonConvert.DeserializeObject(json) as JObject;

            Assert.AreEqual("foo", jobject.Value <string>("Name"));

            var subs  = jobject.Value <JArray>("Subs");
            var s1_j  = subs[0];
            var s2_j  = subs[1];
            var guid1 = s1_j.Value <string>("$id");
            var guid2 = s2_j.Value <string>("$id");

            Assert.AreEqual(s1.Id, s1_j.Value <int>("Id"));
            Assert.AreEqual(s1.X, s1_j.Value <float>("X"));

            Assert.AreEqual(s2.Id, s2_j.Value <int>("Id"));
            Assert.AreEqual(s2.X, s2_j.Value <float>("X"));

            Thread.Sleep(20);

            d = new Data {
                Name = "bar", Subs = new List <Sub> {
                    s2, s3
                }
            };
            json = JsonConvert.SerializeObject(d, Formatting.None, new JsonSerializerSettings {
                ReferenceResolverProvider = () => resolver
            });
            jobject = JsonConvert.DeserializeObject(json) as JObject;

            Assert.AreEqual("bar", jobject.Value <string>("Name"));
            subs = jobject.Value <JArray>("Subs");
            s2_j = subs[0];
            var s3_j = subs[1];

            Assert.AreEqual(guid2, s2_j.Value <string>("$ref"));

            Assert.AreEqual(s3.Id, s3_j.Value <int>("Id"));
            Assert.AreEqual(s3.X, s3_j.Value <float>("X"));

            // make sure the right values are removed
            Thread.Sleep(20);

            d = new Data {
                Name = "zoo", Subs = new List <Sub> {
                    s1
                }
            };
            json = JsonConvert.SerializeObject(d, Formatting.None, new JsonSerializerSettings {
                ReferenceResolverProvider = () => resolver
            });
            jobject = JsonConvert.DeserializeObject(json) as JObject;

            Assert.AreEqual("zoo", jobject.Value <string>("Name"));
            subs = jobject.Value <JArray>("Subs");
            s1_j = subs[0];

            Assert.AreNotEqual(s1_j.Value <string>("$ref"), guid1);
        }