Skip to content

Commit bfdbc23

Browse files
committed
Updated unit tests post changes to weather, maps and directions
1 parent dd21e10 commit bfdbc23

File tree

9 files changed

+368
-68
lines changed

9 files changed

+368
-68
lines changed

src/programy/clients/twitter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def _process_status_question(self, userid, text):
189189
logging.debug(status)
190190

191191
if logging.getLogger().isEnabledFor(logging.DEBUG):
192-
logging.debug("Sending status response [@%s] [%s]", (user.screen_name, response))
192+
logging.debug("Sending status response [@%s] [%s]",user.screen_name, response)
193193

194194
self._api.update_status(status)
195195

src/programy/extensions/maps/maps.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222

2323
class GoogleMapsExtension(Extension):
2424

25+
def get_geo_locator(self):
26+
return GoogleMaps()
27+
2528
# execute() is the interface that is called from the <extension> tag in the AIML
2629
def execute(self, bot, clientid, data):
2730
if logging.getLogger().isEnabledFor(logging.DEBUG):
@@ -32,7 +35,7 @@ def execute(self, bot, clientid, data):
3235
from_place = splits[1]
3336
to_place = splits[2]
3437

35-
googlemaps = GoogleMaps(bot.license_keys)
38+
googlemaps = self.get_geo_locator()
3639

3740
if command == "DISTANCE":
3841
distance = googlemaps.get_distance_between_addresses(from_place, to_place)

src/programy/parser/tokenizer.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ def _is_chinese_char(c):
5353
(0x31C0, 0x31EF)]
5454
return any(s <= ord(c) <= e for s, e in r)
5555

56+
def _is_wildchar(self, ch):
57+
MATCH_CHARS = ['^', '#', '', '*']
58+
return bool(ch in MATCH_CHARS)
59+
5660
def texts_to_words(self, texts):
5761
if not texts:
5862
return []
@@ -63,16 +67,21 @@ def texts_to_words(self, texts):
6367
if CjkTokenizer._is_chinese_char(ch):
6468
if len(last_word) > 0:
6569
words.append(last_word)
66-
last_word = ch
67-
else:
68-
words.append(ch)
70+
last_word = ''
71+
words.append(ch)
6972
else:
70-
if ch == self.split_chars:
73+
if self._is_wildchar(ch):
7174
if len(last_word) > 0:
7275
words.append(last_word)
7376
last_word = ''
77+
words.append(ch)
7478
else:
75-
last_word += ch
79+
if ch == self.split_chars:
80+
if len(last_word) > 0:
81+
words.append(last_word)
82+
last_word = ''
83+
else:
84+
last_word += ch
7685

7786
if len(last_word) > 0:
7887
words.append(last_word)

test/programytest/extensions/maps/maps.aiml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
<template>
8383
<srai>
8484
SHOW_DISTANCE
85-
<extension path="programy.extensions.maps.maps.GoogleMapsExtension">
85+
<extension path="programytest.extensions.maps.test_aiml.MockGoogleMapsExtension">
8686
DISTANCE <star index="1"/> <star index="2"/>
8787
</extension>
8888
</srai>
@@ -115,7 +115,7 @@
115115
<template>
116116
<srai>
117117
SHOW_DIRECTIONS
118-
<extension path="programy.extensions.maps.maps.GoogleMapsExtension">
118+
<extension path="programytest.extensions.maps.test_aiml.MockGoogleMapsExtension">
119119
DIRECTIONS <star index="1"/> <star index="2"/>
120120
</extension>
121121
</srai>
Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,27 @@
11
import unittest
22
import os
3+
import json
4+
5+
from programy.extensions.maps.maps import GoogleMapsExtension
6+
from programy.utils.geo.google import GoogleMaps
37
from programytest.aiml_tests.client import TestClient
4-
from programy.config.sections.brain.file import BrainFileConfiguration
58

9+
class MockGoogleMaps(GoogleMaps):
10+
11+
def __init__(self, response_file):
12+
self._response_file = response_file
13+
14+
def _get_response_as_json(self, url):
15+
with open(self._response_file) as response_data:
16+
return json.load(response_data)
17+
18+
19+
class MockGoogleMapsExtension(GoogleMapsExtension):
20+
21+
response_file = None
22+
23+
def get_geo_locator(self):
24+
return MockGoogleMaps(MockGoogleMapsExtension.response_file)
625

726
class MapsTestsClient(TestClient):
827

@@ -13,27 +32,22 @@ def load_configuration(self, arguments):
1332
super(MapsTestsClient, self).load_configuration(arguments)
1433
self.configuration.brain_configuration.files.aiml_files._files=[os.path.dirname(__file__)]
1534

