extjs-mvc 0.4.0.j → 0.4.0.k

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. data/Rakefile +1 -1
  2. data/VERSION +1 -1
  3. data/lib/extjs-mvc.rb +0 -14
  4. data/lib/extjs-mvc/api.rb +14 -27
  5. data/lib/extjs-mvc/src/App.js +219 -0
  6. data/lib/extjs-mvc/src/MVC.js +260 -0
  7. data/lib/extjs-mvc/src/Presenter.js +52 -0
  8. data/lib/extjs-mvc/src/README.rdoc +69 -0
  9. data/lib/extjs-mvc/src/controller/Controller.js +278 -0
  10. data/lib/extjs-mvc/src/controller/CrudController.js +460 -0
  11. data/lib/extjs-mvc/src/lib/Array.js +26 -0
  12. data/lib/extjs-mvc/src/lib/Booter.js +417 -0
  13. data/lib/extjs-mvc/src/lib/ClassManager.js +191 -0
  14. data/lib/extjs-mvc/src/lib/ControllerClassManager.js +95 -0
  15. data/lib/extjs-mvc/src/lib/Dependencies.js +44 -0
  16. data/lib/extjs-mvc/src/lib/DispatchMatcher.js +98 -0
  17. data/lib/extjs-mvc/src/lib/Dispatcher.js +129 -0
  18. data/lib/extjs-mvc/src/lib/Environment.js +43 -0
  19. data/lib/extjs-mvc/src/lib/Inflector.js +155 -0
  20. data/lib/extjs-mvc/src/lib/ModelClassManager.js +19 -0
  21. data/lib/extjs-mvc/src/lib/Route.js +139 -0
  22. data/lib/extjs-mvc/src/lib/Router.js +282 -0
  23. data/lib/extjs-mvc/src/lib/String.js +94 -0
  24. data/lib/extjs-mvc/src/lib/ViewClassManager.js +229 -0
  25. data/lib/extjs-mvc/src/lib/notes.txt +32 -0
  26. data/lib/extjs-mvc/src/model/AdapterManager.js +30 -0
  27. data/lib/extjs-mvc/src/model/Association.js +26 -0
  28. data/lib/extjs-mvc/src/model/Base.js +63 -0
  29. data/lib/extjs-mvc/src/model/BelongsToAssociation.js +116 -0
  30. data/lib/extjs-mvc/src/model/Cache.js +131 -0
  31. data/lib/extjs-mvc/src/model/HasManyAssociation.js +160 -0
  32. data/lib/extjs-mvc/src/model/Model.js +331 -0
  33. data/lib/extjs-mvc/src/model/UrlBuilder.js +106 -0
  34. data/lib/extjs-mvc/src/model/adapters/AbstractAdapter.js +296 -0
  35. data/lib/extjs-mvc/src/model/adapters/MemoryAdapter.js +103 -0
  36. data/lib/extjs-mvc/src/model/adapters/RESTAdapter.js +345 -0
  37. data/lib/extjs-mvc/src/model/adapters/RESTJSONAdapter.js +68 -0
  38. data/lib/extjs-mvc/src/model/adapters/notes.txt +42 -0
  39. data/lib/extjs-mvc/src/model/associations/Association.js +192 -0
  40. data/lib/extjs-mvc/src/model/associations/notes.txt +87 -0
  41. data/lib/extjs-mvc/src/model/validations/Errors.js +136 -0
  42. data/lib/extjs-mvc/src/model/validations/Plugin.js +139 -0
  43. data/lib/extjs-mvc/src/model/validations/Validations.js +276 -0
  44. data/lib/extjs-mvc/src/notes/Charts.graffle +0 -0
  45. data/lib/extjs-mvc/src/overrides/Ext.Component.js +21 -0
  46. data/lib/extjs-mvc/src/overrides/Ext.extend.js +142 -0
  47. data/lib/extjs-mvc/src/spec/Array.spec.js +15 -0
  48. data/lib/extjs-mvc/src/spec/ExtMVC.spec.js +65 -0
  49. data/lib/extjs-mvc/src/spec/Model.spec.js +370 -0
  50. data/lib/extjs-mvc/src/spec/OS.spec.js +83 -0
  51. data/lib/extjs-mvc/src/spec/Router.spec.js +99 -0
  52. data/lib/extjs-mvc/src/spec/SpecHelper.js +106 -0
  53. data/lib/extjs-mvc/src/spec/String.spec.js +83 -0
  54. data/lib/extjs-mvc/src/spec/model/AbstractAdapter.spec.js +49 -0
  55. data/lib/extjs-mvc/src/spec/model/Associations.spec.js +99 -0
  56. data/lib/extjs-mvc/src/spec/model/Cache.spec.js +5 -0
  57. data/lib/extjs-mvc/src/spec/model/RESTAdapter.spec.js +19 -0
  58. data/lib/extjs-mvc/src/spec/model/ValidationErrors.spec.js +64 -0
  59. data/lib/extjs-mvc/src/spec/model/Validations.spec.js +166 -0
  60. data/lib/extjs-mvc/src/spec/model/ValidationsPlugin.spec.js +108 -0
  61. data/lib/extjs-mvc/src/spec/suite.html +60 -0
  62. data/lib/extjs-mvc/src/specs-old/JSSpec.css +216 -0
  63. data/lib/extjs-mvc/src/specs-old/JSSpec.js +1512 -0
  64. data/lib/extjs-mvc/src/specs-old/all.html +66 -0
  65. data/lib/extjs-mvc/src/specs-old/base.js +14 -0
  66. data/lib/extjs-mvc/src/specs-old/controller.js +17 -0
  67. data/lib/extjs-mvc/src/specs-old/diff_match_patch.js +1 -0
  68. data/lib/extjs-mvc/src/specs-old/model.js +70 -0
  69. data/lib/extjs-mvc/src/specs-old/route.js +38 -0
  70. data/lib/extjs-mvc/src/specs-old/router.js +59 -0
  71. data/lib/extjs-mvc/src/specs-old/string.js +22 -0
  72. data/lib/extjs-mvc/src/testrunner/JSpecFormatter.js +111 -0
  73. data/lib/extjs-mvc/src/testrunner/TestClient.js +181 -0
  74. data/lib/extjs-mvc/src/testrunner/TestGrid.js +351 -0
  75. data/lib/extjs-mvc/src/testrunner/TestRunner.js +110 -0
  76. data/lib/extjs-mvc/src/testrunner/TestViewport.js +94 -0
  77. data/lib/extjs-mvc/src/vendor.yml +30 -0
  78. data/lib/extjs-mvc/src/vendor/ext-3.1.1/vendor.yml +16 -0
  79. data/lib/extjs-mvc/src/view/FormWindow.js +184 -0
  80. data/lib/extjs-mvc/src/view/HasManyEditorGridPanel.js +211 -0
  81. data/lib/extjs-mvc/src/view/scaffold/Edit.js +46 -0
  82. data/lib/extjs-mvc/src/view/scaffold/Index.js +561 -0
  83. data/lib/extjs-mvc/src/view/scaffold/New.js +20 -0
  84. data/lib/extjs-mvc/src/view/scaffold/ScaffoldFormPanel.js +255 -0
  85. data/lib/{vendor.yml → extjs-mvc/vendor.yml} +0 -0
  86. data/test/app/vendor/extjs-mvc/App.js +219 -0
  87. data/test/app/vendor/extjs-mvc/MVC.js +260 -0
  88. data/test/app/vendor/extjs-mvc/Presenter.js +52 -0
  89. data/test/app/vendor/extjs-mvc/README.rdoc +69 -0
  90. data/test/app/vendor/extjs-mvc/controller/Controller.js +278 -0
  91. data/test/app/vendor/extjs-mvc/controller/CrudController.js +460 -0
  92. data/test/app/vendor/extjs-mvc/lib/Array.js +26 -0
  93. data/test/app/vendor/extjs-mvc/lib/Booter.js +417 -0
  94. data/test/app/vendor/extjs-mvc/lib/ClassManager.js +191 -0
  95. data/test/app/vendor/extjs-mvc/lib/ControllerClassManager.js +95 -0
  96. data/test/app/vendor/extjs-mvc/lib/Dependencies.js +44 -0
  97. data/test/app/vendor/extjs-mvc/lib/DispatchMatcher.js +98 -0
  98. data/test/app/vendor/extjs-mvc/lib/Dispatcher.js +129 -0
  99. data/test/app/vendor/extjs-mvc/lib/Environment.js +43 -0
  100. data/test/app/vendor/extjs-mvc/lib/Inflector.js +155 -0
  101. data/test/app/vendor/extjs-mvc/lib/ModelClassManager.js +19 -0
  102. data/test/app/vendor/extjs-mvc/lib/Route.js +139 -0
  103. data/test/app/vendor/extjs-mvc/lib/Router.js +282 -0
  104. data/test/app/vendor/extjs-mvc/lib/String.js +94 -0
  105. data/test/app/vendor/extjs-mvc/lib/ViewClassManager.js +229 -0
  106. data/test/app/vendor/extjs-mvc/lib/notes.txt +32 -0
  107. data/test/app/vendor/extjs-mvc/model/AdapterManager.js +30 -0
  108. data/test/app/vendor/extjs-mvc/model/Association.js +26 -0
  109. data/test/app/vendor/extjs-mvc/model/Base.js +63 -0
  110. data/test/app/vendor/extjs-mvc/model/BelongsToAssociation.js +116 -0
  111. data/test/app/vendor/extjs-mvc/model/Cache.js +131 -0
  112. data/test/app/vendor/extjs-mvc/model/HasManyAssociation.js +160 -0
  113. data/test/app/vendor/extjs-mvc/model/Model.js +331 -0
  114. data/test/app/vendor/extjs-mvc/model/UrlBuilder.js +106 -0
  115. data/test/app/vendor/extjs-mvc/model/adapters/AbstractAdapter.js +296 -0
  116. data/test/app/vendor/extjs-mvc/model/adapters/MemoryAdapter.js +103 -0
  117. data/test/app/vendor/extjs-mvc/model/adapters/RESTAdapter.js +345 -0
  118. data/test/app/vendor/extjs-mvc/model/adapters/RESTJSONAdapter.js +68 -0
  119. data/test/app/vendor/extjs-mvc/model/adapters/notes.txt +42 -0
  120. data/test/app/vendor/extjs-mvc/model/associations/Association.js +192 -0
  121. data/test/app/vendor/extjs-mvc/model/associations/notes.txt +87 -0
  122. data/test/app/vendor/extjs-mvc/model/validations/Errors.js +136 -0
  123. data/test/app/vendor/extjs-mvc/model/validations/Plugin.js +139 -0
  124. data/test/app/vendor/extjs-mvc/model/validations/Validations.js +276 -0
  125. data/test/app/vendor/extjs-mvc/notes/Charts.graffle +0 -0
  126. data/test/app/vendor/extjs-mvc/overrides/Ext.Component.js +21 -0
  127. data/test/app/vendor/extjs-mvc/overrides/Ext.extend.js +142 -0
  128. data/test/app/vendor/extjs-mvc/spec/Array.spec.js +15 -0
  129. data/test/app/vendor/extjs-mvc/spec/ExtMVC.spec.js +65 -0
  130. data/test/app/vendor/extjs-mvc/spec/Model.spec.js +370 -0
  131. data/test/app/vendor/extjs-mvc/spec/OS.spec.js +83 -0
  132. data/test/app/vendor/extjs-mvc/spec/Router.spec.js +99 -0
  133. data/test/app/vendor/extjs-mvc/spec/SpecHelper.js +106 -0
  134. data/test/app/vendor/extjs-mvc/spec/String.spec.js +83 -0
  135. data/test/app/vendor/extjs-mvc/spec/model/AbstractAdapter.spec.js +49 -0
  136. data/test/app/vendor/extjs-mvc/spec/model/Associations.spec.js +99 -0
  137. data/test/app/vendor/extjs-mvc/spec/model/Cache.spec.js +5 -0
  138. data/test/app/vendor/extjs-mvc/spec/model/RESTAdapter.spec.js +19 -0
  139. data/test/app/vendor/extjs-mvc/spec/model/ValidationErrors.spec.js +64 -0
  140. data/test/app/vendor/extjs-mvc/spec/model/Validations.spec.js +166 -0
  141. data/test/app/vendor/extjs-mvc/spec/model/ValidationsPlugin.spec.js +108 -0
  142. data/test/app/vendor/extjs-mvc/spec/suite.html +60 -0
  143. data/test/app/vendor/extjs-mvc/specs-old/JSSpec.css +216 -0
  144. data/test/app/vendor/extjs-mvc/specs-old/JSSpec.js +1512 -0
  145. data/test/app/vendor/extjs-mvc/specs-old/all.html +66 -0
  146. data/test/app/vendor/extjs-mvc/specs-old/base.js +14 -0
  147. data/test/app/vendor/extjs-mvc/specs-old/controller.js +17 -0
  148. data/test/app/vendor/extjs-mvc/specs-old/diff_match_patch.js +1 -0
  149. data/test/app/vendor/extjs-mvc/specs-old/model.js +70 -0
  150. data/test/app/vendor/extjs-mvc/specs-old/route.js +38 -0
  151. data/test/app/vendor/extjs-mvc/specs-old/router.js +59 -0
  152. data/test/app/vendor/extjs-mvc/specs-old/string.js +22 -0
  153. data/test/app/vendor/extjs-mvc/testrunner/JSpecFormatter.js +111 -0
  154. data/test/app/vendor/extjs-mvc/testrunner/TestClient.js +181 -0
  155. data/test/app/vendor/extjs-mvc/testrunner/TestGrid.js +351 -0
  156. data/test/app/vendor/extjs-mvc/testrunner/TestRunner.js +110 -0
  157. data/test/app/vendor/extjs-mvc/testrunner/TestViewport.js +94 -0
  158. data/test/app/vendor/extjs-mvc/vendor.yml +30 -0
  159. data/test/app/vendor/extjs-mvc/vendor/ext-3.1.1/vendor.yml +16 -0
  160. data/test/app/vendor/extjs-mvc/view/FormWindow.js +184 -0
  161. data/test/app/vendor/extjs-mvc/view/HasManyEditorGridPanel.js +211 -0
  162. data/test/app/vendor/extjs-mvc/view/scaffold/Edit.js +46 -0
  163. data/test/app/vendor/extjs-mvc/view/scaffold/Index.js +561 -0
  164. data/test/app/vendor/extjs-mvc/view/scaffold/New.js +20 -0
  165. data/test/app/vendor/extjs-mvc/view/scaffold/ScaffoldFormPanel.js +255 -0
  166. data/test/helper.rb +7 -1
  167. data/test/test_extjs-mvc.rb +46 -0
  168. metadata +167 -7
  169. data/test/test_extjs-mvc-gem.rb +0 -7
