public void TestTrendRequest_IsValid_True_If_Enough_Valid_Values()
        {
            var dataList = DataList();

            // Add invalid data point after 5 more recent points
            dataList.Add(new CoreDataSet
            {
                Value = ValueData.NullValue,
                Denominator = 4,
                Count = 8,
                Year = 2000
            });

            var trendRequest = new TrendRequest()
            {
                UnitValue = 1,
                ValueTypeId = ValueTypeIds.Proportion,
                YearRange = 1,
                Data = dataList
            };

            string validationMessage = null;
            var isValid = trendRequest.IsValid(ref validationMessage);
            Assert.IsTrue(isValid, validationMessage);
        }
        public void TestTrendRequest_IsValid_True_If_Enough_Recent_Values()
        {
            var trendRequest = new TrendRequest()
            {
                UnitValue = 1,
                ValueTypeId = ValueTypeIds.Proportion,
                YearRange = 1,
                Data = DataList()
            };

            string validationMessage = null;
            var isValid = trendRequest.IsValid(ref validationMessage);
            Assert.IsTrue(isValid, validationMessage);
        }
        public void TestTrendRequestIsInvalidForYearRangeGreaterThan1()
        {
            var trendRequest = new TrendRequest()
            {
                UnitValue = 1,
                ValueTypeId = ValueTypeIds.Proportion,
                YearRange = 3
            };

            string validationMessage = null;
            trendRequest.IsValid(ref validationMessage);
            Assert.IsTrue(validationMessage == "The recent trend cannot be calculated for this year range");
        }
        public void TestTrendRequest_IsValid_False_If_Value_Invalid()
        {
            var dataList = DataList();
            dataList[0].Value = ValueData.NullValue;

            var trendRequest = new TrendRequest()
            {
                UnitValue = 1,
                ValueTypeId = ValueTypeIds.Proportion,
                YearRange = 1,
                Data = dataList
            };

            string validationMessage = null;
            trendRequest.IsValid(ref validationMessage);
            Assert.AreEqual("Not enough data points with valid values to calculate recent trend", validationMessage);
        }
        public void TestTrendRequestIsInvalidForNonRelevantValueType()
        {
            var trendRequest = new TrendRequest()
            {
                UnitValue = 1,
                ValueTypeId = ValueTypeIds.Count,
                YearRange = 1
            };

            string validationMessage = null;
            trendRequest.IsValid(ref validationMessage);
            Assert.IsTrue(validationMessage == "The recent trend cannot be calculated for this value type");
        }
        private bool IsSignificant(TrendRequest trendRequest, ref int pointsUsed, ref double chiSquare, ref string message)
        {
            chiSquare = 0.0;

            if (trendRequest.IsValid(ref message) == false)
            {
                pointsUsed = 0;

                return false;
            }

            // Chi squared confidence 
            const double chiSquared99Point8 = 9.54953570608324; // inExcel =CHIINV(0.002,1)
            double chiSquaredConfidence = chiSquared99Point8;

            var fullDataList = trendRequest.Data.ToList();
            for (int pointsToUse = MinimumNumberOfPoints; pointsToUse <= fullDataList.Count; pointsToUse++)
            {
                pointsUsed = pointsToUse;

                double sumOfr = 0;
                double sumOfn = 0;
                double sumOfrAndt = 0;
                double sumOfnAndt = 0;
                double sumOfnAndtSq = 0;
                double t = pointsUsed;

                var dataList = GetMostRecentDataOrderedByIncreasingYear(fullDataList, pointsToUse);
                foreach (var coreDataSet in dataList)
                {
                    var r = coreDataSet.Count.Value;
                    var n = coreDataSet.Denominator;

                    sumOfr += r;
                    sumOfn += n;
                    sumOfrAndt += r * t;
                    sumOfnAndt += n * t;
                    sumOfnAndtSq += n * (t * t);

                    t--;
                }

                var sumPart1 = ((sumOfn * sumOfrAndt) - (sumOfr * sumOfnAndt));

                chiSquare = (sumOfn * (sumPart1 * sumPart1)) /
                            (sumOfr * (sumOfn - sumOfr) * (sumOfn * sumOfnAndtSq - (sumOfnAndt * sumOfnAndt)));

                if (chiSquare > chiSquaredConfidence)
                {
                    return true;
                }
            }

            return false;
        }