using HypothesisTests, Test
using HypothesisTests: default_tail

@testset "Durbin-Watson" begin
x_sim = [
    0.2972879845354616, 0.3823959677906078, -0.5976344767282311, -0.01044524463737564,
    -0.839026854388764, 0.31111133849833383, 2.2950878238373105, -2.2670863488005306,
    0.5299655761667461, 0.43142152642291204, 0.5837082875687786, 0.9632716050381906,
    0.45879095505371686, -0.5223367574215084, 0.40839583832475224, -0.050451229933665284,
    -0.6936536438038856, -1.7738332534080556, 0.12076596493743928, -0.7576330377205277,
    -1.7297561813906863, 0.7959486220046159, 0.6700619812560624, 0.5508523775007609,
    -0.06337459242956062, 1.3369427822509223, -0.07314863333773934, -0.7454643166407556,
    -1.2200551285346526, -0.05317733752769253, -0.1651363578028337, -2.115370248427311,
    -0.0667679865065892, 1.2224618484680618, 0.5676954597384435, 0.7634989283233873,
    0.37859887985335006, -0.645597056636597, -0.6646462443910314, -1.8030263242108941,
    -1.2890476038497443, -0.3352700795181175, 0.07046760136115796, 0.34179376737982303,
    1.7351656660543822, 1.299915964310192, 0.20636408140261675, -1.0088599555376034,
    -0.8500556703153979, 1.1294094358843267, -1.348533456491827, 1.2402909004290597,
    -0.055647093207324264, 0.7593902139454598, -0.030266886646762546,
    -0.36108266775609366, -2.0073032025325626, -0.5688591273466379, -1.1496275243969976,
    1.880622174631185, -1.4706245413873802, -0.5352109701657319, -0.9635439598255011,
    -1.3851080676759138, 0.13430023756127, -0.6161166660088192, -1.719989356319742,
    0.32076927998741056, -1.4473728978815112, -0.4922711880695664, -0.4130873839831828,
    1.001928512455953, 1.174681325975111, -1.326970345062047, -1.593214868044067,
    -0.43870997575879667, 1.225797497997867, 1.4890902780696147, 2.1594331871008534,
    -0.9094790180375028, 1.1478203006125018, -0.5050721965223731, -0.2670670352181297,
    1.499082393930729, 0.7973041601753904, -0.17164044330709693, -0.46907960993009634,
    0.21762402120860017, 0.35914640760234967, 0.3200247157080577, 0.2592163280556861,
    0.459695985041628, 0.20998636004214272, 1.5231753911772645, 1.2597946036121963,
    -0.16528310111426064, 0.15619449488763584, -0.8143152943766987, -1.7098682060045913,
    1.4999378761140325, -0.1289156385300165
]

y_p1_sim = [ # simulated with 0.9 error correlation
    -2.201341073669063, -4.307803337512109, -0.09857411277132777, -1.541105730821739,
    -0.027145670802778188, -2.686792369309708, 1.0325029592455204, -4.546430983473314,
    -0.05574145987936152, -1.0484672373273398, -0.0727407422074402, 2.928588488596894,
    2.431548457465139, -1.6824694270670264, -1.1425390408702634, -0.05703441237172502,
    -3.7519965683524736, -2.093296650507312, -3.017127214946707, -5.023733247576096,
    -6.99222421705045, -1.5297654016216695, -7.079699435755043, -3.653535679506873,
    -7.199787077141922, -8.99013125698203, -7.629907186756253, -9.932939819777665,
    -5.792469964809508, -6.07806145541466, -3.499680333201193, -4.202234791648873,
    -5.778858317935674, -4.24373192427373, -2.085017620018707, -3.014335715988717,
    -0.1471613303199173, 1.8578539252085335, -0.23403766619329314, -1.6531056420525947,
    -3.788213810884947, 2.4223665300397057, -0.7782405228814611, -1.446646277164314,
    -0.439089647647926, -0.6568645300510487, -0.1479791111026496, -0.37816853906616543,
    -1.5546979990960859, 0.7934110284198954, 0.5250598397936805, 0.715179599821307,
    -2.6619881622077957, 0.6738306385872681, -0.5829579084083533, -1.6036851727710095,
    1.7676938677132092, 2.1178719441137925, -0.9822453774326113, 2.644398248982846,
    -0.4222365679492326, -0.08802559167948826, 0.004781669065527239, 0.772037726995288,
    -0.589376818822907, -0.009942853176962085, -1.2940732511754347, 3.3672146186572194,
    0.5720957571272467, 1.9994832545202734, -0.2408374457735749, 1.6235559488713027,
    4.765160983845028, 2.2423062077647176, 2.018531795146693, 3.6912668457665974,
    7.052100921101374, 2.891089489994272, 5.012011484448072, 2.9058206661961257,
    4.74433866373019, 4.522254758963782, 4.483117294212917, 7.161931707757217,
    6.608363617973065, 8.54801536915603, 5.975318310443797, 4.404349461089431,
    6.93366550050009, 4.447502046635322, 5.24747472180249, 6.072362283142831,
    5.9553560646539605, 3.2489334527924516, 3.5194287418405414, -0.24943173222751147,
    2.619648178234713, 4.7339671460783475, -1.5079676768571109, 3.805732205983656,
    2.384418539000519
]

