js2 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog CHANGED
@@ -1,3 +1,10 @@
1
+ == 0.0.10
2
+ * fixed last child bug
3
+ * added more features to *.js.yml extension
4
+ * require array of files or classes (added before code in orig file)
5
+ * include array of files or classes (added after code in orig file)
6
+ * fixed bug regarding make_compilation feature
7
+
1
8
  == 0.0.9 2009-12-23
2
9
  * large 1st move to runtime js2
3
10
 
data/Manifest.txt CHANGED
@@ -28,5 +28,8 @@ lib/js2/sel_decorator.rb
28
28
  lib/js2/tokenizer.rl.erb
29
29
  lib/js2/tree.rb
30
30
  lib/js2/universe.rb
31
+ lib/js2/test/selenium.rb
32
+ lib/js2/test/selenium_element.rb
33
+ lib/js2/test/selenium_helper.rb
31
34
  bin/js2
32
35
  website/index.txt
data/bin/js2 CHANGED
@@ -35,6 +35,10 @@ op = OptionParser.new do |opts|
35
35
  options[:daemonize] = true
36
36
  end
37
37
 
38
+ opts.on("-y YAML_FILE", "--yml YAML_FILE", "Use yml config") do |f|
39
+ options[:yml] = f
40
+ end
41
+
38
42
  opts.on('-h', "--help", "Help Screen") do
39
43
  puts opts
40
44
  exit
@@ -65,6 +69,16 @@ if !dir && File.directory?("./public/javascripts")
65
69
  dir = "./public/javascripts"
66
70
  end
67
71
 
72
+ if options[:yml]
73
+ d = JS2::Processor.daemon_from_yaml(options[:yml])
74
+ d.run do
75
+ puts "Recompiled: " + Time.now.to_s
76
+ sleep 0.5
77
+ end
78
+
79
+ exit
80
+ end
81
+
68
82
  options[:js2_dir] ||= '.'
69
83
  options[:js2_haml_dir] ||= '.'
70
84
  options[:write_dir] ||= '.'
@@ -108,6 +108,7 @@ class JS2.SelMarker {
108
108
  var classname = klass['class'].className.match(/\.\w+$/)[0];
109
109
  return namespace + classname;
110
110
  } else {
111
+ if (!klass.className) return klass['class'].className;
111
112
  return klass.className;
112
113
  }
113
114
  }
@@ -1,4 +1,6 @@
1
1
  class JS2::FileHandler
2
+ attr_accessor :read_dir, :write_dir
3
+
2
4
  def initialize (params = {})
3
5
  @read_dir = params[:read_dir]
4
6
  @write_dir = params[:write_dir] || @read_dir
@@ -6,6 +8,7 @@ class JS2::FileHandler
6
8
  @view_dir = params[:view_dir] || @read_dir
7
9
  @yml_dir = params[:read_dir]
8
10
 
11
+ puts self.inspect
9
12
  @mtimes = Hash.new
10
13
  end
11
14
 
@@ -20,8 +23,8 @@ class JS2::FileHandler
20
23
  end
21
24
 
22
25
  def get_yml_files
23
- return [] unless @haml_dir
24
- return Dir.glob(@haml_dir + '/**/*/*.js2.yml') + Dir.glob(@haml_dir + '/*.js2.yml')
26
+ return [] unless @yml_dir
27
+ return Dir.glob(@yml_dir + '/**/*/*.js2.yml') + Dir.glob(@yml_dir + '/*.js2.yml')
25
28
  end
26
29
 
27
30
  def get_files
