2cc67ace by Adam Heath

More splitting, and more test specs.

1 parent ba0249c5
1 define(function(require) {
2 'use strict';
3 var _ = require('underscore');
4 var Backbone = require('backbone');
5 var Sort = require('./Sort');
6
7 function getItemKeyAccessor(item) {
8 return item.get('key');
9 }
10
11 function wrapComparatorForAllBeforeAfter(comparator, doBefore, doAfter) {
12 if (!doBefore && !doAfter) {
13 return comparator;
14 }
15 return function beforeAfterComparator(a, b) {
16 if (doBefore) {
17 if (a === 'before') {
18 return -1;
19 } else if (b === 'before') {
20 return 1;
21 }
22 }
23 if (doAfter) {
24 if (a === 'after') {
25 return 1;
26 } else if (b === 'after') {
27 return -1;
28 }
29 }
30 return comparator.call(this, a, b);
31 };
32 }
33 var Facet = Backbone.Model.extend({
34 defaults: function defaults() {
35 return {
36 formName: null,
37 query: null,
38 suggestions: [],
39 };
40 },
41 initialize: function(data, options) {
42 this.set('all', true);
43 this.on('change:queryMax change:queryMin', function() {
44 this.set('hasQuery', this.get('queryMin') !== undefined && this.get('queryMax') !== undefined);
45 }, this);
46 (function(self) {
47 var skipCallback;
48 self.on('item-change change:queryMax change:queryMin', function() {
49 switch (skipCallback) {
50 case 'change:checkedKeys':
51 case 'change:all':
52 return;
53 }
54 var checkedKeys = [];
55 this.get('items').each(function(facetItem) {
56 if (facetItem.get('checked')) {
57 checkedKeys.push(facetItem.get('key'));
58 }
59 });
60 var checkedCount = checkedKeys.length;
61 if (this.get('queryMin') !== undefined && this.get('queryMax') !== undefined) {
62 checkedCount++;
63 }
64 skipCallback = 'item-change';
65 try {
66 this.set({
67 all: checkedCount === 0,
68 checkedKeys: checkedKeys,
69
70 });
71 } finally {
72 skipCallback = null;
73 }
74 }, self);
75 self.on('change:all', function() {
76 switch (skipCallback) {
77 case 'change:checkedKeys':
78 case 'item-change':
79 return;
80 }
81 skipCallback = 'change:all';
82 try {
83 this.get('items').invoke('set', {checked: false});
84 this.set({
85 checkedKeys: [],
86 queryMax: undefined,
87 queryMin: undefined,
88 });
89 } finally {
90 skipCallback = null;
91 }
92 }, self);
93 self.on('change:checkedKeys', function() {
94 switch (skipCallback) {
95 case 'item-change':
96 case 'change:all':
97 return;
98 }
99 var checkedKeys = {};
100 _.each(this.get('checkedKeys'), function(value, i) {
101 checkedKeys[value] = true;
102 });
103 skipCallback = 'change:checkedKeys';
104 var checkedCount = 0;
105 if (this.get('queryMin') !== undefined && this.get('queryMax') !== undefined) {
106 checkedCount++;
107 }
108 try {
109 this.get('items').each(function(facetItem) {
110 var newChecked = checkedKeys[facetItem.get('key')];
111 var currentChecked = facetItem.get('checked');
112 if (newChecked !== currentChecked) {
113 facetItem.set('checked', newChecked);
114 }
115 if (facetItem.get('checked')) {
116 checkedCount++;
117 }
118 });
119 this.set({
120 all: checkedCount === 0,
121 });
122 } finally {
123 skipCallback = null;
124 }
125 }, self);
126 })(this);
127 var sortKeyExtractor = options.sortKeyExtractor;
128 if (!sortKeyExtractor) {
129 sortKeyExtractor = getItemKeyAccessor;
130 }
131 var comparator = options.comparator;
132 if (!comparator) {
133 comparator = Sort.standard;
134 } else if (typeof comparator === 'string') {
135 comparator = Sort[comparator];
136 }
137 switch (options.facetType) {
138 case 'year':
139 case 'range':
140 case 'interval':
141 comparator = wrapComparatorForAllBeforeAfter(comparator, ['all', 'before'].indexOf(options.other) !== -1, ['all', 'after'].indexOf(options.other) !== -1);
142 break;
143 }
144 var formatter = options.formatter;
145 if (!formatter) {
146 var labelMap = options.labelMap;
147 if (labelMap) {
148 formatter = function(item) {
149 var value = item.get('key');
150 var label = options.labelMap[value.toUpperCase()];
151 return label ? label : value;
152 };
153 } else {
154 formatter = getItemKeyAccessor;
155 }
156 }
157 this.formatter = formatter;
158 comparator = (function(comparator) {
159 return function facetItemValue(a, b) {
160 var keyA = sortKeyExtractor(a);
161 var keyB = sortKeyExtractor(b);
162 switch (this.get('orderByDirection')) {
163 case 'desc':
164 var tmp = keyA;
165 keyA = keyB;
166 keyB = tmp;
167 break;
168 }
169 return comparator.call(this, sortKeyExtractor(a), sortKeyExtractor(b));
170 };
171 })(comparator);
172 this.set('items', new ItemCollection([], {comparator: comparator}));
173 this.facetType = options.facetType;
174 this.facetStats = options.facetStats;
175 this.other = options.other;
176 this.facetField = options.facetField;
177 this.queryField = options.queryField;
178 this.queryValue = options.queryValue;
179 this.bins = options.bins;
180 switch (this.facetType) {
181 case 'year':
182 this.rangeStart = options.start;
183 this.rangeEnd = options.end;
184 this.rangeGap = '+' + (options.gap ? options.gap : 1) + 'YEAR';
185 break;
186 case 'range':
187 this.rangeStart = options.start;
188 this.rangeEnd = options.end;
189 this.rangeGap = options.gap;
190 break;
191 case 'field':
192 case 'year-field':
193 case 'interval':
194 break;
195 default:
196 var e = new Error('Unsupported facet type: ' + this.facetType);
197 e.facet = this;
198 throw e;
199 }
200 return Facet.__super__.initialize.apply(this, arguments);
201 },
202 /*
203 toJSON: function toJSON(options) {
204 if (!!options.facetSuggestions) {
205 return {
206 rows: 0,
207 facet: true,
208 wt: 'json',
209 q: '*:*',
210 'facet.contains': this.get('query'),
211 'facet.contains.ignoreCase': true,
212 'facet.field': this.queryField,
213 'facet.mincount': 1,
214 };
215 }
216 },
217 parse: function parse(data, options) {
218 if (!!options.facetSuggestions) {
219 var suggestions = [];
220 var key;
221 _.each(data.facet_counts.facet_fields[this.queryField], function(value, index) {
222 if (index % 2 === 0) {
223 key = value;
224 } else if (value > 0) {
225 suggestions.push({key: key, value: value});
226 }
227 });
228 return {
229 suggestions: suggestions,
230 };
231 }
232 return null;
233 },
234 */
235 });
236 var ItemCollection = Backbone.Collection.extend({
237 remove: function() {
238 }
239 });
240 var Item = Facet.Item = Backbone.Model.extend({
241 idAttribute: 'key',
242 defaults: {
243 checked: false,
244 hidden: false,
245 },
246 _initialize: function(data, options) {
247 this.on('add', function(model, parent, options) {
248 // added to a collection
249 this.on('change:checked', function() {
250 parent.trigger('item-change');
251 });
252 }, this);
253 return Item.__super__.initialize.apply(this, arguments);
254 }
255 });
256
257 return Facet;
258 });
1 define(function(require) {
2 'use strict';
3
4 var Sort = {
5 standard: function standardSort(a, b) {
6 if (a < b) {
7 return -1;
8 } else if (a > b) {
9 return 1;
10 } else {
11 return 0;
12 }
13 },
14 date: function dateSort(a, b) {
15 return Sort.standard.call(this, a, b);
16 },
17 number: function numberSort(a, b) {
18 return Sort.standard.call(this, parseInt(a), parseInt(b));
19 },
20 };
21
22 return Sort;
23 });
1 define(function(require) {
2 'use strict';
3 var Facet = require('solr/model/Facet');
4
5 describe('Facet', function() {
6 it('loads', function() {
7 expect(Facet).toBeDefined();
8 });
9 });
10 });
1 define(function(require) {
2 'use strict';
3 var _ = require('underscore');
4 var Backbone = require('backbone');
5 var Facets = require('solr/model/Facets');
6
7 describe('Facets', function() {
8 it('loads', function() {
9 expect(Facets).toBeDefined();
10 });
11 });
12 });
1 define(function(require) {
2 'use strict';
3 var _ = require('underscore');
4 var Backbone = require('backbone');
5 var Sort = require('solr/model/Sort');
6
7 describe('Sort', function() {
8 it('loads', function() {
9 expect(Sort).toBeDefined();
10 });
11 it('standard(number)', function() {
12 var array = [5, 4, 2, 2, 3, 1, 5];
13 array.sort(Sort.standard);
14 expect(array).toEqual([1, 2, 2, 3, 4, 5, 5]);
15 });
16 it('standard(string)', function() {
17 var array = ['1', '500', '2', '400', '3', '300', '4', '200', '5', '100'];
18 array.sort(Sort.standard);
19 expect(array).toEqual(['1', '100', '2', '200', '3', '300', '4', '400', '5', '500']);
20 });
21 it('date', function() {
22 var array = [
23 '2016-02-05T13:25:06-0600',
24 '2015-02-05T13:25:06-0600',
25 '2014-02-05T13:25:06-0600',
26 '2013-02-05T13:25:06-0600',
27 '2012-02-05T13:25:06-0600',
28 '2011-02-05T13:25:06-0600',
29 ];
30 array.sort(Sort.date);
31 expect(array).toEqual([
32 '2011-02-05T13:25:06-0600',
33 '2012-02-05T13:25:06-0600',
34 '2013-02-05T13:25:06-0600',
35 '2014-02-05T13:25:06-0600',
36 '2015-02-05T13:25:06-0600',
37 '2016-02-05T13:25:06-0600',
38 ]);
39 });
40 it('number', function() {
41 var array = ['1', '500', '2', '400', '3', '300', '4', '200', '5', '100'];
42 array.sort(Sort.number);
43 expect(array).toEqual(['1', '2', '3', '4', '5', '100', '200', '300', '400', '500']);
44 });
45 });
46 });