jax 2.0.5 → 2.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +24 -0
- data/features/rails/models.feature +9 -0
- data/features/step_definitions/response_steps.rb +4 -0
- data/features/support/numeric_matcher.rb +26 -0
- data/lib/assets/javascripts/jax/core/util.js +47 -0
- data/lib/assets/javascripts/jax/mvc/model.js +13 -0
- data/lib/assets/javascripts/jax/mvc/route_set.js +2 -2
- data/lib/assets/javascripts/jax/webgl/core/framebuffer.js +107 -18
- data/lib/assets/javascripts/jax/webgl/scene/light_manager.js +3 -1
- data/lib/assets/javascripts/jax/webgl/texture.js +3 -3
- data/lib/assets/javascripts/jax/webgl/world.js +1 -1
- data/lib/assets/javascripts/shaders/shadow_map/material.js +13 -8
- data/lib/jax/directive_processor.rb +14 -5
- data/lib/jax/version.rb +1 -1
- data/spec/generators/jax/scaffold_generator_spec.rb +21 -0
- data/spec/javascripts/jax/core/utils_spec.js +11 -0
- data/spec/javascripts/jax/mvc/route_set_spec.js +11 -0
- data/spec/javascripts/jax/webgl/framebuffer_spec.js +7 -0
- data/spec/javascripts/jax/webgl/lighting_spec.js +31 -2
- data/spec/javascripts/jax/world_spec.js +10 -0
- data/spec/javascripts/node_helper.js +44 -39
- metadata +46 -42
data/CHANGELOG
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
* 2.0.6 *
|
2
|
+
|
3
|
+
* Resolved issue #30: `Jax.Framebuffer#getTexture(context, index)` now returns texture
|
4
|
+
with index 0 if index was not given.
|
5
|
+
|
6
|
+
* Resolved issue #43: Plugin models appear after app models in load order.
|
7
|
+
|
8
|
+
* Minor improvements to `Jax.Framebuffer`
|
9
|
+
|
10
|
+
* `Jax.Texture` data type can now be specified, for example, in apps which make use of
|
11
|
+
the OES_texture_float extension
|
12
|
+
|
13
|
+
* Resolved issue #38: `Jax.RouteSet` now underscores CamelCase routes.
|
14
|
+
|
15
|
+
* `Jax.World#addLightSource()` now returns the light source that was added, just like
|
16
|
+
`Jax.World#addObject()` returns the object that was added.
|
17
|
+
|
18
|
+
* Resolved issue #46: Render errors when shadows are disabled, but shadowmapping is not
|
19
|
+
|
20
|
+
* Resolved issue #47: Removing an object from the scene causes infinite recursion in light
|
21
|
+
manager
|
22
|
+
|
23
|
+
|
24
|
+
|
1
25
|
* 2.0.5 *
|
2
26
|
|
3
27
|
* Setting `shadowcaster` to `false` for a light source now has the expected result: it
|
@@ -0,0 +1,9 @@
|
|
1
|
+
@rails
|
2
|
+
Feature: Models
|
3
|
+
|
4
|
+
Scenario: Plugin models loaded first
|
5
|
+
Given file "app/assets/jax/models/person.js" contains "__feature_model_person"
|
6
|
+
And file "vendor/plugins/mine/app/assets/jax/models/human.js" contains "__feature_model_human"
|
7
|
+
When I visit "/assets/jax/application.js"
|
8
|
+
# Then show me the response
|
9
|
+
Then "__feature_model_human" should come before "__feature_model_person"
|
@@ -11,3 +11,7 @@ end
|
|
11
11
|
Then /^the response should contain:$/ do |text|
|
12
12
|
(!!page.body.to_s[text]).should be_true
|
13
13
|
end
|
14
|
+
|
15
|
+
Then /^"([^"]*)" should come before "([^"]*)"$/ do |first, second|
|
16
|
+
page.body.to_s.index(first).should be_less_than(page.body.to_s.index(second))
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Matchers
|
2
|
+
class NumericMatcher
|
3
|
+
def initialize(expected, operation)
|
4
|
+
@expected, @operation = expected, operation
|
5
|
+
end
|
6
|
+
|
7
|
+
def matches?(actual)
|
8
|
+
@actual = actual
|
9
|
+
@actual.respond_to?(@operation) ? actual.send(@operation, @expected) : false
|
10
|
+
end
|
11
|
+
|
12
|
+
def failure_message
|
13
|
+
"Expected #{@actual.inspect} #{@operation} #{@expected.inspect}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def negative_failure_message
|
17
|
+
"Expected #{@actual.inspect} not #{@operation} #{@expected.inspect}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def be_less_than(other)
|
22
|
+
Matchers::NumericMatcher.new other, :<
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
World(Matchers)
|
@@ -18,6 +18,53 @@ Jax.Util = {
|
|
18
18
|
"a string representing a material in the Jax material registry");
|
19
19
|
},
|
20
20
|
|
21
|
+
gsub: function(source, pattern, replacement) {
|
22
|
+
var match, result, submatch, _replacement;
|
23
|
+
if (!((pattern != null) && (replacement != null))) {
|
24
|
+
return source;
|
25
|
+
}
|
26
|
+
result = '';
|
27
|
+
while (source.length > 0) {
|
28
|
+
if ((match = source.match(pattern))) {
|
29
|
+
// handle \1, \2, etc in replacement string
|
30
|
+
_replacement = replacement;
|
31
|
+
while (submatch = _replacement.match(/\\(\d+)/)) {
|
32
|
+
_replacement = _replacement.replace('\\'+submatch[1], match[submatch[1]]);
|
33
|
+
}
|
34
|
+
|
35
|
+
result += source.slice(0, match.index);
|
36
|
+
result += _replacement;
|
37
|
+
source = source.slice(match.index + match[0].length);
|
38
|
+
} else {
|
39
|
+
result += source;
|
40
|
+
source = '';
|
41
|
+
}
|
42
|
+
}
|
43
|
+
return result;
|
44
|
+
},
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Jax.Util.underscore(word) -> String
|
48
|
+
* word (String): a String to be converted to underscore.
|
49
|
+
*
|
50
|
+
* Takes a String, which may be in CamelCase format, and returns
|
51
|
+
* the same string converted to underscored_format. Examples:
|
52
|
+
*
|
53
|
+
* "HelloWorld" => "hello_world"
|
54
|
+
* "Hello_World" => "hello_world"
|
55
|
+
* "Hello" => "hello"
|
56
|
+
*
|
57
|
+
**/
|
58
|
+
underscore: function(word) {
|
59
|
+
word = Jax.Util.gsub(word, /::/, "\/");
|
60
|
+
word = Jax.Util.gsub(word, /([A-Z]+)([A-Z][a-z])/,'\\1_\\2');
|
61
|
+
word = Jax.Util.gsub(word, /([a-z\d])([A-Z])/,'\\1_\\2');
|
62
|
+
|
63
|
+
while (word.indexOf('-') != -1) word = word.replace('-', '_');
|
64
|
+
|
65
|
+
return word.toLowerCase();
|
66
|
+
},
|
67
|
+
|
21
68
|
/**
|
22
69
|
* Jax.Util.decodePickingColor(red, green, blue, alpha) -> Number
|
23
70
|
*
|
@@ -282,6 +282,19 @@
|
|
282
282
|
for (var id in resources)
|
283
283
|
if (this.resources[id]) throw new Error("Duplicate resource ID: "+id);
|
284
284
|
else this.resources[id] = resources[id];
|
285
|
+
},
|
286
|
+
|
287
|
+
/**
|
288
|
+
* Jax.Model.removeAllResources() -> undefined
|
289
|
+
*
|
290
|
+
* Removes all resources from this model. Existing instances won't be
|
291
|
+
* affected, but #find() will fail for any resource not re-added using
|
292
|
+
* #addResources().
|
293
|
+
*
|
294
|
+
* Useful for managing test cases, so that they can run in isolation.
|
295
|
+
**/
|
296
|
+
removeAllResources: function() {
|
297
|
+
this.resources = {};
|
285
298
|
}
|
286
299
|
};
|
287
300
|
|
@@ -66,7 +66,7 @@ Jax.RouteSet = (function() {
|
|
66
66
|
var parts = path.split(/\//);
|
67
67
|
var controller_name = parts[0];
|
68
68
|
|
69
|
-
this._map[
|
69
|
+
this._map[Jax.Util.underscore(controller_name)] = controller;
|
70
70
|
|
71
71
|
if (!Jax.views.exists(controller_name+"/index"))
|
72
72
|
Jax.views.push(controller_name+"/index", function() {
|
@@ -107,7 +107,7 @@ Jax.RouteSet = (function() {
|
|
107
107
|
var controller_name = parts[0];
|
108
108
|
var action_name = parts[1] || "index";
|
109
109
|
|
110
|
-
var controller_class = this._map[
|
110
|
+
var controller_class = this._map[Jax.Util.underscore(controller_name)];
|
111
111
|
if (!controller_class || !controller_class.prototype)
|
112
112
|
throw new Error("Route not recognized: '"+path+"' (controller not found)");
|
113
113
|
|
@@ -47,11 +47,12 @@ Jax.Framebuffer = (function() {
|
|
47
47
|
format:GL_RGBA,
|
48
48
|
width:width,
|
49
49
|
height:height,
|
50
|
-
min_filter:
|
51
|
-
mag_filter:
|
52
|
-
wrap_s:
|
53
|
-
wrap_t:
|
54
|
-
generate_mipmap:
|
50
|
+
min_filter:self.options.min_filter,
|
51
|
+
mag_filter:self.options.mag_filter,
|
52
|
+
wrap_s:self.options.wrap_s,
|
53
|
+
wrap_t:self.options.wrap_t,
|
54
|
+
generate_mipmap:self.options.generate_mipmap,
|
55
|
+
data_type: self.options.data_type
|
55
56
|
};
|
56
57
|
if (typeof(format) != "number") { texture_options = Jax.Util.normalizeOptions(format, texture_options); }
|
57
58
|
else { texture_options.format = format; }
|
@@ -66,7 +67,13 @@ Jax.Framebuffer = (function() {
|
|
66
67
|
attachment++;
|
67
68
|
}
|
68
69
|
|
69
|
-
|
70
|
+
try {
|
71
|
+
checkStatus(context, self);
|
72
|
+
} catch(e) {
|
73
|
+
// build failed, release all objects so user can (maybe) change options and try again
|
74
|
+
self.dispose(context);
|
75
|
+
throw e;
|
76
|
+
}
|
70
77
|
}
|
71
78
|
|
72
79
|
function checkStatus(context, self) {
|
@@ -101,6 +108,40 @@ Jax.Framebuffer = (function() {
|
|
101
108
|
}
|
102
109
|
|
103
110
|
return Jax.Class.create({
|
111
|
+
dispose: function(context) {
|
112
|
+
if (!this.handles) return;
|
113
|
+
|
114
|
+
var handle = this.getHandle(context);
|
115
|
+
if (!handle) return;
|
116
|
+
|
117
|
+
// handle.stencilbuffer, handle.depthbuffer, handle.depthstencilbuffer
|
118
|
+
if (handle.stencilbuffer) {
|
119
|
+
context.glDeleteRenderbuffer(handle.stencilbuffer);
|
120
|
+
delete handle.stencilbuffer;
|
121
|
+
}
|
122
|
+
if (handle.depthbuffer) {
|
123
|
+
context.glDeleteRenderbuffer(handle.depthbuffer);
|
124
|
+
delete handle.depthbuffer;
|
125
|
+
}
|
126
|
+
if (handle.depthstencilbuffer) {
|
127
|
+
context.glDeleteRenderbuffer(handle.depthstencilbuffer);
|
128
|
+
delete handle.depthstencilbuffer;
|
129
|
+
}
|
130
|
+
|
131
|
+
// texture attachments
|
132
|
+
if (handle.textures) {
|
133
|
+
while (handle.textures.length > 0) {
|
134
|
+
handle.textures[0].dispose(context);
|
135
|
+
handle.textures.splice(0, 1);
|
136
|
+
}
|
137
|
+
delete handle.textures;
|
138
|
+
}
|
139
|
+
|
140
|
+
// finally, delete the framebuffer itself
|
141
|
+
context.glDeleteFramebuffer(handle);
|
142
|
+
this.setHandle(context, null);
|
143
|
+
},
|
144
|
+
|
104
145
|
/**
|
105
146
|
* new Jax.Framebuffer([options])
|
106
147
|
* - options (Object): a generic object containing the following optional properties:
|
@@ -120,6 +161,15 @@ Jax.Framebuffer = (function() {
|
|
120
161
|
* framebuffer must have the same width. Defaults to 512.
|
121
162
|
* * height: the height of the render and color buffers. All render and color buffers for a given
|
122
163
|
* framebuffer must have the same height. Defaults to 512.
|
164
|
+
*
|
165
|
+
* The following options may also be present. If they are, they will be passed into Jax.Texture:
|
166
|
+
*
|
167
|
+
* * data_type: defaults to GL_UNSIGNED_BYTE
|
168
|
+
* * min_filter: defaults to GL_LINEAR
|
169
|
+
* * mag_filter: defaults to GL_LINEAR
|
170
|
+
* * wrap_s: defaults to GL_CLAMP_TO_EDGE
|
171
|
+
* * wrap_t: defaults to GL_CLAMP_TO_EDGE
|
172
|
+
* * generate_mipmap: defaults to false
|
123
173
|
*
|
124
174
|
**/
|
125
175
|
initialize: function(options) {
|
@@ -127,7 +177,13 @@ Jax.Framebuffer = (function() {
|
|
127
177
|
depth: false,
|
128
178
|
stencil: false,
|
129
179
|
width:512,
|
130
|
-
height:512
|
180
|
+
height:512,
|
181
|
+
data_type: GL_UNSIGNED_BYTE,
|
182
|
+
min_filter: GL_LINEAR,
|
183
|
+
mag_filter: GL_LINEAR,
|
184
|
+
wrap_s: GL_CLAMP_TO_EDGE,
|
185
|
+
wrap_t: GL_CLAMP_TO_EDGE,
|
186
|
+
generate_mipmap: false
|
131
187
|
};
|
132
188
|
if (!(options && (options.color || options.colors))) defaults.colors = [GL_RGBA];
|
133
189
|
|
@@ -151,12 +207,12 @@ Jax.Framebuffer = (function() {
|
|
151
207
|
* For cube map framebuffers only, this will bind the specified cube map face to its color buffer position.
|
152
208
|
* The faceEnum can be any of the following face enums:
|
153
209
|
*
|
154
|
-
* 0
|
155
|
-
* 1
|
156
|
-
* 2
|
157
|
-
* 3
|
158
|
-
* 4
|
159
|
-
* 5
|
210
|
+
* 0 or GL_TEXTURE_CUBE_MAP_POSITIVE_X
|
211
|
+
* 1 or GL_TEXTURE_CUBE_MAP_NEGATIVE_X
|
212
|
+
* 2 or GL_TEXTURE_CUBE_MAP_POSITIVE_Y
|
213
|
+
* 3 or GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
|
214
|
+
* 4 or GL_TEXTURE_CUBE_MAP_POSITIVE_Z
|
215
|
+
* 5 or GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
160
216
|
*
|
161
217
|
* Example:
|
162
218
|
*
|
@@ -168,8 +224,7 @@ Jax.Framebuffer = (function() {
|
|
168
224
|
* });
|
169
225
|
**/
|
170
226
|
bindCubeFace: function(context, texIndex, faceEnum, callback) {
|
171
|
-
|
172
|
-
var texture = this.getHandle(context).textures[texIndex];
|
227
|
+
var texture = this.getTexture(context, texIndex);
|
173
228
|
if (texture.options.target != GL_TEXTURE_CUBE_MAP)
|
174
229
|
throw new Error("Texture at index "+texIndex+" is not a cube map!");
|
175
230
|
|
@@ -198,7 +253,7 @@ Jax.Framebuffer = (function() {
|
|
198
253
|
*
|
199
254
|
**/
|
200
255
|
bind: function(context, callback) {
|
201
|
-
|
256
|
+
this.validate(context);
|
202
257
|
context.glBindFramebuffer(GL_FRAMEBUFFER, this.getHandle(context));
|
203
258
|
|
204
259
|
if (callback) {
|
@@ -209,6 +264,33 @@ Jax.Framebuffer = (function() {
|
|
209
264
|
return this;
|
210
265
|
},
|
211
266
|
|
267
|
+
/**
|
268
|
+
* Jax.Framebuffer#validate(context) -> Jax.Framebuffer
|
269
|
+
* - context (Jax.Context): the context to validate this framebuffer for
|
270
|
+
*
|
271
|
+
* If this framebuffer's underlying WebGL counterpart has not yet been
|
272
|
+
* created, this method will do so. This method may raise errors per the
|
273
|
+
* WebGL specification if the framebuffer is not complete or compatible
|
274
|
+
* with the client hardware.
|
275
|
+
*
|
276
|
+
* After successful construction, or if the framebuffer has already been
|
277
|
+
* built, this framebuffer is returned.
|
278
|
+
**/
|
279
|
+
validate: function(context) {
|
280
|
+
if (!this.getHandle(context)) build(context, this);
|
281
|
+
return this;
|
282
|
+
},
|
283
|
+
|
284
|
+
/**
|
285
|
+
* Jax.Framebuffer#countTextures(context) -> Jax.Framebuffer
|
286
|
+
* - context (Jax.Context): a WebGL context
|
287
|
+
*
|
288
|
+
* Returns the number of textures associated with this framebuffer.
|
289
|
+
**/
|
290
|
+
countTextures: function(context) {
|
291
|
+
return this.validate().getHandle(context).textures.length;
|
292
|
+
},
|
293
|
+
|
212
294
|
/**
|
213
295
|
* Jax.Framebuffer#unbind(context) -> Jax.Framebuffer
|
214
296
|
* - context (Jax.Context): the context to bind this framebuffer to
|
@@ -245,7 +327,8 @@ Jax.Framebuffer = (function() {
|
|
245
327
|
* first texture available is returned.
|
246
328
|
**/
|
247
329
|
getTexture: function(context, index) {
|
248
|
-
|
330
|
+
this.validate(context);
|
331
|
+
return this.getHandle(context).textures[index || 0];
|
249
332
|
},
|
250
333
|
|
251
334
|
/**
|
@@ -311,6 +394,12 @@ Jax.Framebuffer = (function() {
|
|
311
394
|
*
|
312
395
|
* Returns this instance of Jax.Framebuffer.
|
313
396
|
**/
|
314
|
-
setHandle: function(context, handle) {
|
397
|
+
setHandle: function(context, handle) {
|
398
|
+
if (handle)
|
399
|
+
this.handles[context.id] = handle;
|
400
|
+
else if (this.handles[context.id])
|
401
|
+
delete this.handles[context.id];
|
402
|
+
return this;
|
403
|
+
}
|
315
404
|
});
|
316
405
|
})();
|
@@ -17,6 +17,7 @@ Jax.Scene.LightManager = (function() {
|
|
17
17
|
},
|
18
18
|
|
19
19
|
removeObject: function(obj) {
|
20
|
+
// if obj is a number, remove that index
|
20
21
|
if (this.objects[obj]) {
|
21
22
|
var o = this.objects[obj];
|
22
23
|
this.objects.splice(obj, 1);
|
@@ -26,9 +27,10 @@ Jax.Scene.LightManager = (function() {
|
|
26
27
|
this.recalculateBoundingRadius();
|
27
28
|
return o;
|
28
29
|
}
|
30
|
+
// ...if it's not, find its index and remove it.
|
29
31
|
for (var i = 0; i < this.objects.length; i++)
|
30
32
|
if (this.objects[i] == obj)
|
31
|
-
return this.removeObject(
|
33
|
+
return this.removeObject(i);
|
32
34
|
},
|
33
35
|
|
34
36
|
getShadowCasters: function() {
|
@@ -80,10 +80,10 @@ Jax.Texture = (function() {
|
|
80
80
|
|
81
81
|
function ti2d(glEnum) {
|
82
82
|
try {
|
83
|
-
context.glTexImage2D(glEnum, 0, format, width, height, 0, format,
|
83
|
+
context.glTexImage2D(glEnum, 0, format, width, height, 0, format, data_type, null);
|
84
84
|
} catch (e) {
|
85
85
|
var tex = new Uint8Array(width*height*Jax.Util.sizeofFormat(format));
|
86
|
-
context.glTexImage2D(glEnum, 0, format, width, height, 0, format,
|
86
|
+
context.glTexImage2D(glEnum, 0, format, width, height, 0, format, data_type, tex);
|
87
87
|
}
|
88
88
|
}
|
89
89
|
|
@@ -391,7 +391,7 @@ Jax.Texture = (function() {
|
|
391
391
|
* to dispose the texture for all contexts except for one).
|
392
392
|
**/
|
393
393
|
dispose: function(context) {
|
394
|
-
context.glDeleteTexture(getHandle(context));
|
394
|
+
context.glDeleteTexture(this.getHandle(context));
|
395
395
|
delete this.handles[context.id];
|
396
396
|
},
|
397
397
|
|
@@ -31,7 +31,7 @@ Jax.World = (function() {
|
|
31
31
|
*
|
32
32
|
* Adds the light to the world and then returns the light itself unchanged.
|
33
33
|
**/
|
34
|
-
addLightSource: function(light) { this.lighting.add(light); },
|
34
|
+
addLightSource: function(light) { this.lighting.add(light); return light; },
|
35
35
|
|
36
36
|
/**
|
37
37
|
* Jax.World#addObject(object) -> Jax.Model
|
@@ -4,21 +4,26 @@ Jax.Material.ShadowMap = Jax.Class.create(Jax.Material, {
|
|
4
4
|
},
|
5
5
|
|
6
6
|
setVariables: function(context, mesh, options, vars) {
|
7
|
+
var light = context.world.lighting.getLight();
|
8
|
+
var shadowmap_enabled = light.isShadowMapEnabled();
|
9
|
+
|
7
10
|
vars.set({
|
8
11
|
DP_SHADOW_NEAR: 0.1, //c.world.lighting.getLight().getDPShadowNear() || 0.1;}},
|
9
12
|
DP_SHADOW_FAR: 500,//c.world.lighting.getLight().getDPShadowFar() || 500;}},
|
10
13
|
|
11
14
|
SHADOWMAP_PCF_ENABLED: false,
|
12
|
-
|
13
|
-
SHADOWMAP_ENABLED: context.world.lighting.getLight().isShadowMapEnabled()
|
15
|
+
SHADOWMAP_ENABLED: shadowmap_enabled
|
14
16
|
});
|
15
17
|
|
16
|
-
|
18
|
+
if (shadowmap_enabled) {
|
19
|
+
vars.set({SHADOWMAP_MATRIX: light.getShadowMatrix()});
|
20
|
+
var front, back;
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
front = light.getShadowMapTextures(context)[0];
|
23
|
+
back = light.getShadowMapTextures(context)[1];
|
24
|
+
|
25
|
+
if (front) vars.texture('SHADOWMAP0', front, context);
|
26
|
+
if (back) vars.texture('SHADOWMAP1', back, context);
|
27
|
+
}
|
23
28
|
}
|
24
29
|
});
|
@@ -25,6 +25,8 @@ module Jax
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def process_require_everything_matching_directive(subpath)
|
28
|
+
# TODO this method is very dirty. Make it prettier.
|
29
|
+
|
28
30
|
# depend on any base subpath directories that may exist
|
29
31
|
# this should pick up any new shaders as they are added to app
|
30
32
|
context.environment.paths.each do |base_path|
|
@@ -33,7 +35,6 @@ module Jax
|
|
33
35
|
end
|
34
36
|
|
35
37
|
files = []
|
36
|
-
# context.environment.each_logical_path do |path|
|
37
38
|
context.environment.each_file do |path|
|
38
39
|
# skip all.js and skip manifest.yml
|
39
40
|
path = path.to_s
|
@@ -42,12 +43,20 @@ module Jax
|
|
42
43
|
logical_path = attrs.logical_path
|
43
44
|
if logical_path[/^#{Regexp::escape subpath}/]
|
44
45
|
# skip if logical path has already been processed
|
45
|
-
|
46
|
-
files <<
|
47
|
-
path = context.resolve(logical_path).to_s
|
48
|
-
process_require_directive path
|
46
|
+
ary = [ path, logical_path ]
|
47
|
+
files << ary unless files.include?(ary)
|
49
48
|
end
|
50
49
|
end
|
50
|
+
|
51
|
+
# order files so they appear in order: plugin files, then app files.
|
52
|
+
plugins_path = 'vendor/plugins'
|
53
|
+
numerize = proc { |a| a[plugins_path] ? 0 : 1 }
|
54
|
+
files.sort! { |a, b| numerize.call(a[0]) <=> numerize.call(b[0]) }
|
55
|
+
|
56
|
+
# require files, now that they are in order
|
57
|
+
files.each do |(path, logical_path)|
|
58
|
+
process_require_directive path
|
59
|
+
end
|
51
60
|
end
|
52
61
|
end
|
53
62
|
end
|
data/lib/jax/version.rb
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'jax:scaffold' do
|
4
|
+
with_args "test_breaker" do
|
5
|
+
it "should camelize model name" do
|
6
|
+
subject.should generate("app/assets/jax/models/test_breaker.js.coffee") { |f|
|
7
|
+
f.should =~ /TestBreaker/
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should camelize controller name" do
|
12
|
+
subject.should generate("app/assets/jax/controllers/test_breaker_controller.js.coffee") { |f|
|
13
|
+
f.should =~ /TestBreaker/
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should camelize names in controller spec" do
|
18
|
+
subject.should generate("spec/javascripts/jax/controllers/test_breaker_controller_spec.js.coffee") { |f|
|
19
|
+
f.should =~ /describe "TestBreakerController"/
|
20
|
+
f.should =~ /redirectTo "test_breaker/
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
4
25
|
with_args "dungeon" do
|
5
26
|
it "should generate dungeon model" do
|
6
27
|
subject.should generate("app/assets/jax/models/dungeon.js.coffee")
|
@@ -1,4 +1,15 @@
|
|
1
1
|
describe("Jax.Util", function() {
|
2
|
+
describe("underscore", function() {
|
3
|
+
it("should work", function() {
|
4
|
+
expect(Jax.Util.underscore("Product")).toEqual("product");
|
5
|
+
expect(Jax.Util.underscore("SpecialGuest")).toEqual("special_guest");
|
6
|
+
expect(Jax.Util.underscore("ApplicationController")).toEqual("application_controller");
|
7
|
+
expect(Jax.Util.underscore("Area51Controller")).toEqual("area51_controller");
|
8
|
+
expect(Jax.Util.underscore("HTMLTidy")).toEqual('html_tidy');
|
9
|
+
expect(Jax.Util.underscore('HTMLTidyGenerator')).toEqual('html_tidy_generator');
|
10
|
+
});
|
11
|
+
});
|
12
|
+
|
2
13
|
describe("vectorize", function() {
|
3
14
|
var data;
|
4
15
|
|
@@ -5,6 +5,17 @@ describe("Jax.RouteSet", function() {
|
|
5
5
|
|
6
6
|
beforeEach(function() { map = Jax.routes; map.clear(); });
|
7
7
|
|
8
|
+
describe("when a CamelCase controller name is given", function() {
|
9
|
+
beforeEach(function() {
|
10
|
+
controller_class = Jax.Controller.create("TestBreaker", {index: function() { }});
|
11
|
+
});
|
12
|
+
|
13
|
+
it("should recognize underscored route names", function() {
|
14
|
+
var route = map.recognizeRoute("test_breaker");
|
15
|
+
expect(route.controller).toEqual(controller_class);
|
16
|
+
});
|
17
|
+
});
|
18
|
+
|
8
19
|
describe("when a controller name is given during controller definition", function() {
|
9
20
|
beforeEach(function() {
|
10
21
|
controller_class = Jax.Controller.create("welcome", {index: function() { }});
|
@@ -1,6 +1,13 @@
|
|
1
1
|
describe("Framebuffer", function() {
|
2
2
|
var buf;
|
3
3
|
|
4
|
+
it("should return the first texture if index not given (issue #30)", function() {
|
5
|
+
// https://github.com/sinisterchipmunk/jax/issues/30
|
6
|
+
buf = new Jax.Framebuffer();
|
7
|
+
expect(buf.getTexture(SPEC_CONTEXT)).toBeTruthy();
|
8
|
+
expect(buf.getTexture(SPEC_CONTEXT)).toBe(buf.getTexture(SPEC_CONTEXT, 0));
|
9
|
+
});
|
10
|
+
|
4
11
|
describe("with no attachments", function() {
|
5
12
|
beforeEach(function() { buf = new Jax.Framebuffer(); });
|
6
13
|
|
@@ -3,11 +3,12 @@ describe("LightManager", function() {
|
|
3
3
|
|
4
4
|
describe("when a light resource is defined with shadowcasting disabled", function() {
|
5
5
|
beforeEach(function() {
|
6
|
+
LightSource.removeAllResources();
|
6
7
|
LightSource.addResources({"__test_shadowcast_disabled":{
|
7
8
|
shadowcaster:!1,enabled:!0,
|
8
9
|
position:{x:-20,y:0,z:0},
|
9
|
-
type:"
|
10
|
-
attenuation:{constant:
|
10
|
+
type:"DIRECTIONAL_LIGHT",
|
11
|
+
attenuation:{constant:1,linear:0,quadratic:0},
|
11
12
|
color:{ambient:{red:.15,green:.15,blue:.15,alpha:1},
|
12
13
|
diffuse:{red:.33,green:.1843137254901961,blue:.12679738562091503,alpha:1},
|
13
14
|
specular:{red:0,green:0,blue:0,alpha:0}}}});
|
@@ -16,6 +17,17 @@ describe("LightManager", function() {
|
|
16
17
|
it("should not be a shadow caster", function() {
|
17
18
|
expect(LightSource.find("__test_shadowcast_disabled").isShadowCaster()).toBeFalsy();
|
18
19
|
});
|
20
|
+
|
21
|
+
it("should not cause render errors with materials that have shadow mapping enabled", function() {
|
22
|
+
var model = new Jax.Model({position:[-20,0,0], lit: true, shadow_caster: false, mesh: new Jax.Mesh.Cube()});
|
23
|
+
model.mesh.lit = true;
|
24
|
+
model.mesh.default_material = new Jax.Material({ layers:[ {type:"Lighting"} ] });
|
25
|
+
model.mesh.default_material.addLayer(new Jax.Material.ShadowMap());
|
26
|
+
|
27
|
+
SPEC_CONTEXT.world.addLightSource("__test_shadowcast_disabled");
|
28
|
+
SPEC_CONTEXT.world.addObject(model);
|
29
|
+
SPEC_CONTEXT.world.render();
|
30
|
+
});
|
19
31
|
});
|
20
32
|
|
21
33
|
describe("when more than 1 light source is active", function() {
|
@@ -66,7 +78,24 @@ describe("LightManager", function() {
|
|
66
78
|
});
|
67
79
|
|
68
80
|
describe("by default", function() {
|
81
|
+
var model;
|
69
82
|
beforeEach(function() { mgr = new Jax.Scene.LightManager(); });
|
83
|
+
|
84
|
+
describe("after adding an object", function() {
|
85
|
+
beforeEach(function() { mgr.addObject(model = new Jax.Model({shadow_caster:true})); });
|
86
|
+
|
87
|
+
it("should be in the shadowcasters list", function() {
|
88
|
+
expect(mgr.getShadowCasters().length).toEqual(1);
|
89
|
+
});
|
90
|
+
|
91
|
+
describe("removing the object", function() {
|
92
|
+
beforeEach(function() { mgr.removeObject(model); });
|
93
|
+
|
94
|
+
it("should be gone", function() {
|
95
|
+
expect(mgr.getShadowCasters().length).toEqual(0);
|
96
|
+
});
|
97
|
+
});
|
98
|
+
});
|
70
99
|
|
71
100
|
it("should not be enabled", function() {
|
72
101
|
expect(mgr.isEnabled()).toBeFalsy();
|
@@ -14,6 +14,16 @@ describe("Jax.World", function() {
|
|
14
14
|
world = SPEC_CONTEXT.world;
|
15
15
|
});
|
16
16
|
|
17
|
+
it("should return objects added to world", function() {
|
18
|
+
var obj = new (Jax.Model.create({one:1}))();
|
19
|
+
expect(world.addObject(obj)).toBe(obj);
|
20
|
+
});
|
21
|
+
|
22
|
+
it("should return light sources added to world", function() {
|
23
|
+
var lite = new Jax.Scene.LightSource();
|
24
|
+
expect(world.addLightSource(lite)).toBe(lite);
|
25
|
+
});
|
26
|
+
|
17
27
|
describe("picking", function() {
|
18
28
|
var at, ofront, otopleft, otopright, obottomleft, obottomright, mesh;
|
19
29
|
|
@@ -1,51 +1,56 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
// This file's name matches the regexp used to load Jasmine helpers,
|
2
|
+
// so we need to code a special case to avoid causing errors.
|
3
|
+
|
4
|
+
if (typeof(require) != 'undefined') {
|
5
|
+
var jsdom = require('jsdom'),
|
6
|
+
doc = jsdom.jsdom('<html><body></body></html>');
|
3
7
|
|
4
|
-
global.document = doc;
|
5
|
-
global.window = doc.createWindow();
|
8
|
+
global.document = doc;
|
9
|
+
global.window = doc.createWindow();
|
6
10
|
|
7
|
-
global.ENV = global.ENV || process.env;
|
8
|
-
global.ENV['SILENCED'] = '1';
|
11
|
+
global.ENV = global.ENV || process.env;
|
12
|
+
global.ENV['SILENCED'] = '1';
|
9
13
|
|
10
|
-
/* TODO remove this when node-canvas supports webgl */
|
11
|
-
var canvas = document._elementBuilders.canvas;
|
12
|
-
document._elementBuilders.canvas = function(document, tagName) {
|
13
|
-
|
14
|
-
|
14
|
+
/* TODO remove this when node-canvas supports webgl */
|
15
|
+
var canvas = document._elementBuilders.canvas;
|
16
|
+
document._elementBuilders.canvas = function(document, tagName) {
|
17
|
+
var element = canvas.call(this, document, tagName);
|
18
|
+
var getContext = element.getContext;
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
element.getContext = function(name) {
|
21
|
+
if (name == "webgl" || name == "experimental-webgl") {
|
22
|
+
return require("./node/mocks/webgl.js").context();
|
23
|
+
} else {
|
24
|
+
return getContext.call(this, name);
|
25
|
+
}
|
26
|
+
};
|
23
27
|
|
24
|
-
|
28
|
+
element.width = element.height = 100;
|
25
29
|
|
26
|
-
|
27
|
-
};
|
30
|
+
return element;
|
31
|
+
};
|
28
32
|
|
29
|
-
// mock navigator
|
30
|
-
global.navigator = {
|
31
|
-
|
32
|
-
};
|
33
|
+
// mock navigator
|
34
|
+
global.navigator = {
|
35
|
+
userAgent: 'firefox'
|
36
|
+
};
|
33
37
|
|
34
|
-
global.Image = global.Image || function() {
|
35
|
-
|
38
|
+
global.Image = global.Image || function() {
|
39
|
+
var src;
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
|
41
|
+
this.__defineGetter__("src", function() {
|
42
|
+
return src;
|
43
|
+
});
|
40
44
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
};
|
45
|
+
this.__defineSetter__("src", function(s) {
|
46
|
+
src = s;
|
47
|
+
if (this.onload) this.onload();
|
48
|
+
return src;
|
49
|
+
});
|
50
|
+
};
|
47
51
|
|
48
|
-
global.Jax = require("../../tmp/jax.js").Jax;
|
52
|
+
global.Jax = require("../../tmp/jax.js").Jax;
|
49
53
|
|
50
|
-
require("./helpers/jax_spec_environment_helper.js");
|
51
|
-
setupJaxSpecContext();
|
54
|
+
require("./helpers/jax_spec_environment_helper.js");
|
55
|
+
setupJaxSpecContext();
|
56
|
+
} // if (typeof(require) != 'undefined')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-17 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &2153610220 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.1.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153610220
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: jquery-rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &2153609620 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.0.13
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153609620
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jasmine
|
38
|
-
requirement: &
|
38
|
+
requirement: &2153609040 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.0.2.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2153609040
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rest-client
|
49
|
-
requirement: &
|
49
|
+
requirement: &2153608480 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.6.3
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2153608480
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &2153593920 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 2.6.0
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2153593920
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: coffee-rails
|
71
|
-
requirement: &
|
71
|
+
requirement: &2153593380 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 3.1.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *2153593380
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: coderay
|
82
|
-
requirement: &
|
82
|
+
requirement: &2153592720 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: 0.9.7
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *2153592720
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: sqlite3
|
93
|
-
requirement: &
|
93
|
+
requirement: &2153592180 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: 1.3.4
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *2153592180
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: sass-rails
|
104
|
-
requirement: &
|
104
|
+
requirement: &2153591580 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ~>
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: 3.1.0
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *2153591580
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: uglifier
|
115
|
-
requirement: &
|
115
|
+
requirement: &2153591000 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - ~>
|
@@ -120,10 +120,10 @@ dependencies:
|
|
120
120
|
version: 1.0.2
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *2153591000
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: genspec
|
126
|
-
requirement: &
|
126
|
+
requirement: &2153590400 !ruby/object:Gem::Requirement
|
127
127
|
none: false
|
128
128
|
requirements:
|
129
129
|
- - ~>
|
@@ -131,10 +131,10 @@ dependencies:
|
|
131
131
|
version: 0.2.3
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
|
-
version_requirements: *
|
134
|
+
version_requirements: *2153590400
|
135
135
|
- !ruby/object:Gem::Dependency
|
136
136
|
name: selenium-webdriver
|
137
|
-
requirement: &
|
137
|
+
requirement: &2153589820 !ruby/object:Gem::Requirement
|
138
138
|
none: false
|
139
139
|
requirements:
|
140
140
|
- - ~>
|
@@ -142,10 +142,10 @@ dependencies:
|
|
142
142
|
version: 2.9.1
|
143
143
|
type: :development
|
144
144
|
prerelease: false
|
145
|
-
version_requirements: *
|
145
|
+
version_requirements: *2153589820
|
146
146
|
- !ruby/object:Gem::Dependency
|
147
147
|
name: fakeweb
|
148
|
-
requirement: &
|
148
|
+
requirement: &2153589220 !ruby/object:Gem::Requirement
|
149
149
|
none: false
|
150
150
|
requirements:
|
151
151
|
- - ~>
|
@@ -153,10 +153,10 @@ dependencies:
|
|
153
153
|
version: 1.3.0
|
154
154
|
type: :development
|
155
155
|
prerelease: false
|
156
|
-
version_requirements: *
|
156
|
+
version_requirements: *2153589220
|
157
157
|
- !ruby/object:Gem::Dependency
|
158
158
|
name: ansi
|
159
|
-
requirement: &
|
159
|
+
requirement: &2153588720 !ruby/object:Gem::Requirement
|
160
160
|
none: false
|
161
161
|
requirements:
|
162
162
|
- - ! '>='
|
@@ -164,10 +164,10 @@ dependencies:
|
|
164
164
|
version: '0'
|
165
165
|
type: :development
|
166
166
|
prerelease: false
|
167
|
-
version_requirements: *
|
167
|
+
version_requirements: *2153588720
|
168
168
|
- !ruby/object:Gem::Dependency
|
169
169
|
name: cucumber-rails
|
170
|
-
requirement: &
|
170
|
+
requirement: &2153588060 !ruby/object:Gem::Requirement
|
171
171
|
none: false
|
172
172
|
requirements:
|
173
173
|
- - ~>
|
@@ -175,10 +175,10 @@ dependencies:
|
|
175
175
|
version: 1.0.2
|
176
176
|
type: :development
|
177
177
|
prerelease: false
|
178
|
-
version_requirements: *
|
178
|
+
version_requirements: *2153588060
|
179
179
|
- !ruby/object:Gem::Dependency
|
180
180
|
name: RedCloth
|
181
|
-
requirement: &
|
181
|
+
requirement: &2153587440 !ruby/object:Gem::Requirement
|
182
182
|
none: false
|
183
183
|
requirements:
|
184
184
|
- - ~>
|
@@ -186,10 +186,10 @@ dependencies:
|
|
186
186
|
version: '4.2'
|
187
187
|
type: :development
|
188
188
|
prerelease: false
|
189
|
-
version_requirements: *
|
189
|
+
version_requirements: *2153587440
|
190
190
|
- !ruby/object:Gem::Dependency
|
191
191
|
name: w3c_validators
|
192
|
-
requirement: &
|
192
|
+
requirement: &2153586860 !ruby/object:Gem::Requirement
|
193
193
|
none: false
|
194
194
|
requirements:
|
195
195
|
- - ~>
|
@@ -197,10 +197,10 @@ dependencies:
|
|
197
197
|
version: '1.2'
|
198
198
|
type: :development
|
199
199
|
prerelease: false
|
200
|
-
version_requirements: *
|
200
|
+
version_requirements: *2153586860
|
201
201
|
- !ruby/object:Gem::Dependency
|
202
202
|
name: treetop
|
203
|
-
requirement: &
|
203
|
+
requirement: &2153586280 !ruby/object:Gem::Requirement
|
204
204
|
none: false
|
205
205
|
requirements:
|
206
206
|
- - ~>
|
@@ -208,10 +208,10 @@ dependencies:
|
|
208
208
|
version: 1.4.9
|
209
209
|
type: :development
|
210
210
|
prerelease: false
|
211
|
-
version_requirements: *
|
211
|
+
version_requirements: *2153586280
|
212
212
|
- !ruby/object:Gem::Dependency
|
213
213
|
name: bluecloth
|
214
|
-
requirement: &
|
214
|
+
requirement: &2153584940 !ruby/object:Gem::Requirement
|
215
215
|
none: false
|
216
216
|
requirements:
|
217
217
|
- - ~>
|
@@ -219,7 +219,7 @@ dependencies:
|
|
219
219
|
version: 2.0.11
|
220
220
|
type: :development
|
221
221
|
prerelease: false
|
222
|
-
version_requirements: *
|
222
|
+
version_requirements: *2153584940
|
223
223
|
description: ! "\n Framework for creating rich WebGL-enabled applications using
|
224
224
|
JavaScript and Ruby.\n Can be used stand-alone to create static JavaScript documents,
|
225
225
|
or integrated\n seamlessly with Ruby on Rails to build dynamic WebGL applications.\n
|
@@ -259,6 +259,7 @@ files:
|
|
259
259
|
- bin/jax
|
260
260
|
- config.ru
|
261
261
|
- config/routes.rb
|
262
|
+
- features/rails/models.feature
|
262
263
|
- features/rails/resources.feature
|
263
264
|
- features/rails/shaders.feature
|
264
265
|
- features/rails/specs.feature
|
@@ -268,6 +269,7 @@ files:
|
|
268
269
|
- features/step_definitions/runtime.rb
|
269
270
|
- features/step_definitions/web_steps.rb
|
270
271
|
- features/support/env.rb
|
272
|
+
- features/support/numeric_matcher.rb
|
271
273
|
- features/support/paths.rb
|
272
274
|
- features/support/rails_environment.rb
|
273
275
|
- features/support/selectors.rb
|
@@ -646,7 +648,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
646
648
|
version: '0'
|
647
649
|
segments:
|
648
650
|
- 0
|
649
|
-
hash:
|
651
|
+
hash: 1570841926271225879
|
650
652
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
651
653
|
none: false
|
652
654
|
requirements:
|
@@ -655,7 +657,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
655
657
|
version: '0'
|
656
658
|
segments:
|
657
659
|
- 0
|
658
|
-
hash:
|
660
|
+
hash: 1570841926271225879
|
659
661
|
requirements: []
|
660
662
|
rubyforge_project: jax
|
661
663
|
rubygems_version: 1.8.10
|
@@ -664,6 +666,7 @@ specification_version: 3
|
|
664
666
|
summary: Framework for creating rich WebGL-enabled applications using JavaScript and
|
665
667
|
Ruby
|
666
668
|
test_files:
|
669
|
+
- features/rails/models.feature
|
667
670
|
- features/rails/resources.feature
|
668
671
|
- features/rails/shaders.feature
|
669
672
|
- features/rails/specs.feature
|
@@ -673,6 +676,7 @@ test_files:
|
|
673
676
|
- features/step_definitions/runtime.rb
|
674
677
|
- features/step_definitions/web_steps.rb
|
675
678
|
- features/support/env.rb
|
679
|
+
- features/support/numeric_matcher.rb
|
676
680
|
- features/support/paths.rb
|
677
681
|
- features/support/rails_environment.rb
|
678
682
|
- features/support/selectors.rb
|