11from unittest .mock import Mock , sentinel
2+ import pytest
3+ import datetime as dt
4+ import cftime
5+ import numpy as np
26import re
37
48import forest .db .database as database
@@ -18,12 +22,21 @@ def _assert_query_and_params(db, expected_query, expected_params):
1822 db .cursor .execute .assert_called_once ()
1923 args , kwargs = db .cursor .execute .call_args
2024 query , params = args
21- query = re .sub (r'\s+' , ' ' , query ).strip ()
22- assert query == expected_query
25+ assert_query_equal (query , expected_query )
2326 assert params == expected_params
2427 assert kwargs == {}
2528
2629
30+ def assert_query_equal (left , right ):
31+ left , right = single_spaced (left ), single_spaced (right )
32+ assert left == right
33+
34+
35+ def single_spaced (query ):
36+ query = query .replace ("\n " , "" )
37+ return re .sub (r'\s+' , ' ' , query ).strip ()
38+
39+
2740def test_Database_valid_times__defaults ():
2841 db = _create_db ()
2942
@@ -39,7 +52,7 @@ def test_Database_valid_times__all_args():
3952 db = _create_db ()
4053
4154 valid_times = db .valid_times (sentinel .pattern , sentinel .variable ,
42- sentinel . initial_time )
55+ dt . datetime ( 2020 , 1 , 1 ) )
4356
4457 _assert_query_and_params (
4558 db , 'SELECT time.value FROM time'
@@ -49,10 +62,94 @@ def test_Database_valid_times__all_args():
4962 ' WHERE file.reference = :initial_time'
5063 ' AND file.name GLOB :pattern AND v.name = :variable' ,
5164 {'pattern' : sentinel .pattern , 'variable' : sentinel .variable ,
52- 'initial_time' :sentinel . initial_time })
65+ 'initial_time' : "2020-01-01 00:00:00" })
5366 assert valid_times == [sentinel .value1 , sentinel .value2 ]
5467
5568
69+ @pytest .mark .parametrize ("pattern, variable, initial_time, expect" , [
70+ (None , None , None , """
71+ SELECT time.value FROM time
72+ """ ),
73+ (sentinel .pattern , None , None , """
74+ SELECT time.value FROM time
75+ JOIN variable_to_time AS vt ON vt.time_id = time.id
76+ JOIN variable AS v ON vt.variable_id = v.id
77+ JOIN file ON v.file_id = file.id
78+ WHERE file.name GLOB :pattern
79+ """ ),
80+ (None , sentinel .variable , None , """
81+ SELECT time.value FROM time
82+ JOIN variable_to_time AS vt ON vt.time_id = time.id
83+ JOIN variable AS v ON vt.variable_id = v.id
84+ JOIN file ON v.file_id = file.id
85+ WHERE v.name = :variable
86+ """ ),
87+ (sentinel .pattern , sentinel .variable , None , """
88+ SELECT time.value FROM time
89+ JOIN variable_to_time AS vt ON vt.time_id = time.id
90+ JOIN variable AS v ON vt.variable_id = v.id
91+ JOIN file ON v.file_id = file.id
92+ WHERE file.name GLOB :pattern AND v.name = :variable
93+ """ ),
94+ (sentinel .pattern , sentinel .variable , sentinel .initial_time , """
95+ SELECT time.value FROM time
96+ JOIN variable_to_time AS vt ON vt.time_id = time.id
97+ JOIN variable AS v ON vt.variable_id = v.id
98+ JOIN file ON v.file_id = file.id
99+ WHERE file.reference = :initial_time
100+ AND file.name GLOB :pattern AND v.name = :variable
101+ """ ),
102+ ])
103+ def test_valid_times_query (pattern , variable , initial_time , expect ):
104+ result = database .Database .valid_times_query (pattern , variable , initial_time )
105+ assert_query_equal (expect , result )
106+
107+
108+ @pytest .mark .parametrize ("pattern, variable, initial_time, expect" , [
109+ (None , None , None , """
110+ SELECT DISTINCT value FROM pressure
111+ ORDER BY value
112+ """ ),
113+ (sentinel .pattern , None , None , """
114+ SELECT DISTINCT pressure.value FROM pressure
115+ JOIN variable_to_pressure AS vp ON vp.pressure_id = pressure.id
116+ JOIN variable AS v ON v.id = vp.variable_id
117+ JOIN file ON v.file_id = file.id
118+ WHERE file.name GLOB :pattern
119+ ORDER BY value
120+ """ ),
121+ (None , sentinel .variable , None , """
122+ SELECT DISTINCT pressure.value FROM pressure
123+ JOIN variable_to_pressure AS vp ON vp.pressure_id = pressure.id
124+ JOIN variable AS v ON v.id = vp.variable_id
125+ JOIN file ON v.file_id = file.id
126+ WHERE v.name = :variable
127+ ORDER BY value
128+ """ ),
129+ (sentinel .pattern , sentinel .variable , None , """
130+ SELECT DISTINCT pressure.value FROM pressure
131+ JOIN variable_to_pressure AS vp ON vp.pressure_id = pressure.id
132+ JOIN variable AS v ON v.id = vp.variable_id
133+ JOIN file ON v.file_id = file.id
134+ WHERE v.name = :variable AND file.name GLOB :pattern
135+ ORDER BY value
136+ """ ),
137+ (sentinel .pattern , sentinel .variable , sentinel .initial_time , """
138+ SELECT DISTINCT pressure.value FROM pressure
139+ JOIN variable_to_pressure AS vp ON vp.pressure_id = pressure.id
140+ JOIN variable AS v ON v.id = vp.variable_id
141+ JOIN file ON v.file_id = file.id
142+ WHERE v.name = :variable
143+ AND file.name GLOB :pattern
144+ AND file.reference = :initial_time
145+ ORDER BY value
146+ """ ),
147+ ])
148+ def test_pressures_query (pattern , variable , initial_time , expect ):
149+ result = database .Database .pressures_query (pattern , variable , initial_time )
150+ assert_query_equal (expect , result )
151+
152+
56153def test_Database_pressures__defaults ():
57154 db = _create_db ()
58155
@@ -69,7 +166,7 @@ def test_Database_pressures__all_args():
69166 db = _create_db ()
70167
71168 pressures = db .pressures (sentinel .pattern , sentinel .variable ,
72- sentinel . initial_time )
169+ dt . datetime ( 2020 , 1 , 1 ) )
73170
74171 _assert_query_and_params (
75172 db , 'SELECT DISTINCT pressure.value FROM pressure'
@@ -80,5 +177,31 @@ def test_Database_pressures__all_args():
80177 ' AND file.reference = :initial_time'
81178 ' ORDER BY value' ,
82179 {'pattern' : sentinel .pattern , 'variable' : sentinel .variable ,
83- 'initial_time' :sentinel . initial_time })
180+ 'initial_time' : "2020-01-01 00:00:00" })
84181 assert pressures == [sentinel .value1 , sentinel .value2 ]
182+
183+
184+
185+ @pytest .mark .parametrize ("initial_time" , [
186+ pytest .param (dt .datetime (2020 , 1 , 1 ), id = "datetime" ),
187+ pytest .param (cftime .DatetimeGregorian (2020 , 1 , 1 ), id = "cftime" ),
188+ pytest .param (np .datetime64 ("2020-01-01" , "ns" ), id = "np.datetime64" ),
189+ ])
190+ def test_Database_valid_times_given_datetime_like_objects (initial_time ):
191+ initial_datetime = dt .datetime (2020 , 1 , 1 )
192+ valid_times = [dt .datetime (2020 , 1 , 1 , 12 )]
193+ db = database .Database .connect (":memory:" )
194+ db .insert_file_name ("file.nc" , initial_datetime )
195+ db .insert_times ("file.nc" , "air_temperature" , valid_times )
196+ result = db .valid_times ("file.nc" , "air_temperature" , initial_time )
197+ expect = ["2020-01-01 12:00:00" ]
198+ assert expect == result
199+
200+
201+ @pytest .mark .parametrize ("time" , [
202+ pytest .param (dt .datetime (2020 , 1 , 1 ), id = "datetime" ),
203+ pytest .param (cftime .DatetimeGregorian (2020 , 1 , 1 ), id = "cftime" ),
204+ pytest .param (np .datetime64 ("2020-01-01" , "ns" ), id = "np.datetime64" ),
205+ ])
206+ def test_Database_sanitize_datetime_like_objects (time ):
207+ assert database .Database .sanitize_time (time ) == "2020-01-01 00:00:00"
0 commit comments