OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 | 2 |
3 """ | 3 """ |
4 Copyright 2014 Google Inc. | 4 Copyright 2014 Google Inc. |
5 | 5 |
6 Use of this source code is governed by a BSD-style license that can be | 6 Use of this source code is governed by a BSD-style license that can be |
7 found in the LICENSE file. | 7 found in the LICENSE file. |
8 | 8 |
9 ImagePairSet class; see its docstring below. | 9 ImagePairSet class; see its docstring below. |
10 """ | 10 """ |
11 | 11 |
| 12 # System-level imports |
| 13 import posixpath |
| 14 |
| 15 # Local imports |
12 import column | 16 import column |
13 | 17 |
14 # Keys used within dictionary representation of ImagePairSet. | 18 # Keys used within dictionary representation of ImagePairSet. |
15 # NOTE: Keep these in sync with static/constants.js | 19 # NOTE: Keep these in sync with static/constants.js |
16 KEY__EXTRACOLUMNHEADERS = 'extraColumnHeaders' | 20 KEY__EXTRACOLUMNHEADERS = 'extraColumnHeaders' |
17 KEY__IMAGEPAIRS = 'imagePairs' | 21 KEY__IMAGEPAIRS = 'imagePairs' |
18 KEY__IMAGESETS = 'imageSets' | 22 KEY__IMAGESETS = 'imageSets' |
19 KEY__IMAGESETS__BASE_URL = 'baseUrl' | 23 KEY__IMAGESETS__FIELD__BASE_URL = 'baseUrl' |
20 KEY__IMAGESETS__DESCRIPTION = 'description' | 24 KEY__IMAGESETS__FIELD__DESCRIPTION = 'description' |
| 25 KEY__IMAGESETS__SET__DIFFS = 'diffs' |
| 26 KEY__IMAGESETS__SET__IMAGE_A = 'imageA' |
| 27 KEY__IMAGESETS__SET__IMAGE_B = 'imageB' |
| 28 KEY__IMAGESETS__SET__WHITEDIFFS = 'whiteDiffs' |
21 | 29 |
22 DEFAULT_DESCRIPTIONS = ('setA', 'setB') | 30 DEFAULT_DESCRIPTIONS = ('setA', 'setB') |
| 31 DIFF_BASE_URL = '/static/generated-images' |
23 | 32 |
24 | 33 |
25 class ImagePairSet(object): | 34 class ImagePairSet(object): |
26 """A collection of ImagePairs, representing two arbitrary sets of images. | 35 """A collection of ImagePairs, representing two arbitrary sets of images. |
27 | 36 |
28 These could be: | 37 These could be: |
29 - images generated before and after a code patch | 38 - images generated before and after a code patch |
30 - expected and actual images for some tests | 39 - expected and actual images for some tests |
31 - or any other pairwise set of images. | 40 - or any other pairwise set of images. |
32 """ | 41 """ |
33 | 42 |
34 def __init__(self, descriptions=None): | 43 def __init__(self, descriptions=None): |
35 """ | 44 """ |
36 Args: | 45 Args: |
37 descriptions: a (string, string) tuple describing the two image sets. | 46 descriptions: a (string, string) tuple describing the two image sets. |
38 If not specified, DEFAULT_DESCRIPTIONS will be used. | 47 If not specified, DEFAULT_DESCRIPTIONS will be used. |
39 """ | 48 """ |
40 self._column_header_factories = {} | 49 self._column_header_factories = {} |
41 self._descriptions = descriptions or DEFAULT_DESCRIPTIONS | 50 self._descriptions = descriptions or DEFAULT_DESCRIPTIONS |
42 self._extra_column_tallies = {} # maps column_id -> values | 51 self._extra_column_tallies = {} # maps column_id -> values |
43 # -> instances_per_value | 52 # -> instances_per_value |
44 self._image_pair_dicts = [] | 53 self._image_pair_dicts = [] |
| 54 self._image_base_url = None |
| 55 self._diff_base_url = DIFF_BASE_URL |
45 | 56 |
46 def add_image_pair(self, image_pair): | 57 def add_image_pair(self, image_pair): |
47 """Adds an ImagePair; this may be repeated any number of times.""" | 58 """Adds an ImagePair; this may be repeated any number of times.""" |
48 # Special handling when we add the first ImagePair... | 59 # Special handling when we add the first ImagePair... |
49 if not self._image_pair_dicts: | 60 if not self._image_pair_dicts: |
50 self._base_url = image_pair.base_url | 61 self._image_base_url = image_pair.base_url |
51 | 62 |
52 if image_pair.base_url != self._base_url: | 63 if image_pair.base_url != self._image_base_url: |
53 raise Exception('added ImagePair with base_url "%s" instead of "%s"' % ( | 64 raise Exception('added ImagePair with base_url "%s" instead of "%s"' % ( |
54 image_pair.base_url, self._base_url)) | 65 image_pair.base_url, self._image_base_url)) |
55 self._image_pair_dicts.append(image_pair.as_dict()) | 66 self._image_pair_dicts.append(image_pair.as_dict()) |
56 extra_columns_dict = image_pair.extra_columns_dict | 67 extra_columns_dict = image_pair.extra_columns_dict |
57 if extra_columns_dict: | 68 if extra_columns_dict: |
58 for column_id, value in extra_columns_dict.iteritems(): | 69 for column_id, value in extra_columns_dict.iteritems(): |
59 self._add_extra_column_value_to_summary(column_id, value) | 70 self._add_extra_column_value_to_summary(column_id, value) |
60 | 71 |
61 def set_column_header_factory(self, column_id, column_header_factory): | 72 def set_column_header_factory(self, column_id, column_header_factory): |
62 """Overrides the default settings for one of the extraColumn headers. | 73 """Overrides the default settings for one of the extraColumn headers. |
63 | 74 |
64 Args: | 75 Args: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 column_header_factory = self.get_column_header_factory(column_id) | 131 column_header_factory = self.get_column_header_factory(column_id) |
121 asdict[column_id] = column_header_factory.create_as_dict( | 132 asdict[column_id] = column_header_factory.create_as_dict( |
122 values_for_column) | 133 values_for_column) |
123 return asdict | 134 return asdict |
124 | 135 |
125 def as_dict(self): | 136 def as_dict(self): |
126 """Returns a dictionary describing this package of ImagePairs. | 137 """Returns a dictionary describing this package of ImagePairs. |
127 | 138 |
128 Uses the KEY__* constants as keys. | 139 Uses the KEY__* constants as keys. |
129 """ | 140 """ |
| 141 key_description = KEY__IMAGESETS__FIELD__DESCRIPTION |
| 142 key_base_url = KEY__IMAGESETS__FIELD__BASE_URL |
130 return { | 143 return { |
131 KEY__EXTRACOLUMNHEADERS: self._column_headers_as_dict(), | 144 KEY__EXTRACOLUMNHEADERS: self._column_headers_as_dict(), |
132 KEY__IMAGEPAIRS: self._image_pair_dicts, | 145 KEY__IMAGEPAIRS: self._image_pair_dicts, |
133 KEY__IMAGESETS: [{ | 146 KEY__IMAGESETS: { |
134 KEY__IMAGESETS__BASE_URL: self._base_url, | 147 KEY__IMAGESETS__SET__IMAGE_A: { |
135 KEY__IMAGESETS__DESCRIPTION: self._descriptions[0], | 148 key_description: self._descriptions[0], |
136 }, { | 149 key_base_url: self._image_base_url, |
137 KEY__IMAGESETS__BASE_URL: self._base_url, | 150 }, |
138 KEY__IMAGESETS__DESCRIPTION: self._descriptions[1], | 151 KEY__IMAGESETS__SET__IMAGE_B: { |
139 }], | 152 key_description: self._descriptions[1], |
| 153 key_base_url: self._image_base_url, |
| 154 }, |
| 155 KEY__IMAGESETS__SET__DIFFS: { |
| 156 key_description: 'color difference per channel', |
| 157 key_base_url: posixpath.join( |
| 158 self._diff_base_url, 'diffs'), |
| 159 }, |
| 160 KEY__IMAGESETS__SET__WHITEDIFFS: { |
| 161 key_description: 'differing pixels in white', |
| 162 key_base_url: posixpath.join( |
| 163 self._diff_base_url, 'whitediffs'), |
| 164 }, |
| 165 }, |
140 } | 166 } |
OLD | NEW |