data/lib/js2/js2.js CHANGED
@@ -1,4 +1,6 @@
1
1
  (function (scope) {
2
+ if (scope.JS2) return;
3
+
2
4
  var JS2 = {};
3
5
  scope.JS2 = JS2;
4
6
 
@@ -1,4 +1,6 @@
1
1
  (function (scope) {
2
+ if (scope.JS2) return;
3
+
2
4
  var JS2 = {};
3
5
  scope.JS2 = JS2;
4
6
 
data/lib/js2/parser.rb CHANGED
@@ -1,11 +1,9 @@
1
-
2
1
  #line 1 "tokenizer.rl"
3
2
  # Somewhat based on http://www.mozilla.org/js/language/js20-2000-07/formal/lexer-grammar.html
4
3
  # Regular Expression Literals determined with these rules:
5
4
  # http://www.mozilla.org/js/language/js20-1999-03-25/tokens.html
6
5
 
7
-
8
- #line 414 "tokenizer.rl"
6
+ #line 414 "tokenizer.rl"
9
7
 
10
8
 
11
9
  require 'rubygems'
@@ -110,7 +108,7 @@ class JS2::Parser
110
108
 
111
109
 
112
110
 
113
- #line 114 "tokenizer.c"
111
+ #line 112 "tokenizer.c"
114
112
  static const unsigned char _dude_actions[] = {
115
113
  0, 1, 1, 1, 2, 1, 3, 1,
116
114
  4, 1, 5, 1, 6, 1, 7, 1,
@@ -2469,20 +2467,18 @@ static const int dude_error = -1;
2469
2467
 
2470
2468
  static const int dude_en_main = 452;
2471
2469
 
2472
-
2473
2470
  #line 518 "tokenizer.rl"
2474
2471
 
2475
- #line 2476 "tokenizer.c"
2472
+ #line 2473 "tokenizer.c"
2476
2473
  {
2477
2474
  cs = dude_start;
2478
2475
  ts = 0;
2479
2476
  te = 0;
2480
2477
  act = 0;
2481
2478
  }
2482
-
2483
2479
  #line 519 "tokenizer.rl"
2484
2480
 
2485
- #line 2486 "tokenizer.c"
2481
+ #line 2482 "tokenizer.c"
2486
2482
  {
2487
2483
  int _klen;
2488
2484
  unsigned int _trans;
@@ -2501,7 +2497,7 @@ _resume:
2501
2497
  #line 1 "tokenizer.rl"
2502
2498
  {ts = p;}
2503
2499
  break;
2504
- #line 2505 "tokenizer.c"
2500
+ #line 2501 "tokenizer.c"
2505
2501
  }
2506
2502
  }
2507
2503
 
@@ -3467,7 +3463,7 @@ _eof_trans:
3467
3463
  }
3468
3464
  }
3469
3465
  break;
3470
- #line 3471 "tokenizer.c"
3466
+ #line 3467 "tokenizer.c"
3471
3467
  }
3472
3468
  }
3473
3469
 
@@ -3480,7 +3476,7 @@ _again:
3480
3476
  #line 1 "tokenizer.rl"
3481
3477
  {ts = 0;}
3482
3478
  break;
3483
- #line 3484 "tokenizer.c"
3479
+ #line 3480 "tokenizer.c"
3484
3480
  }
3485
3481
  }
3486
3482
 
@@ -3496,7 +3492,6 @@ _again:
3496
3492
  }
3497
3493
 
3498
3494
  }
3499
-
3500
3495
  #line 520 "tokenizer.rl"
3501
3496
 
3502
3497
  if (curly_idx) curly_idx--;
data/lib/js2/replace.rb CHANGED
@@ -99,8 +99,8 @@ module JS2
99
99
  end
100
100
 
101
101
  replacer = Replacer.new
102
- template = ERB.new(File.read('tokenizer.rl.erb'), 0, "%<>")
102
+ template = ERB.new(File.read('./tokenizer.rl.erb'), 0, "%<>")
103
103
 
104
- File.open('tokenizer.rl', 'w') do |f|
104
+ File.open('./tokenizer.rl', 'w') do |f|
105
105
  f << template.result(binding)
106
106
  end
