qlive 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in qlive.gemspec
4
3
  gemspec
@@ -12,10 +12,12 @@ module Qlive
12
12
 
13
13
 
14
14
  def self.reload_main
15
+ Registry.reset_all
15
16
  load "#{File.expand_path('../rack.rb', __FILE__)}"
16
17
  load "#{File.expand_path('../qunit_assets.rb', __FILE__)}"
17
18
  load "#{File.expand_path('../suite.rb', __FILE__)}"
18
19
  load "#{File.expand_path('../registry.rb', __FILE__)}"
20
+ Registry.find_suites
19
21
  end
20
22
  end
21
23
  end
@@ -5,9 +5,9 @@ module Qlive
5
5
  def prepare_assets
6
6
  before_body_close.concat(
7
7
  qunit_html_structure |
8
- qunit_support_assets |
9
8
  qunit_framework |
10
9
  qunit_disable_autostart |
10
+ qunit_support_assets |
11
11
  qunit_javascript_test_sources |
12
12
  qunit_finalize
13
13
  )
@@ -21,19 +21,11 @@ module Qlive
21
21
  end
22
22
 
23
23
  def qunit_support_assets
24
- support_relpath = Qlive.setup[:js_support_relpath]
25
- path = "#{Qlive.setup[:base_path]}#{support_relpath}"
26
- if (File.exist?(path))
27
- glob_script_tags(path, "#{Qlive.setup[:url_prefix] || ''}#{support_relpath}")
28
- else
29
- []
30
- end
24
+ glob_script_tags("#{sans_slash(base_path)}#{Qlive.setup[:js_support_relpath]}")
31
25
  end
32
26
 
33
27
  def qunit_javascript_test_sources
34
- test_path = File.expand_path('..', self.meta_data[:path])
35
- url_prefix = "#{Qlive.setup[:url_prefix] || ''}/#{suite_name}"
36
- glob_script_tags(test_path, url_prefix)
28
+ glob_script_tags(File.expand_path('..', self.registration.path))
37
29
  end
38
30
 
39
31
  def qunit_html_structure
@@ -45,7 +37,6 @@ module Qlive
45
37
  '<h2 id="qunit-userAgent"></h2>',
46
38
  '<ol id="qunit-tests"></ol>',
47
39
  '<div id="qunit-fixture">test markup, will be hidden</div>',
48
- '<div id="display-proxified-tests"></div>',
49
40
  '</div>'
50
41
  ]
51
42
  end
@@ -57,19 +48,48 @@ module Qlive
57
48
  end
58
49
 
59
50
  def qunit_finalize
60
- [
61
- '<script>QUnit.done = function(failed, passed, total, runtime) { window.qunitComplete = true; };</script>'
62
- ]
51
+ js=<<EOJS
52
+ <script>
53
+ window.endQlive = function() {
54
+ if (!$('#qlive-complete').length) {
55
+ $('body').append('<div id="qlive-complete"></div>');
56
+ }
57
+ };
58
+ QUnit.done = function(failed, passed, total, runtime) {
59
+ window.endQlive();
60
+ };
61
+ </script>
62
+ EOJS
63
+ [ js ]
63
64
  end
64
65
 
65
- def glob_script_tags(src_base_path, url_prefix)
66
- sources = Dir.glob("#{src_base_path}#{src_base_path.end_with?('/') ? '' : '/'}**/*.js").sort.flatten
66
+ def glob_script_tags(src_base_path)
67
+ return [] unless File.exist?(src_base_path)
68
+ sources = Dir.glob("#{src_base_path}#{trailing_slash(src_base_path)}**/*.js").sort.flatten
67
69
  sources.map do |src|
68
70
  src = src.to_s
69
- href = "#{url_prefix}#{src.sub(src_base_path, '')}"
71
+ href = "#{url_prefix}#{src.sub(base_path, '')}"
70
72
  "<script type='text/javascript' src='#{href}'></script>"
71
73
  end
72
74
  end
73
75
 
76
+ private
77
+
78
+ def url_prefix
79
+ @url_prefix ||= sans_slash(Qlive.setup[:url_prefix] || '')
80
+ end
81
+
82
+ def sans_slash(path)
83
+ path.end_with?('/') ? path[0..-1] : path
84
+ end
85
+
86
+ def base_path
87
+ Qlive.setup[:base_path]
88
+ end
89
+
90
+ def trailing_slash(path)
91
+ path.end_with?('/') ? '' : '/'
92
+ end
93
+
74
94
  end
75
95
  end
@@ -22,13 +22,14 @@ module Qlive
22
22
  :request => request,