# regression
n = length(y_p1_sim)
X = [ones(n, 1) x_sim]
b = X \ y_p1_sim
resid = y_p1_sim - X * b

t = DurbinWatsonTest(X, resid) # asymptotic p-values

@test t.n == 101
@test t.DW ≈ 0.40499929824035813
@test t.p_compute == :ndep
@test pvalue(t) ≈ 5.158964292454297e-16
@test pvalue(t, tail = :left) ≈ 0.9999999999999998
@test pvalue(t, tail = :right) ≈ 2.5794821462271485e-16
@test default_tail(t) == :both
show(IOBuffer(), t)

t = DurbinWatsonTest(X, resid; p_compute = :exact) # exact p-values

@test t.n == 101
@test t.DW ≈ 0.40499929824035813
@test t.p_compute == :exact
@test pvalue(t) ≈ 3.6994415420651786e-24
@test pvalue(t, tail = :left) ≈ 1.00
@test pvalue(t, tail = :right) ≈ 1.8497207710325893e-24
@test default_tail(t) == :both
show(IOBuffer(), t)

y_m1_sim = [ # simulated with -0.9 error correlation
    -1.3910099248613454, -1.5236862020915085, 4.097936666328973, -1.8511224691327444,
    4.089543164538723, -4.495552189456728, 7.111817193652225, -5.978343737983263,
    6.002151715790337, -2.927307499513737, 5.458083999297893, 1.169591175532601,
    4.594296073450898, -4.243581518221936, 2.8299935873046445, -0.5860831006926581,
    -0.9991240800029624, 0.10615464305915895, -1.7044498818807359, -0.9995564116656306,
    -3.5319792844484295, 4.179137229344947, -5.254163800722545, 5.711864125579977,
    -5.990925805935972, 1.5816393282765917, -1.7032484999745658, -0.617286443723021,
    1.5845107369357039, -0.6096898012505031, 3.3496253127300184, -1.1686422345229122,
    -1.5918280931408098, 1.1415907584907719, 3.006908809246799, 0.16279484914286346,
    4.785411299104295, 2.2981183100018683, 0.212429391905895, -1.163256462733893,
    -3.062755396990661, 5.4435487477430335, -3.425834811822814, 2.6321872628475,
    -0.837244387584767, 4.031062468957392, 0.24230351459424804, 2.563723587223389,
    -2.388107267343436, 3.894089606181092, -0.005377707121046793, 1.4234173532692622,
    -1.8229221872128627, 3.8287942020863945, -0.6858661742876399, 1.1178057096772471,
    2.5196873774438067, 0.38418130890537316, -1.4155851844623182, 2.8866125226188566,
    -0.4941340798489638, -0.0011241065963577546, 0.43409066782110806, 0.6425507130120189,
    -1.3986687332385075, 1.8531056183925938, -2.1057647202687244, 5.003685916104994,
    -2.3348521765098624, 3.0528589106154387, -3.234749402470284, 4.142408525714717,
    2.75967828902951, 1.8334770219703578, -0.9220644601902186, 2.498387343549808,
    3.580976074314626, -0.37369360814264785, 4.713559024928862, 0.05056665062182075,
    3.374560008823081, 1.6454107505584676, 1.5983424828203905, 3.9197926529917604,
    2.7024280115597086, 4.662666562844124, -0.805868878530069, 0.9823593012348448,
    2.8591273650074895, -0.12192899074208174, 2.8388011459132807, 1.716213267783003,
    2.7887106550396696, -1.3611491982524841, 3.6582922884633065, -3.3126745262864654,
    5.030080939945388, 1.0915507567022984, -2.9861092295546072, 3.7140067907674967,
    0.6518327501226435
]

# regression
n = length(y_m1_sim)
X = [ones(n, 1) x_sim]
b = X \ y_m1_sim
resid = y_m1_sim - X * b

t = DurbinWatsonTest(X, resid) # asymptotic p-values

@test t.n == 101
@test t.DW ≈ 3.1196941838878423
@test t.p_compute == :ndep
@test pvalue(t) ≈ 1.3691928363065143e-8
@test pvalue(t, tail = :left) ≈ 6.8459641815325715e-9
@test pvalue(t, tail = :right) ≈ 0.9999999931540359
@test default_tail(t) == :both
show(IOBuffer(), t)