@@ -0,0 +1,119 @@
1
+ begin
2
+ require 'rubygems'
3
+ gem "selenium-client", ">=1.2.16"
4
+ require "selenium/client"
5
+ require "yaml"
6
+ require "json"
7
+
8
+
9
+ class JS2::Test::Selenium < Selenium::Client::Driver
10
+ attr_accessor :reference_dir, :child_selector
11
+
12
+ RESET_SEL_MARKER = "if (window.JS2) { window.USE_SEL_MARKER = window.JS2.SEL_MARKER; }"
13
+
14
+ class << self
15
+
16
+ def logger
17
+ return @logger || nil
18
+ end
19
+
20
+ def logger= (a_logger)
21
+ @logger = a_logger
22
+ end
23
+
24
+ def connect (config_file, env = nil)
25
+ config = YAML.load_file(config_file)
26
+ config = config[env] if env
27
+
28
+ reference_dir = config['reference_dir'] || './spec/js2refs'
29
+ config = config['selenium']
30
+ ret = self.new( :host => config['host'] || 'localhost',
31
+ :port => config['port'] || 4444,
32
+ :browser => config['browser'] || '*firefox',
33
+ :url => config['url'] || 'http://www.factual.com',
34
+
35
+ :timeout_in_second => config[:timeout] || 60,
36
+ :highlight_located_element => config['highlight'] || false,
37
+ :javascript_framework => config['framework'] || 'jquery' )
38
+
39
+ # hack to get an instance var in.
40
+ ret.reference_dir = reference_dir
41
+ ret.child_selector = nil
42
+ return ret
43
+ end
44
+ end
45
+
46
+ def get_sel_markers ()
47
+ json = self.execute("JS2.SEL_MARKER.toJson()")
48
+ struct = JSON.parse(json)
49
+ puts YAML::dump(struct)
50
+ end
51
+
52
+ def open!(uri)
53
+ ret = self.open(uri)
54
+ self.wait_for_page
55
+ self.set_sel_marker!
56
+ return ret
57
+ end
58
+
59
+ def execute (js)
60
+ puts js
61
+ return self.js_eval("window.eval(#{js.to_json});")
62
+ end
63
+
64
+ def wait_for_html(html, timeout=15000)
65
+ js = %{window.document.body.innerHTML.toLowerCase().replace(/[\"\']/g, '').indexOf(#{html.to_json.downcase}) >= 0;}
66
+ begin
67
+ self.wait_for_condition(js, timeout)
68
+ return true
69
+ rescue Selenium::CommandError
70
+ return false
71
+ end
72
+ end
73
+
74
+ def uri
75
+ return self.location.sub(%r|^https?://(.*)?/|, '/')
76
+ end
77
+
78
+ def get_helper (klass_name)
79
+ klass = klass_name
80
+ ref_file = %|#{@reference_dir}/#{klass_name}.yml|
81
+ lookup = if File.exist? ref_file
82
+ YAML.load_file(ref_file)
83
+ else
84
+ Hash.new
85
+ end
86
+
87
+ return JS2::Test::SeleniumHelper.new(klass_name, lookup, self)
88
+ end
89
+
90
+ def child_scope (selector)
91
+ js = "if (window.JS2) { window.USE_SEL_MARKER = window.JS2.SEL_MARKER."
92
+ js << selector.split('>').collect { |s| "children.#{s}" }.join('.')
93
+ js << '};'
94
+ @keep_selector = js
95
+ self.set_sel_marker!
96
+ yield()
97
+ @keep_selector = nil
98
+ self.set_sel_marker!
99
+ end
100
+
101
+ def set_sel_marker!
102
+ self.execute(@keep_selector || RESET_SEL_MARKER)
103
+ end
104
+
105
+ def scope(klass_name)
106
+ self.set_sel_marker!
107
+ helper = get_helper(klass_name)
108
+ if block_given?
109
+ yield(helper)
110
+ else
111
+ return helper
112
+ end
113
+ end
114
+
115
+ end
116
+
117
+ rescue Exception => e
118
+ warn "No support for selenium"
119
+ end
@@ -0,0 +1,234 @@
1
+ class JS2::Test::SeleniumElement
2
+ attr_accessor :options
3
+ QUICK_WAIT_FOR = 5
4
+ AJAX_TIME_OUT = 60
5
+ def initialize (sel, klass, key, selector = nil)
6
+ @sel = sel
7
+ @key = key
8
+ @klass = klass
9
+ @selector = selector
10
+ end
11
+
12
+ def log (str)
13
+ if JS2::Test::Selenium.logger
14
+ JS2::Test::Selenium.logger.info(str)
15
+ end
16
+ end
17
+
18
+ def raw
19
+ ret = self.class.new(@sel, @klass, @key, @selector)
20
+ ret.options[:raw] = true
21
+ return ret
22
+ end
23
+
24
+ def check
25
+ return execute('checked=true')
26
+ end
27
+
28
+ def uncheck
29
+ return execute('checked=false')
30
+ end
31
+
32
+ def checked?
33
+ return execute('checked')
34
+ end
35
+
36
+ def execute (str)
37
+ wait_for_ajax
38
+ return @sel.execute(get_js_locator() + '.' + str)
39
+ end
40
+
41
+ def visible?(wait_for = nil)
42
+ return self.check_attribute(':visible', true, wait_for);
43
+ end
44
+
45
+ def sel_visible?()
46
+ return @sel.visible?(get_ele())
47
+ end
48
+
49
+ def hidden?(wait_for = nil)
50
+ return self.check_attribute(':visible', false, wait_for);
51
+ end
52
+
53
+ def find (str, idx = 0)
54
+ selector = "window.$(#{get_js_locator()}).find(#{str.to_json})[#{idx}]"
55
+ return self.class.new(@sel, @klass, @key, selector)
56
+ end
57
+
58
+ def filter (str, idx = 0)
59
+ selector = "window.$(#{get_js_locator()}).filter(#{str.to_json})[#{idx}]"
60
+ return self.class.new(@sel, @klass, @key, selector)
61
+ end
62
+
63
+ def get (idx)
64
+ # when jqObjects in //@+
65
+ selector = "#{get_js_locator()}[#{idx}][0]"
66
+ return self.class.new(@sel, @klass, @key, selector)
67
+ end
68
+
69
+ def [] (idx)
70
+ selector = "#{get_js_locator()}[#{idx}]"
71
+ return self.class.new(@sel, @klass, @key, selector)
72
+ end
73
+
74
+ def attr (attr)
75
+ get_ele()
76
+ js = %{window.$(#{get_js_locator()}).attr(#{attr.to_json});}
77
+ return @sel.js_eval(js)
78
+ end
79
+
80
+ def jq_attr (attr)
81
+ return @sel.execute("window.$(#{get_js_locator()}).#{attr};")
82
+ end
83
+
84
+ def check_attribute (attr, val, wait_for = nil)
85
+ wait_for ||= QUICK_WAIT_FOR
86
+ get_ele()
87
+ js = %{window.$(#{get_js_locator()}).is('#{attr}') == #{val.to_json};}
88
+ begin
89
+ log "Waiting for #{@key}.#{attr} to be #{val.to_json}... Waiting #{wait_for} secs."
90
+ @sel.wait_for_condition(js, wait_for)
91
+ rescue Selenium::CommandError
92
+ return false
93
+ end
94
+
95
+ return true
96
+ end
97
+
98
+ def containsp? (str, timeout=QUICK_WAIT_FOR)
99
+ wait_for_ajax
100
+ js = %{window.$(#{get_js_locator()}).html().toLowerCase().replace(/[\"\']/g, '').indexOf(#{str.to_json.downcase}) >= 0;}
101
+ begin
102
+ @sel.wait_for_condition(js, timeout)
103
+ return true
104
+ rescue Selenium::CommandError
105
+ return false
106
+ end
107
+ end
108
+
109
+ def contains? (str,timeout=QUICK_WAIT_FOR)
110
+ wait_for_ajax
111
+ js = %{window.$(#{get_js_locator()}).html().indexOf(#{str.to_json}) >= 0;}
112
+ begin
113
+ @sel.wait_for_condition(js, timeout)
114
+ return true
115
+ rescue Selenium::CommandError
116
+ return false
117
+ end
118
+ end
119
+
120
+ def click (options = {})
121
+ @sel.click(get_ele(), options)
122
+ end
123
+
124
+ def text
125
+ return @sel.text(get_ele())
126
+ end
127
+
128
+ def get_value
129
+ return @sel.get_value(get_ele())
130
+ end
131
+
132
+ def click! (options = {})
133
+ @sel.click(get_ele(), options)
134
+ @sel.wait_for_page
135
+ end
136
+
137
+ def mouse_up ()
138
+ trigger("LEFT_MOUSE_UP")
139
+ end
140
+
141
+ def mouse_down ()
142
+ trigger("LEFT_MOUSE_DOWN")
143
+ end
144
+
145
+ def mouse_over
146
+ @sel.mouse_over(get_ele())
147
+ end
148
+
149
+ def mouse_out
150
+ @sel.mouse_out(get_ele())
151
+ end
152
+
153
+ def key_down(value)
154
+ @sel.key_down(get_ele(), value)
155
+ end
156
+
157
+ def type (*params)
158
+ elem = get_ele()
159
+ @sel.type(elem, *params)
160
+ @sel.fire_event(elem, 'blur')
161
+ end
162
+
163
+ def select(params)
164
+ elem = get_ele()
165
+ @sel.select(elem, params)
166
+ @sel.fire_event(elem, 'blur')
167
+ end
168
+
169
+ def html ()
170
+ wait_for_ajax
171
+ js = get_js_locator()
172
+ return @sel.js_eval("#{js}.innerHTML;")
173
+ end
174
+
175
+ private
176
+
177
+ def get_locator
178
+ js = get_js_locator()
179
+ dom_locator = "dom=#{js};"
180
+ return dom_locator
181
+ end
182
+
183
+ def get_ele
184
+ real_locator = get_locator()
185
+ wait_for_ele()
186
+
187
+ return real_locator
188
+ end
189
+
190
+ def get_js_locator
191
+ if @selector
192
+ return @selector
193
+ end
194
+
195
+ filtered_locator = @key.to_s
196
+ int = ''
197
+
198
+ if m = filtered_locator.match(/([^\[\]]+)(\[([^\]]*)\])/)
199
+ log "filtered: #{filtered_locator} #{m.inspect}"
200
+ filtered_locator = m[1]
201
+ int = ', ' + m[3] if m[3]
202
+ end
203
+
204
+ funct = 'getVal'
205
+ get_val = "window.USE_SEL_MARKER.#{funct}('#{@klass}', '#{filtered_locator}'#{int})"
206
+
207
+ return get_val
208
+ end
209
+
210
+ def wait_for_ele ()
211
+ real_locator = get_locator
212
+ puts "waiting for #{real_locator}"
213
+ wait_for_ajax
214
+ @sel.wait_for_condition real_locator, QUICK_WAIT_FOR
215
+ puts "found #{real_locator}"
216
+ end
217
+
218
+ def wait_for_ajax
219
+ @sel.wait_for_condition('selenium.browserbot.getCurrentWindow().jQuery.active == 0', AJAX_TIME_OUT)
220
+ end
221
+
222
+ def trigger (event)
223
+ get_ele()
224
+ @sel.execute("window.$(#{get_js_locator}).trigger(JS2.SEL_EVENTS.#{event})")
225
+ end
226
+
227
+ def method_missing (method, *arg)
228
+ if @sel.respond_to?(method)
229
+ return @sel.send(method, get_js_locator, *arg)
230
+ else
231
+ raise "Method missing: #{method}"
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,27 @@
1
+ class JS2::Test::SeleniumHelper
2
+ attr_accessor :klass, :lookup
3
+
4
+ def initialize (klass, lookup, sel)
5
+ @klass = klass
6
+ @lookup = lookup
7
+ @sel = sel
8
+ @all_eles = Hash.new
9
+ end
10
+
11
+ def [] (key, tail = nil)
12
+ key = key.to_s
13
+
14
+ return @all_eles[key] if @all_eles[key]
15
+
16
+ # TODO: support inheritence
17
+ #raise "invalid key #{key}" unless @lookup[key]
18
+
19
+ return @all_eles[key] = JS2::Test::SeleniumElement.new(@sel, @klass, key, tail)
20
+ end
21
+
22
+ def type_form (params = {})
23
+ params.each_pair do |k,v|
24
+ self[k].type(v)
25
+ end
26
+ end
27
+ end
data/lib/js2/tree.rb CHANGED
@@ -105,12 +105,23 @@ class JS2::Class < JS2::Node
105
105
  if @extends
106
106
  extends = "#{@name}.oo('extends', #{@extends});"
107
107
  end
108
+
108
109
 
109
- return %|JS2.OO.#{createName}("#{@name}"); #{extends} (function (K) {var self=K; var _super=JS2.OO['super']; #{@start}|
110
+ return %|JS2.OO.#{createName}("#{@name}"); #{extends} (function (K,Package) {var self=K; var _super=JS2.OO['super']; #{@start}|
110
111
  end
111
112
 
112
113
  def last_string (s)
113
- return s.to_s + ")(#{@name});"
114
+ pkg = @name.split(/\./)
115
+ pkg.pop()
116
+
117
+ if pkg.empty?
118
+ pkg = 'null'
119
+ else
120
+ pkg = pkg.join('.')
121
+ end
122
+
123
+ #pkg = pkg.length > 0 ? pkg : 'null'
124
+ return s.to_s + ")(#{@name}, #{pkg});"
114
125
  end
115
126
 
116
127
  def to_s
@@ -323,7 +334,7 @@ class JS2::ParserHelper
323
334
  @classes.push(new_node)
324
335
  end
325
336
 
326
- @stack.last.set_child(new_node)
337
+ @stack.last.set_child(new_node) if @stack.last
327
338
  @stack.push << new_node
328
339
  end
329
340
 
data/lib/js2/universe.rb CHANGED
@@ -66,8 +66,7 @@ class JS2::Universe
66
66
 
67
67
  def add_yml (yml, filename)
68
68
  yml.each_pair do |klass_name, config|
69
- template = config['template']
70
- next unless template
69
+ template = config['template'] || []
71
70
 
72
71
  trees = @tree_lookup[klass_name]
73
72
  filename = trees.first.filename
@@ -79,11 +78,34 @@ class JS2::Universe
79
78
  end
80
79
 
81
80
  if config['make_compilation']
82
- compilation = [ filename ]
81
+ compilation = []
82
+
83
+ if config['require']
84
+ compilation += config['require'].collect do |name|
85
+ # if class name
86
+ if @tree_lookup[name]
87
+ @tree_lookup[name].collect { |t| t.filename }
88
+
89
+ # assume its just a file name
90
+ else
91
+ [ @file_handler.write_dir + '/' + name ]
92
+ end
93
+ end.flatten
94
+ end
83
95
 
84
- if config['include']
85
- compilation += config['include'].collect { |name| @tree_lookup[name].collect { |t| t.filename } }.flatten
96
+ compilation << filename
86
97
 
98
+ if config['include']
99
+ compilation += config['include'].collect do |name|
100
+ # if class name
101
+ if @tree_lookup[name]
102
+ @tree_lookup[name].collect { |t| t.filename }
103
+
104
+ # assume its just a file name
105
+ else
106
+ [ @file_handler.write_dir + '/' + name ]
107
+ end
108
+ end.flatten
87
109
  end
88
110
 
89
111
  template.each do |t|
data/lib/js2.rb CHANGED
@@ -3,7 +3,9 @@ $:.unshift(File.dirname(__FILE__)) unless
3
3
 
4
4
 
5
5
  module JS2
6
- VERSION = '0.0.9'
6
+ VERSION = '0.0.10'
7
+ module Test
8
+ end
7
9
  end
8
10
 
9
11
  require 'js2/config'
@@ -16,6 +18,10 @@ require 'js2/parser'
16
18
  require 'js2/file_handler'
17
19
  require 'js2/universe'
18
20
 
21
+ require 'js2/test/selenium'
22
+ require 'js2/test/selenium_element'
23
+ require 'js2/test/selenium_helper'
24
+
19
25
  $:.unshift File.dirname(__FILE__)
20
26
 
21
27
  begin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: js2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Su
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-29 00:00:00 +08:00
12
+ date: 2010-02-19 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -86,6 +86,9 @@ files:
86
86
  - lib/js2/tokenizer.rl.erb
87
87
  - lib/js2/tree.rb
88
88
  - lib/js2/universe.rb
89
+ - lib/js2/test/selenium.rb
90
+ - lib/js2/test/selenium_element.rb
91
+ - lib/js2/test/selenium_helper.rb
89
92
  - bin/js2
90
93
  - website/index.txt
91
94
  has_rdoc: true