23
23
  :session => env["rack.session"]
24
24
  })
25
- suite.before_each_request(request)
25
+ suite.before_each_suite(request)
26
26
  end
27
27
  end
28
28
 
29
29
  status, headers, body = @app.call(env)
30
30
 
31
31
  if suite
32
+ suite.before_suite_response(status, headers, body)
32
33
  inject_html(:after_open, :head, suite.html_after_head_open, body, headers)
33
34
  inject_html(:before_close, :head, suite.html_before_head_close, body, headers)
34
35
  inject_html(:after_open, :body, suite.html_after_body_open, body, headers)
@@ -1,62 +1,81 @@
1
+ require 'uri'
1
2
  require 'qlive/setup'
2
3
  require 'qlive/suite'
3
4
 
4
5
  module Qlive
5
6
  module Registry
6
7
 
7
- $qlive_all_suites ||= {}
8
+ $qlive_registrations_by_name ||= {}
9
+ $qlive_registrations_by_class ||= {}
8
10
 
9
- def self.suites
10
- $qlive_all_suites
11
- end
11
+ class Registration
12
+ attr_accessor :name
13
+ attr_accessor :path
14
+ attr_accessor :klass
15
+ attr_accessor :extras
12
16
 
17
+ def initialize(args)
18
+ [ :name, :path, :klass ].each do |var|
19
+ instance_variable_set("@#{var}", args[var])
20
+ end
21
+ end
22
+ end
13
23
 
14
24
  def self.find_suites
15
- suites = {}
16
25
  base_path = Qlive.setup[:base_path]
17
- sources = Dir.glob("#{base_path}#{base_path.end_with?('/') ? '' : '/'}**/*_qlive.rb").sort.flatten
18
- sources.each do |path|
19
- path = path.to_s
26
+ Dir.glob("#{base_path}#{base_path.end_with?('/') ? '' : '/'}**/*qlive.rb").sort.flatten.each do |path|
20
27
  name = self.extract_suite_name_from_path(path)
21
- suites[name] ||= {}
22
- suites[name][:path] = path
28
+ unless all_by_name[name]
29
+ all_by_name[name] = Registration.new(
30
+ :name => name,
31
+ :path => path)
32
+ @qlive_current_suite_name = name
33
+ load(path.to_s)
34
+ @qlive_current_suite_name = nil
35
+ end
23
36
  end
24
-
25
- $qlive_all_suites = suites
37
+ all_by_name
26
38
  end
27
39
 
28
40
  def self.build_suite(suite_name)
29
- meta = Registry.suites[suite_name]
30
- unless meta || Qlive.setup[:skip_suite_reloader]
41
+ suite_name = URI.unescape(suite_name)
42
+ registration = Registry.all_by_name[suite_name]
43
+ unless registration || Qlive.setup[:skip_suite_reloader]
31
44
  Registry.find_suites
32
- meta = Registry.suites[suite_name]
45
+ registration = Registry.all_by_name[suite_name]
33
46
  end
34
- raise "Qlive Suite not found: #{suite_name}" unless meta
35
- load meta[:path]
36
- klass = meta[:klass]
47
+ raise "Qlive Suite not found: #{suite_name}" unless registration
48
+ load registration.path
49
+ klass = registration.klass
37
50
  raise "Qlive could not find class for suite: #{suite_name}" unless klass
38
51
  klass.new
39
52
  end
40
53
 
41
54
  def self.register_class(klass)
42
- name = self.extract_suite_name_from_class(klass)
43
- meta = Registry.suites[name] || {}
44
- meta.merge!(:name => name,
45
- :klass => klass)
46
- meta
55
+ registration = $qlive_registrations_by_class[klass]
56
+ registration ||= Registry.all_by_name[@qlive_current_suite_name]
57
+ if registration
58
+ registration.klass = klass
59
+ $qlive_registrations_by_class[klass] = registration
60
+ else
61
+ Qlive.logger.warn "Ignoring Qlive class '#{klass}'. File must be placed within the Qlive base_path: #{Qlive.setup[:base_path]}. Or you can change the base_path with Qlive.setup[:base_path] = /some/other/path"
62
+ end
63
+ registration
47
64
  end
48
65
 
49
- private
66
+ def self.reset_all
67
+ $qlive_registrations_by_name = {}
68
+ $qlive_registrations_by_class = {}
69
+ end
50
70
 
