return function()local A=require(script.Parent.statistics)local m=100000 local Y=.05 it("\115\104\111\117\108\100 \103\105\118\101 \097\099\099\117\114\097\116\101 \115\116\097\116\105\115\116\105\099\097\108 \109\101\097\115\117\114\101\115",function()local m={1,2;3,4;5}local Y={1;1;2,3,4,5};(expect(A.series.sum(m))).to.equal(15);(expect(A.series.mean(m))).to.equal(3);(expect(A.series.median(m))).to.equal(3);(expect(A.series.median(Y))).to.equal(2.5);(expect(A.series.mode(Y))).to.equal(1);(expect(A.series.standardDeviation(m))).to.be.near(1.414213562)do local m=A.series.mode({1;1,2,2});(expect(#m)).to.equal(2);(expect(m[1])).to.equal(1);(expect(m[2])).to.equal(2)end local x,a=A.series.getExtremes(m);(expect(x)).to.equal(1);(expect(a)).to.equal(5)end)it("\115\104\111\117\108\100 \103\101\110\101\114\097\116\101 \115\101\114\105\101\115 \112\114\111\112\101\114\108\121",function()local m=A.series.generate(5,function()return 1 end);(expect(#m)).to.equal(5);(expect(m[1])).to.equal(1)end)it("\115\104\111\117\108\100 \103\105\118\101 \097\112\112\114\111\120\105\109\097\116\101 \110\111\114\109\097\108 \100\105\115\116\114\105\098\117\116\105\111\110\115",function()local x=A.series.generate(m,A.distributions.standardNormal);(expect(A.series.mean(x))).to.be.near(0,Y);(expect(A.series.standardDeviation(x))).to.be.near(1,Y)local a=A.series.generate(m,A.distributions.normal,1,1);(expect(A.series.mean(a))).to.be.near(1,Y);(expect(A.series.standardDeviation(a))).to.be.near(1,Y)end)it("\115\104\111\117\108\100 \103\105\118\101 \097\112\112\114\111\120\105\109\097\116\101 \101\120\112\111\110\101\110\116\105\097\108 \100\105\115\116\114\105\098\117\116\105\111\110\115",function()local x=2 local a=A.series.generate(m,A.distributions.exponential,x);(expect(A.series.mean(a))).to.be.near(1/x,Y);(expect(A.series.variance(a))).to.be.near(1/(x*x),Y)end)it("\115\104\111\117\108\100 \103\105\118\101 \097\112\112\114\111\120\105\109\097\116\101 \098\105\110\111\109\105\097\108 \100\105\115\116\114\105\098\117\116\105\111\110\115",function()local x=100 local a=.5 local s=A.series.generate(m,A.distributions.binomial,x,a);(expect(A.series.mean(s))).to.be.near(x*a,Y);(expect(A.series.variance(s))).to.be.near((x*a)*(1-a),Y)end)it("\115\104\111\117\108\100 \103\105\118\101 \097\112\112\114\111\120\105\109\097\116\101 \115\116\097\110\100\097\114\100 \100\105\115\099\114\101\116\101 \100\105\115\116\114\105\098\117\116\105\111\110\115",function()local x=A.series.generate(m,A.distributions.standardDiscrete,{.01;.99},{0;1});(expect(A.series.mean(x))).to.be.near(1,Y);(expect(A.distributions.standardDiscrete({-0.1;-0.1},{1;2}))).to.equal(2)end)it("\115\104\111\117\108\100 \103\105\118\101 \097\112\112\114\111\120\105\109\097\116\101 \103\101\111\109\101\116\114\105\099 \100\105\115\116\114\105\098\117\116\105\111\110\115",function()local x=.5 local a=A.series.generate(m,A.distributions.geometric,x);(expect(A.series.mean(a))).to.be.near((1-x)/x,Y);(expect(A.series.variance(a))).to.be.near((1-x)/(x*x),Y)end)end
return function()
	local statistics = require(script.Parent.statistics)
	local generatedSeriesLength = 100000
	local epsilon = 0.05

	it("should give accurate statistical measures", function()
		local odd = { 1, 2, 3, 4, 5 } -- Odd length series
		local even = { 1, 1, 2, 3, 4, 5 } -- Even length series

		expect(statistics.series.sum(odd)).to.equal(15)
		expect(statistics.series.mean(odd)).to.equal(3)
		expect(statistics.series.median(odd)).to.equal(3)
		expect(statistics.series.median(even)).to.equal(2.5)
		expect(statistics.series.mode(even)).to.equal(1)
		expect(statistics.series.standardDeviation(odd)).to.be.near(1.414213562)

		-- Check that the mode function can return multiple values
		do
			local mode = statistics.series.mode({1, 1, 2, 2})
			expect(#mode).to.equal(2)
			expect(mode[1]).to.equal(1)
			expect(mode[2]).to.equal(2)
		end

		local min, max = statistics.series.getExtremes(odd)
		expect(min).to.equal(1)
		expect(max).to.equal(5)
	end)

	it("should generate series properly", function()
		local generatedSeries = statistics.series.generate(5, function() return 1 end)

		expect(#generatedSeries).to.equal(5)
		expect(generatedSeries[1]).to.equal(1)
	end)

	it("should give approximate normal distributions", function()
		local standardNormalSeries = statistics.series.generate(
			generatedSeriesLength,
			statistics.distributions.standardNormal
		)
		expect(statistics.series.mean(standardNormalSeries)).to.be.near(0, epsilon)
		expect(statistics.series.standardDeviation(standardNormalSeries)).to.be.near(1, epsilon)

		local nonStandardNormalSeries = statistics.series.generate(
			generatedSeriesLength,
			statistics.distributions.normal, 1, 1
		)
		expect(statistics.series.mean(nonStandardNormalSeries)).to.be.near(1, epsilon)
		expect(statistics.series.standardDeviation(nonStandardNormalSeries)).to.be.near(1, epsilon)
	end)

	it("should give approximate exponential distributions", function()
		local lambda = 2

		local exponentialSeries = statistics.series.generate(
			generatedSeriesLength,
			statistics.distributions.exponential,
			lambda
		)
		expect(statistics.series.mean(exponentialSeries)).to.be.near(1 / lambda, epsilon)
		expect(statistics.series.variance(exponentialSeries)).to.be.near(1 / (lambda * lambda), epsilon)
	end)

	it("should give approximate binomial distributions", function()
		-- This will inherently also test the bernoulli distribution

		local n = 100
		local p = 0.5

		local binomalSeries = statistics.series.generate(
			generatedSeriesLength,
			statistics.distributions.binomial,
			n,
			p
		)
		expect(statistics.series.mean(binomalSeries)).to.be.near(n * p, epsilon)
		expect(statistics.series.variance(binomalSeries)).to.be.near(n * p * (1 - p), epsilon)
	end)

	it("should give approximate standard discrete distributions", function()
		local standardDiscreteSeries = statistics.series.generate(
			generatedSeriesLength,
			statistics.distributions.standardDiscrete,
			{0.01, 0.99},
			{0, 1}
		)
		expect(statistics.series.mean(standardDiscreteSeries)).to.be.near(1, epsilon)

		expect(statistics.distributions.standardDiscrete({-0.1, -0.1}, {1, 2})).to.equal(2)
	end)

	it("should give approximate geometric distributions", function()
		local p = 0.5

		local exponentialSeries = statistics.series.generate(
			generatedSeriesLength,
			statistics.distributions.geometric,
			p
		)
		expect(statistics.series.mean(exponentialSeries)).to.be.near((1 - p) / p, epsilon)
		expect(statistics.series.variance(exponentialSeries)).to.be.near((1 - p) / (p * p), epsilon)
	end)
end