1#!/usr/bin/python2.4
2#
3# Copyright 2008 Google Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""Unittest for Graphy and Google Chart API backend."""
18
19import string
20import unittest
21
22from graphy import graphy_test
23from graphy.backends.google_chart_api import util
24
25
26class SimpleEncoderTest(graphy_test.GraphyTest):
27
28  def setUp(self):
29    self.simple = util.SimpleDataEncoder()
30
31  def testEmpty(self):
32    self.assertEqual('', self.simple.Encode([]))
33
34  def testSingle(self):
35    self.assertEqual('A', self.simple.Encode([0]))
36
37  def testFull(self):
38    full = string.ascii_uppercase + string.ascii_lowercase + string.digits
39    self.assertEqual(full, self.simple.Encode(range(0, 62)))
40
41  def testRoundingError(self):
42    """Scaling might give us some rounding error.  Make sure that the encoder
43    deals with it properly.
44    """
45    a = [-1, 0, 0, 1, 60, 61, 61, 62]
46    b = [-0.999999, -0.00001, 0.00001, 0.99998,
47         60.00001, 60.99999, 61.00001, 61.99998]
48    self.assertEqual(self.simple.Encode(a), self.simple.Encode(b))
49
50  def testFloats(self):
51    ints   = [1, 2, 3, 4]
52    floats = [1.1, 2.1, 3.1, 4.1]
53    self.assertEqual(self.simple.Encode(ints), self.simple.Encode(floats))
54
55  def testOutOfRangeDropped(self):
56    """Confirm that values outside of min/max are left blank."""
57    nums = [-79, -1, 0, 1, 61, 62, 1012]
58    self.assertEqual('__AB9__', self.simple.Encode(nums))
59
60  def testNoneDropped(self):
61    """Confirm that the value None is left blank."""
62    self.assertEqual('_JI_H', self.simple.Encode([None, 9, 8, None, 7]))
63
64
65class EnhandedEncoderTest(graphy_test.GraphyTest):
66
67  def setUp(self):
68    self.encoder = util.EnhancedDataEncoder()
69
70  def testEmpty(self):
71    self.assertEqual('', self.encoder.Encode([]))
72
73  def testFull(self):
74    full = ''.join(self.encoder.code)
75    self.assertEqual(full, self.encoder.Encode(range(0, 4096)))
76
77  def testOutOfRangeDropped(self):
78    nums = [-79, -1, 0, 1, 61, 4096, 10012]
79    self.assertEqual('____AAABA9____', self.encoder.Encode(nums))
80
81  def testNoneDropped(self):
82    self.assertEqual('__AJAI__AH', self.encoder.Encode([None, 9, 8, None, 7]))
83
84
85class ScaleTest(graphy_test.GraphyTest):
86
87  """Test scaling."""
88
89  def testScaleIntegerData(self):
90    scale = util.ScaleData
91    # Identity
92    self.assertEqual([1, 2, 3], scale([1, 2, 3], 1, 3, 1, 3))
93    self.assertEqual([-1, 0, 1], scale([-1, 0, 1], -1, 1, -1, 1))
94
95    # Translate
96    self.assertEqual([4, 5, 6], scale([1, 2, 3], 1, 3, 4, 6))
97    self.assertEqual([-3, -2, -1], scale([1, 2, 3], 1, 3, -3, -1))
98
99    # Scale
100    self.assertEqual([1, 3.5, 6], scale([1, 2, 3], 1, 3, 1, 6))
101    self.assertEqual([-6, 0, 6], scale([1, 2, 3], 1, 3, -6, 6))
102
103    # Scale and Translate
104    self.assertEqual([100, 200, 300], scale([1, 2, 3], 1, 3, 100, 300))
105
106  def testScaleDataWithDifferentMinMax(self):
107    scale = util.ScaleData
108    self.assertEqual([1.5, 2, 2.5], scale([1, 2, 3], 0, 4, 1, 3))
109    self.assertEqual([-2, 2, 6], scale([0, 2, 4], 1, 3, 0, 4))
110
111  def testScaleFloatingPointData(self):
112    scale = util.ScaleData
113    data = [-3.14, -2.72, 0, 2.72, 3.14]
114    scaled_e = 5 + 5 * 2.72 / 3.14
115    expected_data = [0, 10 - scaled_e, 5, scaled_e, 10]
116    actual_data = scale(data, -3.14, 3.14, 0, 10)
117    for expected, actual in zip(expected_data, actual_data):
118      self.assertAlmostEqual(expected, actual)
119
120  def testScaleDataOverRealRange(self):
121    scale = util.ScaleData
122    self.assertEqual([0, 30.5, 61], scale([1, 2, 3], 1, 3, 0, 61))
123
124  def testScalingLotsOfData(self):
125    data = range(0, 100)
126    expected = range(-100, 100, 2)
127    actual = util.ScaleData(data, 0, 100, -100, 100)
128    self.assertEqual(expected, actual)
129
130
131class NameTest(graphy_test.GraphyTest):
132
133  """Test long/short parameter names."""
134
135  def testLongNames(self):
136    params = dict(size='S', data='D', chg='G')
137    params = util.ShortenParameterNames(params)
138    self.assertEqual(dict(chs='S', chd='D', chg='G'), params)
139
140  def testCantUseBothLongAndShortName(self):
141    """Make sure we don't let the user specify both the long and the short
142    version of a parameter.  (If we did, which one would we pick?)
143    """
144    params = dict(size='long', chs='short')
145    self.assertRaises(KeyError, util.ShortenParameterNames, params)
146
147
148if __name__ == '__main__':
149  unittest.main()
150