@@ -0,0 +1,351 @@
1
+ /**
2
+ * @class ExtMVC.test.TestGrid
3
+ * @extends Ext.grid.GridPanel
4
+ * Customised GridPanel which shows the results of unit tests
5
+ */
6
+ ExtMVC.test.TestGrid = Ext.extend(Ext.grid.GridPanel, {
7
+
8
+ initComponent: function() {
9
+ var expander = new Ext.ux.grid.RowExpander({
10
+ tpl : new Ext.XTemplate(
11
+ '<tpl for="failingSpecs">',
12
+ '<div class="detail">',
13
+ '<tpl for="suite">',
14
+ '<h2>Suite: {name}</h2>',
15
+ '</tpl>',
16
+ 'Expectation: {description}',
17
+ '<ul class="assertions">',
18
+ '<tpl for="assertions">',
19
+ '<li>',
20
+ '{message}',
21
+ '</li>',
22
+ '</tpl>',
23
+ '</ul>',
24
+ '<div class="code">',
25
+ '{code}',
26
+ '</div>',
27
+ '</div>',
28
+ '</tpl>'
29
+ )
30
+ });
31
+
32
+ Ext.applyIf(this, {
33
+ plugins: expander,
34
+
35
+ store: new Ext.data.JsonStore({
36
+ data : [],
37
+ fields: [
38
+ {name: 'passes', type: 'int'},
39
+ {name: 'failures', type: 'int'},
40
+ {name: 'time', type: 'int'},
41
+ {name: 'total', type: 'int', mapping: 'specs'},
42
+ {name: 'failingSpecs'}
43
+ ]
44
+ }),
45
+
46
+ cm: new Ext.grid.ColumnModel({
47
+ defaults: {
48
+ sortable: false
49
+ },
50
+ columns: [
51
+ expander,
52
+ {
53
+ header : "Passes",
54
+ dataIndex: 'passes'
55
+ },
56
+ {
57
+ header : "Failures",
58
+ dataIndex: 'failures'
59
+ },
60
+ {
61
+ header : "Total",
62
+ dataIndex: 'total'
63
+ },
64
+ {
65
+ header : "Time (ms)",
66
+ dataIndex: 'time'
67
+ }
68
+ ]
69
+ }),
70
+
71
+ viewConfig: {
72
+ forceFit: true,
73
+ getRowClass: function(record, index) {
74
+ return record.get('failures') == 0 ? 'pass' : 'fail';
75
+ }
76
+ }
77
+ });
78
+
79
+ ExtMVC.test.TestGrid.superclass.initComponent.apply(this, arguments);
80
+
81
+ /**
82
+ * When a new row has been inserted, expand it if the tests didn't all pass
83
+ * We have to do a little hack to set the rowIndex inside here, as the RowExpander
84
+ * plugin errors otherwise :/
85
+ */
86
+ this.getView().on('rowsinserted', function(view, firstRow, lastRow) {
87
+ var record = this.store.getAt(firstRow);
88
+
89
+ if (record.get('failures') > 0) {
90
+ //first, collapse all rows
91
+ this.store.each(function(record, index) {
92
+ var row = view.getRow(index);
93
+ row.rowIndex = index;
94
+
95
+ expander.collapseRow(row);
96
+ });
97
+
98
+ //now, expand the last row as it contains errors
99
+ var row = view.getRow(firstRow);
100
+ row.rowIndex = firstRow;
101
+
102
+ expander.expandRow(row);
103
+
104
+ row.scrollIntoView(this.ownerCt);
105
+ };
106
+ }, this);
107
+ }
108
+ });
109
+
110
+
111
+ /*!
112
+ * Ext JS Library 3.0+
113
+ * Copyright(c) 2006-2009 Ext JS, LLC
114
+ * licensing@extjs.com
115
+ * http://www.extjs.com/license
116
+ */
117
+ Ext.ns('Ext.ux.grid');
118
+
119
+ /**
120
+ * @class Ext.ux.grid.RowExpander
121
+ * @extends Ext.util.Observable
122
+ * Plugin (ptype = 'rowexpander') that adds the ability to have a Column in a grid which enables
123
+ * a second row body which expands/contracts. The expand/contract behavior is configurable to react
124
+ * on clicking of the column, double click of the row, and/or hitting enter while a row is selected.
125
+ *
126
+ * @ptype rowexpander
127
+ */
128
+ Ext.ux.grid.RowExpander = Ext.extend(Ext.util.Observable, {
129
+ /**
130
+ * @cfg {Boolean} expandOnEnter
131
+ * <tt>true</tt> to toggle selected row(s) between expanded/collapsed when the enter
132
+ * key is pressed (defaults to <tt>true</tt>).
133
+ */
134
+ expandOnEnter : true,
135
+ /**
136
+ * @cfg {Boolean} expandOnDblClick
137
+ * <tt>true</tt> to toggle a row between expanded/collapsed when double clicked
138
+ * (defaults to <tt>true</tt>).
139
+ */
140
+ expandOnDblClick : true,
141
+
142
+ header : '',
143
+ width : 20,
144
+ sortable : false,
145
+ fixed : true,
146
+ menuDisabled : true,
147
+ dataIndex : '',
148
+ id : 'expander',
149
+ lazyRender : true,
150
+ enableCaching : true,
151
+
152
+ constructor: function(config){
153
+ Ext.apply(this, config);
154
+
155
+ this.addEvents({
156
+ /**
157
+ * @event beforeexpand
158
+ * Fires before the row expands. Have the listener return false to prevent the row from expanding.
159
+ * @param {Object} this RowExpander object.
160
+ * @param {Object} Ext.data.Record Record for the selected row.
161
+ * @param {Object} body body element for the secondary row.
162
+ * @param {Number} rowIndex The current row index.
163
+ */
164
+ beforeexpand: true,
165
+ /**
166
+ * @event expand
167
+ * Fires after the row expands.
168
+ * @param {Object} this RowExpander object.
169
+ * @param {Object} Ext.data.Record Record for the selected row.
170
+ * @param {Object} body body element for the secondary row.
171
+ * @param {Number} rowIndex The current row index.
172
+ */
173
+ expand: true,
174
+ /**
175
+ * @event beforecollapse
176
+ * Fires before the row collapses. Have the listener return false to prevent the row from collapsing.
177
+ * @param {Object} this RowExpander object.
178
+ * @param {Object} Ext.data.Record Record for the selected row.
179
+ * @param {Object} body body element for the secondary row.
180
+ * @param {Number} rowIndex The current row index.
181
+ */
182
+ beforecollapse: true,
183
+ /**
184
+ * @event collapse
185
+ * Fires after the row collapses.
186
+ * @param {Object} this RowExpander object.
187
+ * @param {Object} Ext.data.Record Record for the selected row.
188
+ * @param {Object} body body element for the secondary row.
189
+ * @param {Number} rowIndex The current row index.
190
+ */
191
+ collapse: true
192
+ });
193
+
194
+ Ext.ux.grid.RowExpander.superclass.constructor.call(this);
195
+
196
+ if(this.tpl){
197
+ if(typeof this.tpl == 'string'){
198
+ this.tpl = new Ext.Template(this.tpl);
199
+ }
200
+ this.tpl.compile();
201
+ }
202
+
203
+ this.state = {};
204
+ this.bodyContent = {};
205
+ },
206
+
207
+ getRowClass : function(record, rowIndex, p, ds){
208
+ p.cols = p.cols-1;
209
+ var content = this.bodyContent[record.id];
210
+ if(!content && !this.lazyRender){
211
+ content = this.getBodyContent(record, rowIndex);
212
+ }
213
+ if(content){
214
+ p.body = content;
215
+ }
216
+ return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
217
+ },
218
+
219
+ init : function(grid){
220
+ this.grid = grid;
221
+
222
+ var view = grid.getView();
223
+ view.getRowClass = view.getRowClass.createSequence(this.getRowClass, this);
224
+
225
+ view.enableRowBody = true;
226
+
227
+
228
+ grid.on('render', this.onRender, this);
229
+ grid.on('destroy', this.onDestroy, this);
230
+ },
231
+
232
+ // @private
233
+ onRender: function() {
234
+ var grid = this.grid;
235
+ var mainBody = grid.getView().mainBody;
236
+ mainBody.on('mousedown', this.onMouseDown, this, {delegate: '.x-grid3-row-expander'});
237
+ if (this.expandOnEnter) {
238
+ this.keyNav = new Ext.KeyNav(this.grid.getGridEl(), {
239
+ 'enter' : this.onEnter,
240
+ scope: this
241
+ });
242
+ }
243
+ if (this.expandOnDblClick) {
244
+ grid.on('rowdblclick', this.onRowDblClick, this);
245
+ }
246
+ },
247
+
248
+ // @private
249
+ onDestroy: function() {
250
+ if(this.keyNav){
251
+ this.keyNav.disable();
252
+ delete this.keyNav;
253
+ }
254
+ /*
255
+ * A majority of the time, the plugin will be destroyed along with the grid,
256
+ * which means the mainBody won't be available. On the off chance that the plugin
257
+ * isn't destroyed with the grid, take care of removing the listener.
258
+ */
259
+ var mainBody = this.grid.getView().mainBody;
260
+ if(mainBody){
261
+ mainBody.un('mousedown', this.onMouseDown, this);
262
+ }
263
+ },
264
+ // @private
265
+ onRowDblClick: function(grid, rowIdx, e) {
266
+ this.toggleRow(rowIdx);
267
+ },
268
+
269
+ onEnter: function(e) {
270
+ var g = this.grid;
271
+ var sm = g.getSelectionModel();
272
+ var sels = sm.getSelections();
273
+ for (var i = 0, len = sels.length; i < len; i++) {
274
+ var rowIdx = g.getStore().indexOf(sels[i]);
275
+ this.toggleRow(rowIdx);
276
+ }
277
+ },
278
+
279
+ getBodyContent : function(record, index){
280
+ if(!this.enableCaching){
281
+ return this.tpl.apply(record.data);
282
+ }
283
+ var content = this.bodyContent[record.id];
284
+ if(!content){
285
+ content = this.tpl.apply(record.data);
286
+ this.bodyContent[record.id] = content;
287
+ }
288
+ return content;
289
+ },
290
+
291
+ onMouseDown : function(e, t){
292
+ e.stopEvent();
293
+ var row = e.getTarget('.x-grid3-row');
294
+ this.toggleRow(row);
295
+ },
296
+
297
+ renderer : function(v, p, record){
298
+ p.cellAttr = 'rowspan="2"';
299
+ return '<div class="x-grid3-row-expander">&#160;</div>';
300
+ },
301
+
302
+ beforeExpand : function(record, body, rowIndex){
303
+ if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){
304
+ if(this.tpl && this.lazyRender){
305
+ body.innerHTML = this.getBodyContent(record, rowIndex);
306
+ }
307
+ return true;
308
+ }else{
309
+ return false;
310
+ }
311
+ },
312
+
313
+ toggleRow : function(row){
314
+ if(typeof row == 'number'){
315
+ row = this.grid.view.getRow(row);
316
+ }
317
+ this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
318
+ },
319
+
320
+ expandRow : function(row){
321
+ if(typeof row == 'number'){
322
+ row = this.grid.view.getRow(row);
323
+ }
324
+
325
+ var record = this.grid.store.getAt(row.rowIndex);
326
+ var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
327
+ if(this.beforeExpand(record, body, row.rowIndex)){
328
+ this.state[record.id] = true;
329
+ Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
330
+ this.fireEvent('expand', this, record, body, row.rowIndex);
331
+ }
332
+ },
333
+
334
+ collapseRow : function(row){
335
+ if(typeof row == 'number'){
336
+ row = this.grid.view.getRow(row);
337
+ }
338
+ var record = this.grid.store.getAt(row.rowIndex);
339
+ var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
340
+ if(this.fireEvent('beforecollapse', this, record, body, row.rowIndex) !== false){
341
+ this.state[record.id] = false;
342
+ Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
343
+ this.fireEvent('collapse', this, record, body, row.rowIndex);
344
+ }
345
+ }
346
+ });
347
+
348
+ Ext.preg('rowexpander', Ext.ux.grid.RowExpander);
349
+
350
+ //backwards compat
351
+ Ext.grid.RowExpander = Ext.ux.grid.RowExpander;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @class ExtMVC.test.TestRunner
3
+ * @extends Ext.util.Observable
4
+ * Wraps JSpec to provide normal Ext-style events
5
+ */
6
+ ExtMVC.test.TestRunner = Ext.extend(Ext.util.Observable, {
7
+
8
+ constructor: function(config) {
9
+ ExtMVC.test.TestRunner.superclass.constructor.apply(this, arguments);
10
+
11
+ Ext.apply(this, {
12
+ /**
13
+ * @property hasRecentFailures
14
+ * @type Boolean
15
+ * True if the last full suite run had failures
16
+ */
17
+ hasRecentFailures: false,
18
+
19
+ /**
20
+ * @property fullRun
21
+ * @type Boolean
22
+ * True if the last run was a full run (as opposed to only running a subset of suites)
23
+ */
24
+ fullRun: false
25
+ });
26
+
27
+ this.addEvents(
28
+ /**
29
+ * @event starting
30
+ * Fires when the runner starts running specs
31
+ */
32
+ 'starting',
33
+
34
+ /**
35
+ * @event finished
36
+ * Fires when the runner has finished running a batch of tests
37
+ * @param {Object} stats Test pass stats
38
+ */
39
+ 'finished'
40
+ );
41
+
42
+ this.tests = [];
43
+ },
44
+
45
+ onJSpecFinish: function(options) {
46
+ runner.fireEvent('finished', JSpec.stats);
47
+
48
+ if (runner.fullRun == true) {
49
+ runner.hasRecentFailures = JSpec.stats.failures > 0;
50
+ }
51
+ },
52
+
53
+ /**
54
+ * Adds an array of test suites
55
+ * @param {Array} tests Array of urls to load test suites from
56
+ */
57
+ addTests: function(tests) {
58
+ this.tests = this.tests.concat(tests);
59
+ },
60
+
61
+ /**
62
+ * Executes an array of test files and fires the 'finished' event when complete
63
+ * @param {Array} tests Optional array of test files to run (defaults to all tests)
64
+ */
65
+ runTests: function(tests) {
66
+ //we're doing a full run if a test subset array was not passed in
67
+ this.fullRun = !Ext.isArray(tests);
68
+
69
+ tests = tests || this.tests;
70
+
71
+ delete JSpec;
72
+ var filename = "../vendor/jspec/lib/jspec.js",
73
+ callback = function() {
74
+ this.fireEvent('starting');
75
+
76
+ JSpec.options.formatter = ExtMVC.test.JSpecFormatter;
77
+
78
+ Ext.each(tests, function(test) {
79
+ JSpec.exec(test);
80
+ }, this);
81
+
82
+ JSpec.include({
83
+ utilities : {
84
+ runner: this
85
+ },
86
+ reporting : this.onJSpecFinish
87
+ });
88
+
89
+ JSpec.run({ failuresOnly: false }).report();
90
+ }.createDelegate(this);
91
+
92
+ var script = document.createElement('script');
93
+ script.type = "text/javascript";
94
+ script.src = filename;
95
+
96
+ //IE has a different way of handling <script> loads, so we need to check for it here
97
+ if (script.readyState) {
98
+ script.onreadystatechange = function(){
99
+ if (script.readyState == "loaded" || script.readyState == "complete") {
100
+ script.onreadystatechange = null;
101
+ callback();
102
+ }
103
+ };
104
+ } else {
105
+ script.onload = callback;
106
+ }
107
+
108
+ document.getElementsByTagName("head")[0].appendChild(script);
109
+ }
110
+ });