qlive 0.2.0 → 0.4.0

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.
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