35+
1636
class MapsAIMLTests(unittest.TestCase):
1737

1838
def setUp (self):
1939
MapsAIMLTests.test_client = MapsTestsClient()
2040

21-
latlong = os.path.dirname(__file__) + os.sep + "google_latlong.json"
22-
distance = os.path.dirname(__file__) + os.sep + "distance.json"
23-
directions = os.path.dirname(__file__) + os.sep + "directions.json"
24-
25-
MapsAIMLTests.test_client.bot.license_keys.load_license_key_data("""
26-
GOOGLE_LATLONG=%s
27-
GOOGLE_MAPS_DISTANCE=%s
28-
GOOGLE_MAPS_DIRECTIONS=%s
29-
"""%(latlong, distance, directions))
30-
3141
def test_distance(self):
42+
MockGoogleMapsExtension.response_file = os.path.dirname(__file__) + os.sep + "distance.json"
43+
3244
response = MapsAIMLTests.test_client.bot.ask_question("testif", "DISTANCE EDINBURGH KINGHORN")
3345
self.assertIsNotNone(response)
3446
self.assertEqual(response, 'It is 25 . 1 miles')
3547

3648
def test_directions(self):
49+
MockGoogleMapsExtension.response_file = os.path.dirname(__file__) + os.sep + "directions.json"
50+
3751
response = MapsAIMLTests.test_client.bot.ask_question("testif", "DIRECTIONS EDINBURGH KINGHORN")
3852
self.assertIsNotNone(response)
3953
self.assertTrue(response.startswith("To get there Head west on Leith St"))

test/programytest/extensions/maps/test_maps.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,71 @@
11
import unittest
22
import unittest.mock
3+
import os
4+
import json
35

46
from programy.extensions.maps.maps import GoogleMapsExtension
57
from programy.utils.geo.google import GoogleDistance
68
from programytest.aiml_tests.client import TestClient
7-
import os
9+
10+
from programy.utils.geo.google import GoogleMaps
11+
12+
class MockGoogleMaps(GoogleMaps):
13+
14+
def __init__(self, response_file):
15+
self._response_file = response_file
16+
17+
def _get_response_as_json(self, url):
18+
with open(self._response_file) as response_data:
19+
return json.load(response_data)
20+
21+
22+
class MockGoogleMapsExtension(GoogleMapsExtension):
23+
24+
def __init__(self, response_file):
25+
self._response_file = response_file
26+
27+
def get_geo_locator(self):
28+
return MockGoogleMaps(self._response_file)
29+
830

931
class MapsExtensionTests(unittest.TestCase):
1032

1133
def setUp(self):
1234
self.test_client = TestClient()
1335

14-
latlong = os.path.dirname(__file__) + os.sep + "google_latlong.json"
36+
def test_maps_distance(self):
1537
distance = os.path.dirname(__file__) + os.sep + "distance.json"
16-
directions = os.path.dirname(__file__) + os.sep + "directions.json"
17-
18-
self.test_client.bot.license_keys.load_license_key_data("""
19-
GOOGLE_LATLONG=%s
20-
GOOGLE_MAPS_DISTANCE=%s
21-
GOOGLE_MAPS_DIRECTIONS=%s
22-
"""%(latlong, distance, directions))
2338

24-
def test_maps_distance(self):
25-
googlemaps = GoogleMapsExtension()
39+
googlemaps = MockGoogleMapsExtension(distance)
2640
self.assertIsNotNone(googlemaps)
2741

2842
result = googlemaps.execute(self.test_client.bot, "testid", "DISTANCE EDINBURGH KINGHORN")
2943
self.assertIsNotNone(result)
3044
self.assertEquals("DISTANCE DEC 25 FRAC 1 UNITS miles", result)
3145

3246
def test_maps_direction(self):
33-
googlemaps = GoogleMapsExtension()
47+
directions = os.path.dirname(__file__) + os.sep + "directions.json"
48+
49+
googlemaps = MockGoogleMapsExtension(directions)
3450
self.assertIsNotNone(googlemaps)
3551

3652
result = googlemaps.execute(self.test_client.bot, "testid", "DIRECTIONS EDINBURGH KINGHORN")
3753
self.assertIsNotNone(result)
3854
self.assertTrue(result.startswith("DIRECTIONS Head west on Leith St/A900 toward Leith"))
3955

4056
def test_maps_unknown(self):
41-
googlemaps = GoogleMapsExtension()
57+
latlong = os.path.dirname(__file__) + os.sep + "google_latlong.json"
58+
59+
googlemaps = MockGoogleMapsExtension(latlong)
4260
self.assertIsNotNone(googlemaps)
4361