t = DurbinWatsonTest(X, resid; p_compute = :exact) # exact p-values

@test t.n == 101
@test t.DW ≈ 3.1196941838878423
@test t.p_compute == :exact
@test pvalue(t) ≈ 6.608698033261362e-10
@test pvalue(t, tail = :left) ≈ 3.304349016630681e-10
@test pvalue(t, tail = :right) ≈ 0.9999999996695651
@test default_tail(t) == :both
show(IOBuffer(), t)

y_0_sim = [ # simulated with 0 error correlation
    -1.7961754992652044, -2.5510957528383353, 3.2525339877180928, 0.19231575061789374,
    1.89169121462802, -1.7386623034795425, 3.258218157382714, -2.526695955245271,
    2.3288443884260106, 0.7381645606308258, 1.8471935105613477, 4.537960965742147,
    2.7213734745790865, -1.9897890454508897, -0.30877316780251873, 1.466080926146517,
    -2.613632233922138, 0.24522161603320347, -1.3710354663088093, -2.4209400297411765,
    -3.4512221745897302, 2.881796133532548, -3.597925434303817, 1.8506552588011762,
    -2.380926529249864, -3.160258392310042, 0.09071892000097082, -2.6081167226985844,
    2.088064405287688, -0.024234312547235515, 2.385739734138283, 0.3967490275831522,
    -2.3202265548315593, 0.33309301826620985, 2.8843408018580714, 0.8655964597465511,
    3.7488337387014004, 4.297643800846097, 0.1873148360133016, -1.207270876248609,
    -3.205052473244388, 4.259413925143798, -0.7425056693856398, -0.598646937182016,
    1.1973080753889698, 1.507929336481593, 2.1567293512995978, 1.2684047056422159,
    -0.6475511763894612, 1.968716146589186, 1.6551464263288553, 0.8306015804336573,
    -1.9237481856587493, 2.628892109084551, 0.7853215622266103, -0.28924845119256015,
    3.3683615196802235, 1.5894237058883518, -1.9790760667912535, 2.570502472637483,
    -0.34918890076289344, -0.07692872949280205, 0.2585418367307264, 0.9004832694436649,
    -1.0522919323231783, 0.5574000211207956, -0.8615471735157796, 3.820189106289126,
    -0.14496612583980942, 1.218044512431157, -1.2637743788791052, 1.5357218567794906,
    4.895903296016806, 1.1354244022005544, 0.36426053387077517, 1.7715587797565924,
    4.779742721710445, -0.30330824012822477, 3.393632860526853, 1.3438900516253283,
    2.7745850292681986, 2.4674323600529258, 1.7461500847342628, 4.242713515247852,
    3.1964332401219315, 4.847669943114067, 0.8363177531165059, -0.35817985387610163,
    3.3565008608192253, 0.32924436697495, 1.9868939670380534, 2.810384666312773,
    2.4117663029348924, -0.4810983070564472, 1.5143233221817027, -1.7185645332767443,
    2.4464053017635212, 3.997453694160127, -3.8861258284250813, 3.094705799661703,
    1.4768492077143098
]

# regression
n = length(y_0_sim)
X = [ones(n, 1) x_sim]
b = X \ y_0_sim
resid = y_0_sim - X * b

t = DurbinWatsonTest(X, resid)

@test t.n == 101
@test t.DW ≈ 2.0315450779948154
@test t.p_compute == :ndep
@test pvalue(t) ≈ 0.8794168553233327
@test pvalue(t, tail = :left) ≈ 0.43970842766166635
@test pvalue(t, tail = :right) ≈ 0.5602915723383337
@test default_tail(t) == :both
show(IOBuffer(), t)

t = DurbinWatsonTest(X, resid; p_compute = :exact) # exact p-values

@test t.n == 101
@test t.DW ≈ 2.0315450779948154
@test t.p_compute == :exact
@test pvalue(t) ≈ 0.8794168553233327 # exact p-values outsid [0,1], use approx.
@test pvalue(t, tail = :left) ≈ 0.43970842766166635
@test pvalue(t, tail = :right) ≈ 0.5602915723383337
@test default_tail(t) == :both
show(IOBuffer(), t)

# test corner cases
t1 = DurbinWatsonTest(X, size(X,1), 0.00, :exact)

@test pvalue(t1) == 0.00
@test pvalue(t1, tail = :left) == 1.00
@test pvalue(t1, tail = :right) == 0.00
show(IOBuffer(), t1)

t1 = DurbinWatsonTest(X, size(X,1), 4.00, :exact)

@test pvalue(t1) == 0.00
@test pvalue(t1, tail = :left) == 0.00
@test pvalue(t1, tail = :right) == 1.00
show(IOBuffer(), t1)
end