51
- def self.extract_suite_name_from_path(path)
52
- res = path.sub(Qlive.setup[:base_path], '').sub(/^\//, '')
53
- res.split('/')[0..-2].join('/')
71
+ def self.all_by_name
72
+ $qlive_registrations_by_name
54
73
  end
55
74
 
56
- def self.extract_suite_name_from_class(klass)
57
- parts = klass.name.split('::')
58
- parts = parts.map { |part| part.gsub(/(.)([A-Z])/,'\1_\2').downcase }
59
- parts.join('/').sub(/_qlive$/, '')
75
+ private
76
+
77
+ def self.extract_suite_name_from_path(path)
78
+ path.sub(Qlive.setup[:base_path], '').sub(/_?qlive\.rb$/, '').sub(/^\//, '').sub(/\/$/, '')
60
79
  end
61
80
 
62
81
  end
@@ -12,7 +12,15 @@ module Qlive
12
12
  @qlive_config
13
13
  end
14
14
 
15
+ class DefaultLogger
16
+ %w( debug info warn error).each do |level|
17
+ define_method(level) do |raw|
18
+ $stdout.write("#{level.upcase}: #{raw.to_s}\n")
19
+ end
20
+ end
21
+ end
22
+
15
23
  def self.logger
16
- self.setup[:logger]
24
+ self.setup[:logger] ||= DefaultLogger.new
17
25
  end
18
26
  end
@@ -10,13 +10,13 @@ module Qlive
10
10
  InsertionPoints ||= [ 'after_head_open', 'before_head_close', 'after_body_open', 'before_body_close']
11
11
 
12
12
  def self.included(base)
13
- meta = Registry.register_class(base)
13
+ registration = Registry.register_class(base)
14
14
  base.class_eval do
15
15
  class << self
16
- attr_reader :suite_meta_data
16
+ attr_reader :suite_registration
17
17
  end
18
18
  end
19
- base.instance_variable_set(:@suite_meta_data, meta)
19
+ base.instance_variable_set(:@suite_registration, registration)
20
20
 
21
21
  InsertionPoints.each do |place|
22
22
  attr_accessor place
@@ -42,25 +42,26 @@ module Qlive
42
42
  prepare_assets
43
43
  end
44
44
 
45
-
46
- def name
47
- self.meta_data[:name]
48
- end
49
-
50
- def meta_data
51
- self.class.suite_meta_data
45
+ def registration
46
+ self.class.suite_registration
52
47
  end
53
48
 
54
-
55
49
  def suite_name
56
- self.name
50
+ self.registration.name
57
51
  end
58
52
 
53
+ def before_each_suite(rack_request)
54
+ # override in suite
55
+ end
59
56
 
60
- protected
57
+ def before_suite_response(status, headers, body)
58
+ # override in suite
59
+ end
61
60
 
61
+ # DEPRECATED
62
62
  def before_each_request(rack_request)
63
- # override to create server-side fixtures here for the qlive request
63
+ Qlive.logger.warn("Qlive suite '#{suite_name}' uses deprecated 'before_each_request' method. Rename it to 'before_each_suite'.")
64
+ before_each_suite(rack_request)
64
65
  end
65
66
 
66
67
  end
@@ -1,3 +1,3 @@
1
1
  module Qlive
2
- VERSION = "0.2.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -19,5 +19,5 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  s.add_dependency 'rack', '~> 1.4'
22
- s.add_development_dependency "rspec", '~> 2.8.0'
22
+ s.add_development_dependency "rspec", '~> 2.11'
23
23
  end
@@ -0,0 +1,11 @@
1
+ module FancyWorkflow
2
+ class AsAdmin
3
+ include Qlive::Suite
4
+ # would normally include QliveHelper
5
+
6
+ def before_each_suite(rack_request)
7
+ # would login_as Factory(:admin)
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module FancyWorkflow
2
+ class AsUser
3
+ include Qlive::Suite
4
+ # would normally include QliveHelper
5
+
6
+ def before_each_suite(rack_request)
7
+ # would login_as Factory(:user)
8
+ end
9
+
10
+ end
11
+ end
@@ -2,7 +2,7 @@ module Regressions
2
2
  class StayUnbrokenQlive
3
3
  include Qlive::Suite
4
4
 
5
- def before_each_request(rack_request)
5
+ def before_each_suite(rack_request)
6
6
  # fixtures that reproduce the original bug
7
7
  end
8
8
 
@@ -1,20 +1,21 @@
1
1
  require File.expand_path("../../spec_helper.rb", __FILE__)
2
2
 
3
- describe Qlive::Rack do
4
- class HappyGoLuckyQlive
5
- include Qlive::Suite
3
+ Registry = Qlive::Registry
6
4
 
7
- def before_each_request(rack_request)
8
- rack_request.session[:logged_in_as] = 1255
9
- end
10
- end
5
+ describe Qlive::Rack do
11
6
 
12
7
  before(:each) do
13
- suite = HappyGoLuckyQlive.new
14
- Qlive::Registry.stub!(:build_suite).and_return suite
8
+ Registry.find_suites
9
+ suite = FancyWorkflow::AsUser.new
10
+ class << suite
11
+ def before_each_suite(rack_request)
12
+ rack_request.session[:logged_in_as] = 1255
13
+ end
14
+ end
15
+ Registry.stub!(:build_suite).with('fancy_workflow/as_user').and_return(suite)
15
16
  end
16
17
 
17
- let(:environment) { Rack::MockRequest.env_for('/webapp/tinfoiled?qlive=happy_go_lucky#frontpage') }
18
+ let(:environment) { Rack::MockRequest.env_for('/webapp/tinfoiled?qlive=fancy_workflow/as_user#frontpage') }
18
19
  let(:application) { lambda{|env| [200, {'Content-Type' => 'text/html'}, [ html_page ]]} }
19
20
  let(:middleware) do
20
21
  Qlive::Rack.new(application, { :base_path => fixtures_base_path })
@@ -27,7 +28,7 @@ describe Qlive::Rack do
27
28
 
28
29
  it "should allow suite to modify session data" do
29
30
  middleware.call(environment)
30
- environment['rack.session'].should == {:logged_in_as => 1255} # see before_each_request
31
+ environment['rack.session'].should == {:logged_in_as => 1255} # see before_each_suite
31
32
  end
32
33
 
33
34
  #todo: describe "magic param" do
@@ -1,15 +1,15 @@
1
1
  require File.expand_path("../../spec_helper.rb", __FILE__)
2
2
 
3
3
  describe Qlive::Registry, "find_suites" do
4
- it "should find qlive suites" do
4
+ it "should find qlive suites in the qlive base_path" do
5
5
  suites = Qlive::Registry.find_suites
6
6
  suites.length.should > 0
7
- suites['fancy_workflow'].should_not be_nil
8
7
  end
9
8
 
10
- it "should support subdirectories namespaced by modules" do
9
+ it "should name suites by pathname within the base path, trimming qlive.rb and lead/trail slashes" do
11
10
  suites = Qlive::Registry.find_suites
12
- suites.length.should == 2
11
+ suites['fancy_workflow/as_user'].should_not be_nil
12
+ suites['fancy_workflow/as_admin'].should_not be_nil
13
13
  suites['regressions/stay_unbroken'].should_not be_nil
14
14
  end
15
15
  end
@@ -18,13 +18,14 @@ end
18
18
  describe Qlive::Registry, "build_suite" do
19
19
 
20
20
  it "should instantiate suite and add class to meta data registry" do
21
- suite = Qlive::Registry.build_suite('fancy_workflow')
22
- suite.class.name.should == 'FancyWorkflowQlive'
21
+ suite = Qlive::Registry.build_suite('fancy_workflow/as_user')
22
+ suite.class.name.should == 'FancyWorkflow::AsUser'
23
23
  end
24
24
 
25
- it "should work with namespaced subdirs " do
26
- suite = Qlive::Registry.build_suite('regressions/stay_unbroken')
27
- suite.class.name.should == 'Regressions::StayUnbrokenQlive'
25
+ it "should raise an error when suite is not found" do
26
+ lambda {
27
+ suite = Qlive::Registry.build_suite('stay_unbroken')
28
+ }.should raise_error
28
29
  end
29
30
 
30
31
  end
@@ -1,20 +1,14 @@
1
1
  require File.expand_path("../../spec_helper.rb", __FILE__)
2
2
 
3
- describe Qlive::Suite do
4
- class BlueSuite
5
- include Qlive::Suite
6
-
7
- def before_each_request(rack_request)
8
- @pretend_factory_girl = true
9
- @pretend_devise_user_login = true
10
- end
11
- end
3
+ Registry = ::Qlive::Registry
12
4
 
5
+ describe Qlive::Suite do
13
6
  let(:suite) do
14
- suite = BlueSuite.new
15
- suite.prepare
16
- suite.after_head_open << '<script> doSomethingEarly();</script>'
17
- suite
7
+ Registry.find_suites
8
+ res = Registry.build_suite('fancy_workflow/as_user')
9
+ res.prepare # normally called by rack
10
+ res.after_head_open << '<script> doSomethingEarly();</script>'
11
+ res
18
12
  end
19
13
 
20
14
  it "should provide array of desired html at all insertion points" do
@@ -28,29 +22,25 @@ end
28
22
 
29
23
  describe Qlive::Suite, "qunit source" do
30
24
  before(:each) do
31
- @suite = Qlive::Registry.build_suite('fancy_workflow')
25
+ @suite = Qlive::Registry.build_suite('fancy_workflow/as_user')
32
26
  @suite.prepare
33
27
  end
34
28
 
35
29
  it "should insert qunit resources and all js files in the same directory as the suite" do
36
30
  source_tags = @suite.qunit_javascript_test_sources
37
31
  source_tags.length.should == 2
38
- source_tags.join("\n").should match(/#{Regexp.escape("/qlive/sources/fancy_workflow/post-new-recipe.js")}/)
32
+ source_tags.join("\n").should match(/#{Regexp.escape("/qlive/sources/fancy_workflow/as_user/post-new-recipe.js")}/)
39
33
  end
40
34
 
41
35
  end
42
36
 
43
37
 
44
38
  describe Qlive::Suite, "insertion helper methods" do
45
- class GreenSuite
46
- include Qlive::Suite
47
- end
48
-
49
- let(:suite) { GreenSuite.new }
39
+ let(:registration) { Registry.find_suites; Registry.all_by_name['fancy_workflow/as_user'] }
50
40
 
51
41
  it "should not mess up metacoding too much" do
52
- a = GreenSuite.new
53
- b = GreenSuite.new
42
+ a = registration.klass.new
43
+ b = registration.klass.new
54
44
  a.after_head_open = [ 8 ]
55
45
  b.after_head_open = [ 9 ]
56
46
  a.after_head_open[0].should == 8
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qlive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
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: 2012-08-31 00:00:00.000000000 Z
12
+ date: 2013-03-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
- requirement: &2152316140 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,18 +21,28 @@ dependencies:
21
21
  version: '1.4'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2152316140
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.4'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: rspec
27
- requirement: &2152315360 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ~>
31
36
  - !ruby/object:Gem::Version
32
- version: 2.8.0
37
+ version: '2.11'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *2152315360
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.11'
36
46
  description: run qunit tests against actual back-end server with prepared test fixtures
37
47
  email:
38
48
  - support@proxv.com
@@ -52,11 +62,12 @@ files:
52
62
  - lib/qlive/suite.rb
53
63
  - lib/qlive/version.rb
54
64
  - qlive.gemspec
55
- - spec/fixtures/fancy_workflow/fancy_workflow_qlive.rb
65
+ - spec/fixtures/fancy_workflow/as_admin_qlive.rb
66
+ - spec/fixtures/fancy_workflow/as_user_qlive.rb
56
67
  - spec/fixtures/fancy_workflow/post-new-recipe.js
57
68
  - spec/fixtures/fancy_workflow/verify-creds.js
58
69
  - spec/fixtures/qunit_support/start-qunit.js
59
- - spec/fixtures/regressions/stay_unbroken/stay_unbroken_qlive.rb
70
+ - spec/fixtures/regressions/stay_unbroken/qlive.rb
60
71
  - spec/fixtures/regressions/stay_unbroken/test-never-again.js
61
72
  - spec/qlive/rack_spec.rb
62
73
  - spec/qlive/registry_spec.rb
@@ -83,16 +94,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
94
  version: '0'
84
95
  requirements: []
85
96
  rubyforge_project: qlive
86
- rubygems_version: 1.8.10
97
+ rubygems_version: 1.8.25
87
98
  signing_key:
88
99
  specification_version: 3
89
100
  summary: run qunit tests against actual back-end server with prepared test fixtures
90
101
  test_files:
91
- - spec/fixtures/fancy_workflow/fancy_workflow_qlive.rb
102
+ - spec/fixtures/fancy_workflow/as_admin_qlive.rb
103
+ - spec/fixtures/fancy_workflow/as_user_qlive.rb
92
104
  - spec/fixtures/fancy_workflow/post-new-recipe.js
93
105
  - spec/fixtures/fancy_workflow/verify-creds.js
94
106
  - spec/fixtures/qunit_support/start-qunit.js
95
- - spec/fixtures/regressions/stay_unbroken/stay_unbroken_qlive.rb
107
+ - spec/fixtures/regressions/stay_unbroken/qlive.rb
96
108
  - spec/fixtures/regressions/stay_unbroken/test-never-again.js
97
109
  - spec/qlive/rack_spec.rb
98
110
  - spec/qlive/registry_spec.rb
@@ -1,9 +0,0 @@
1
- class FancyWorkflowQlive
2
- include Qlive::Suite
3
- # include QliveHelper
4
-
5
- def before_each_request(rack_request)
6
- # login_as Factory(:user)
7
- end
8
-
9
- end