4462
result = googlemaps.execute(self.test_client.bot, "testid", "SOMETHINGELSE EDINBURGH KINGHORN")
4563
self.assertIsNone(result)
4664

4765
def test_format_distance_for_programy(self):
48-
googlemaps = GoogleMapsExtension()
66+
distance = os.path.dirname(__file__) + os.sep + "distance.json"
67+
68+
googlemaps = MockGoogleMapsExtension(distance)
4969
self.assertIsNotNone(googlemaps)
5070

5171
distance = GoogleDistance("here", "there")
@@ -57,7 +77,9 @@ def test_format_distance_for_programy(self):
5777
self.assertEquals("DISTANCE DEC 22 FRAC 45 UNITS km", googlemaps._format_distance_for_programy(distance))
5878

5979
def test_format_directions_for_programy(self):
60-
googlemaps = GoogleMapsExtension()
80+
directions = os.path.dirname(__file__) + os.sep + "directions.json"
81+
82+
googlemaps = MockGoogleMapsExtension(directions)
6183
self.assertIsNotNone(googlemaps)
6284

6385
directions = unittest.mock.Mock()

test/programytest/extensions/weather/test_aiml.py

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,48 @@
11
import unittest
22
import os
3+
import json
4+
5+
from programy.extensions.weather.weather import WeatherExtension
36
from programytest.aiml_tests.client import TestClient
7+
from programy.utils.weather.metoffice import MetOffice
8+
from programy.utils.geo.google import GoogleMaps
9+
10+
class MockGoogleMaps(GoogleMaps):
11+
12+
def __init__(self, response_file):
13+
self._response_file = response_file
14+
15+
def _get_response_as_json(self, url):
16+
with open(self._response_file) as response_data:
17+
return json.load(response_data)
18+
19+
20+
class MockMetOffice(MetOffice):
21+
22+
def __init__(self, response_file):
23+
self._response_file = response_file
24+
25+
def _get_response_as_json(self):
26+
with open(self._response_file) as response_data:
27+
return json.load(response_data)
28+
29+
def get_forecast_data(self, lat, lon, forecast_type):
30+
return self._get_response_as_json()
31+
32+
def get_observation_data(self, lat, lon):
33+
return self._get_response_as_json()
34+
35+
36+
class MockWeatherExtension(WeatherExtension):
37+
38+
maps_file = None
39+
weather_file = None
40+
41+
def get_geo_locator(self, bot):
42+
return MockGoogleMaps(MockWeatherExtension.maps_file)
43+
44+
def get_met_office(self, bot):
45+
return MockMetOffice(MockWeatherExtension.weather_file)
446

547

648
class WeathersTestsClient(TestClient):
@@ -15,19 +57,26 @@ def load_configuration(self, arguments):
1557

1658
class WeathersAIMLTests(unittest.TestCase):
1759

60+
1861
def setUp (self):
1962
WeathersAIMLTests.test_client = WeathersTestsClient()
20-
WeathersAIMLTests.test_client.bot.license_keys.load_license_key_data("""
21-
METOFFICE_API_KEY=TESTKEY
22-
""")
63+
WeathersAIMLTests.test_client.bot.get_conversation("testid").properties["active"] = "true"
2364

2465
def test_weather(self):
25-
latlong = os.path.dirname(__file__) + os.sep + "google_latlong.json"
26-
observation = os.path.dirname(__file__) + os.sep + "observation.json"
66+
MockWeatherExtension.maps_file = os.path.dirname(__file__) + os.sep + "google_latlong.json"
67+
MockWeatherExtension.weather_file = os.path.dirname(__file__) + os.sep + "observation.json"
2768
threehourly = os.path.dirname(__file__) + os.sep + "forecast_3hourly.json"
2869
daily = os.path.dirname(__file__) + os.sep + "forecast_daily.json"
2970

3071
response = WeathersAIMLTests.test_client.bot.ask_question("testid", "WEATHER LOCATION KY39UR WHEN TODAY")
3172
self.assertIsNotNone(response)
32-
self.assertEqual(response, "Today the weather is Partly cloudy (day) , with a temperature of 12 dot 3 \'C")
73+
self.assertEqual(response, "According to the UK Met Office, this it is partly cloudy (day) , with a temperature of around 12dot3'C , humidty is 57.3% , with pressure at 1017mb and falling .")
3374

75+
"""
76+
WEATHER IN *
77+
WEATHER LOCATION * WHEN *
78+
FORECAST LOCATION * DAY *
79+
FORECAST LOCATION * TIME *
80+
WILL IT RAIN TODAY IN *
81+
WILL IT RAIN TOMORROW IN *
82+
"""

0 commit comments

Comments
 (0)