eetee 0.0.1
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/.gitignore +6 -0
- data/.travis.yml +5 -0
- data/Gemfile +14 -0
- data/Guardfile +8 -0
- data/LICENSE +22 -0
- data/README.md +101 -0
- data/Rakefile +27 -0
- data/eetee.gemspec +19 -0
- data/examples/extensions/extension.rb +17 -0
- data/examples/extensions/test.rb +13 -0
- data/examples/focus/focus.rb +38 -0
- data/examples/shared/shared.rb +34 -0
- data/examples/simple/simple.rb +36 -0
- data/lib/eetee/assertion_wrapper.rb +107 -0
- data/lib/eetee/context.rb +67 -0
- data/lib/eetee/errors.rb +17 -0
- data/lib/eetee/ext/mocha.rb +47 -0
- data/lib/eetee/ext/rack.rb +78 -0
- data/lib/eetee/ext/time.rb +25 -0
- data/lib/eetee/reporter.rb +62 -0
- data/lib/eetee/reporters/console.rb +123 -0
- data/lib/eetee/reporters/text.rb +80 -0
- data/lib/eetee/runner.rb +62 -0
- data/lib/eetee/shared.rb +27 -0
- data/lib/eetee/test.rb +40 -0
- data/lib/eetee/version.rb +3 -0
- data/lib/eetee.rb +65 -0
- data/lib/guard/eetee.rb +77 -0
- data/specs/spec_helper.rb +11 -0
- data/specs/unit/assertion_wrapper_spec.rb +134 -0
- data/specs/unit/context_spec.rb +91 -0
- data/specs/unit/shared_spec.rb +35 -0
- data/specs/unit/test_spec.rb +78 -0
- data/tests/multi/file1.rb +28 -0
- data/tests/multi/file2.rb +14 -0
- data/tests/multi/run.rb +10 -0
- data/tests/simple/simple.rb +36 -0
- metadata +104 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
|
2
|
+
# parameters:
|
3
|
+
# output => the formatted to use
|
4
|
+
# backtrace => number of lines, nil = everything
|
5
|
+
guard 'eetee', :output => "BetterOutput", :backtrace => nil do
|
6
|
+
watch(%r{^lib/eetee/(.+)\.rb$}) { |m| "specs/unit/#{m[1]}_spec.rb" }
|
7
|
+
watch(%r{specs/.+\.rb$})
|
8
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Julien Ammous
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
|
2
|
+
# Continuous integration ([](http://travis-ci.org/schmurfy/eetee))
|
3
|
+
|
4
|
+
This gem is tested against these ruby by travis-ci.org:
|
5
|
+
|
6
|
+
- MRI 1.9.3
|
7
|
+
- rubinius (1.9 mode)
|
8
|
+
|
9
|
+
# What is this name ?
|
10
|
+
|
11
|
+
Finding an unused name is getting hard so I finally settled for E.T. because why not ?
|
12
|
+
I did not want to hve a gem with a two letters name so here is eetee !
|
13
|
+
|
14
|
+
# What is this gem ?
|
15
|
+
|
16
|
+
I used the bacon test framework for quite some time now but I have some issues with it which
|
17
|
+
are mostly unfixable without rewriting internals, this is what E.T. is !
|
18
|
+
From the outside the specs should run the same on both but the changed internals allow better
|
19
|
+
integration with guard amongst other things.
|
20
|
+
|
21
|
+
My goals were:
|
22
|
+
- as light as possible (like bacon)
|
23
|
+
- minimal set of helpers, go check rspec if you want more
|
24
|
+
- specs file should be executable as is, there is no "eetee" binary
|
25
|
+
- specs can be grouped without changing anything in them (run all the spec folder)
|
26
|
+
- keep bacon syntax as I am used to it and like it
|
27
|
+
- a set of extensions I used often (but not required by default)
|
28
|
+
|
29
|
+
# Usage
|
30
|
+
|
31
|
+
E.T. is using itself for its tests, you can look at the spec_helper.rb file and its tests,
|
32
|
+
here is a quickstart:
|
33
|
+
|
34
|
+
create a test file (I suppose you are using bundler, if not you should !):
|
35
|
+
```ruby
|
36
|
+
require 'rubygems'
|
37
|
+
require 'bundler/setup'
|
38
|
+
require "eetee"
|
39
|
+
|
40
|
+
include EEtee
|
41
|
+
|
42
|
+
describe 'Tests' do
|
43
|
+
before do
|
44
|
+
@a = 3
|
45
|
+
end
|
46
|
+
|
47
|
+
should 'have access to instance variables' do
|
48
|
+
@a.should == 3
|
49
|
+
end
|
50
|
+
|
51
|
+
should 'wait 1s' do
|
52
|
+
sleep 1
|
53
|
+
1.should == 1
|
54
|
+
end
|
55
|
+
|
56
|
+
should 'works 2' do
|
57
|
+
(40 + 5).should == 45
|
58
|
+
end
|
59
|
+
|
60
|
+
should 'fails' do
|
61
|
+
"toto".should == 4
|
62
|
+
end
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
and to run it:
|
67
|
+
```bash
|
68
|
+
$ ruby test.rb
|
69
|
+
```
|
70
|
+
|
71
|
+
# Available extensions
|
72
|
+
|
73
|
+
## guard
|
74
|
+
The guard is included inside the gem, just look at the Guardfile for the gem for the syntax (unfortunately guard init excepts the guard to live in a separate gem)
|
75
|
+
|
76
|
+
## mocha
|
77
|
+
Allow mocha expectations to be considered as E.T. expectations.
|
78
|
+
|
79
|
+
## rack
|
80
|
+
Boilet plate around rack-test to test rack applications.
|
81
|
+
|
82
|
+
## time
|
83
|
+
Some time helpers:
|
84
|
+
time_block{ ... } => return execution time in milliseconds
|
85
|
+
freeze_time => Time.now will return the same time inside the block
|
86
|
+
|
87
|
+
|
88
|
+
# Setting up development environmeent
|
89
|
+
|
90
|
+
```bash
|
91
|
+
# clone the repository and:
|
92
|
+
$ bundle
|
93
|
+
$ bundle exec guard
|
94
|
+
```
|
95
|
+
|
96
|
+
the tests will run when a file changed, if only want to run all tests once:
|
97
|
+
|
98
|
+
```bash
|
99
|
+
$ bundle exec rake
|
100
|
+
```
|
101
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
|
5
|
+
task :default => :test
|
6
|
+
|
7
|
+
task :test do
|
8
|
+
|
9
|
+
# do not generate coverage report under travis
|
10
|
+
unless ENV['TRAVIS']
|
11
|
+
|
12
|
+
require 'simplecov'
|
13
|
+
SimpleCov.command_name "E.T."
|
14
|
+
SimpleCov.start do
|
15
|
+
add_filter ".*_spec"
|
16
|
+
add_filter "/helpers/"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'eetee'
|
21
|
+
|
22
|
+
runner = EEtee::Runner.new
|
23
|
+
runner.run_pattern('specs/**/*_spec.rb')
|
24
|
+
runner.report_results()
|
25
|
+
|
26
|
+
end
|
27
|
+
|
data/eetee.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/eetee/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Julien Ammous"]
|
6
|
+
gem.email = ["schmurfy@gmail.com"]
|
7
|
+
gem.description = %q{Test framework inspired by Bacon}
|
8
|
+
gem.summary = %q{Another test framework}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.name = "eetee"
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
gem.version = EEtee::VERSION
|
16
|
+
|
17
|
+
|
18
|
+
gem.add_dependency 'term-ansicolor', '~> 1.0.7'
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
module SimpleExtension
|
3
|
+
def run(&block)
|
4
|
+
super{ run_with_changes(&block) }
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
def run_with_changes(&block)
|
9
|
+
Thread.current[:eetee_simple_extension] = [1]
|
10
|
+
# puts "I did something before the test"
|
11
|
+
block.call
|
12
|
+
# puts "and after the test"
|
13
|
+
Thread.current[:eetee_simple_extension] << 2
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require "eetee"
|
5
|
+
|
6
|
+
include EEtee
|
7
|
+
|
8
|
+
EEtee.enable_focus_mode = true
|
9
|
+
|
10
|
+
describe 'Tests' do
|
11
|
+
before do
|
12
|
+
@a = 3
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'have access to instance variables' do
|
16
|
+
@a.should == 3
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'wait 1s' do
|
20
|
+
sleep 1
|
21
|
+
1.should == 1
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'works 2', :focus => true do
|
25
|
+
(40 + 5).should == 45
|
26
|
+
end
|
27
|
+
|
28
|
+
should 'fails' do
|
29
|
+
"toto".should == 4
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'nested context' do
|
33
|
+
should 'also have access to instance variables' do
|
34
|
+
@a.should == 3
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require "eetee"
|
4
|
+
|
5
|
+
include EEtee
|
6
|
+
|
7
|
+
|
8
|
+
shared(:valid_object) do |obj, n|
|
9
|
+
should 'receive correct number' do
|
10
|
+
n.should == 42
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'respond to :to_i' do
|
14
|
+
obj.should.respond_to?(:to_i)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'nested' do
|
18
|
+
should 'have a length higher than 2' do
|
19
|
+
obj.size.should > 2
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe 'Tests' do
|
26
|
+
before do
|
27
|
+
@obj = "string"
|
28
|
+
end
|
29
|
+
|
30
|
+
in_scope do
|
31
|
+
run_shared(:valid_object, @obj, 42)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require "eetee"
|
5
|
+
|
6
|
+
include EEtee
|
7
|
+
|
8
|
+
|
9
|
+
describe 'Tests' do
|
10
|
+
before do
|
11
|
+
@a = 3
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'have access to instance variables' do
|
15
|
+
@a.should == 3
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'wait 1s' do
|
19
|
+
sleep 1
|
20
|
+
1.should == 1
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'works 2' do
|
24
|
+
(40 + 5).should == 45
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'fails' do
|
28
|
+
"toto".should == 4
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'nested context' do
|
32
|
+
should 'also have access to instance variables' do
|
33
|
+
@a.should == 3
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module EEtee
|
2
|
+
|
3
|
+
module Assertions
|
4
|
+
def be_a(klass)
|
5
|
+
object_class = @object.class
|
6
|
+
|
7
|
+
invert_helper(
|
8
|
+
"expected instance of #{klass}, got #{object_class}",
|
9
|
+
"instance of #{klass} not expected"
|
10
|
+
) do
|
11
|
+
object_class.should == klass
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def raise(error_class = RuntimeError)
|
17
|
+
@object.should.be_a ::Proc
|
18
|
+
|
19
|
+
err = nil
|
20
|
+
begin
|
21
|
+
self.call()
|
22
|
+
rescue => ex
|
23
|
+
err = ex
|
24
|
+
end
|
25
|
+
|
26
|
+
invert_helper(
|
27
|
+
"expected to raise #{error_class}, got #{err.class}",
|
28
|
+
"expected not to raise #{error_class}"
|
29
|
+
) do
|
30
|
+
err.class.should == error_class
|
31
|
+
end
|
32
|
+
|
33
|
+
err
|
34
|
+
end
|
35
|
+
|
36
|
+
def close?(target, error_margin)
|
37
|
+
invert_helper(
|
38
|
+
"expected #{target} += #{error_margin}, got #{target}",
|
39
|
+
"expected to be outside of #{target} += #{error_margin}, got #{target}"
|
40
|
+
) do
|
41
|
+
(target-error_margin .. target+error_margin).should.include?(@object)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
class AssertionWrapper < BasicObject
|
48
|
+
|
49
|
+
instance_methods.each do |name|
|
50
|
+
if name =~ /\?|^\W+$/
|
51
|
+
undef_method(name)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
include Assertions
|
56
|
+
|
57
|
+
def initialize(object)
|
58
|
+
@object = object
|
59
|
+
@invert = false
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_missing(name, *args, &block)
|
63
|
+
::EEtee.current_test.reporter.increment_assertions()
|
64
|
+
ret = @object.__send__(name, *args, &block)
|
65
|
+
|
66
|
+
if !!ret == !!@invert
|
67
|
+
if args.empty?
|
68
|
+
msg = "#{@object.inspect}.#{name}() => #{ret}"
|
69
|
+
else
|
70
|
+
msg = "#{@object.inspect}.#{name}(#{args}) => #{ret}"
|
71
|
+
end
|
72
|
+
|
73
|
+
::Kernel.raise AssertionFailed.new("#{@invert ? '[not] ' : ''}#{msg}")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def not
|
78
|
+
@invert = true
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
def be
|
83
|
+
self
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
##
|
88
|
+
# invert result if needed.
|
89
|
+
def invert_helper(message, invert_message)
|
90
|
+
err = nil
|
91
|
+
|
92
|
+
begin
|
93
|
+
ret = yield
|
94
|
+
rescue AssertionFailed => ex
|
95
|
+
err = ex
|
96
|
+
end
|
97
|
+
|
98
|
+
if err || @invert
|
99
|
+
::Kernel.raise AssertionFailed.new(@invert ? invert_message : message)
|
100
|
+
end
|
101
|
+
|
102
|
+
ret
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module EEtee
|
2
|
+
|
3
|
+
module SharedContextMethods
|
4
|
+
def before(&block)
|
5
|
+
instance_eval(&block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def describe(description, &block)
|
9
|
+
vars = {}
|
10
|
+
|
11
|
+
instance_variables.reject{|name| name.to_s.start_with?('@_') }.each do |name|
|
12
|
+
value = instance_variable_get(name)
|
13
|
+
vars[name] = value
|
14
|
+
end
|
15
|
+
|
16
|
+
Context.new(description, @_level + 1, @_reporter, vars, @_focus_mode, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def should(label, opts = {}, &block)
|
20
|
+
it("should #{label}", opts, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def it(label, opts = {}, &block)
|
24
|
+
if !@_focus_mode || opts[:focus]
|
25
|
+
Test.new(label, @_reporter, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Context
|
31
|
+
attr_reader :description, :level
|
32
|
+
|
33
|
+
include SharedContextMethods
|
34
|
+
|
35
|
+
def description; @_description; end
|
36
|
+
def level; @_level; end
|
37
|
+
|
38
|
+
def initialize(description, level, reporter, vars = {}, focus_mode = false, &block)
|
39
|
+
vars.each do |name, value|
|
40
|
+
instance_variable_set(name, value)
|
41
|
+
end
|
42
|
+
|
43
|
+
@_focus_mode = focus_mode
|
44
|
+
|
45
|
+
@_description = description
|
46
|
+
@_level = level
|
47
|
+
@_reporter = reporter
|
48
|
+
@_reporter.around_context(self) do
|
49
|
+
run(&block)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def run(&block)
|
54
|
+
instance_eval(&block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def run_shared(name, *args)
|
58
|
+
Shared.run(name, @_reporter, @_level, *args)
|
59
|
+
end
|
60
|
+
|
61
|
+
def in_scope(&block)
|
62
|
+
instance_eval(&block)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/lib/eetee/errors.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
gem 'mocha', '~> 0.12.0'
|
2
|
+
require 'mocha_standalone'
|
3
|
+
|
4
|
+
#
|
5
|
+
# This extension ensure that mocha expectations are considered
|
6
|
+
# as bacon tests. Amongst other thing it allows to have a test
|
7
|
+
# containing only mocha expectations.
|
8
|
+
class MochaCounterWrapper
|
9
|
+
def initialize(reporter)
|
10
|
+
@reporter = reporter
|
11
|
+
end
|
12
|
+
|
13
|
+
def increment
|
14
|
+
@reporter.increment_assertions()
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
module MochaSpec
|
21
|
+
def self.included(klass)
|
22
|
+
klass.__send__(:include, Mocha::API)
|
23
|
+
end
|
24
|
+
|
25
|
+
def run(&block)
|
26
|
+
super{ run_with_mocha(&block) }
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def run_with_mocha(&block)
|
31
|
+
begin
|
32
|
+
mocha_setup
|
33
|
+
block.call
|
34
|
+
mocha_verify(MochaCounterWrapper.new(@reporter))
|
35
|
+
rescue Mocha::ExpectationError => e
|
36
|
+
raise EEtee::AssertionFailed.new(e.message)
|
37
|
+
# raise EEte::Error.new(:failed, "#{e.message}\n#{e.backtrace[0...10].join("\n")}")
|
38
|
+
ensure
|
39
|
+
mocha_teardown
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
EEtee::Context.__send__(:include, Mocha::API)
|
46
|
+
EEtee::Test.__send__(:include, MochaSpec)
|
47
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
gem 'rack-test', '~> 0.6.2'
|
3
|
+
require 'rack/test'
|
4
|
+
|
5
|
+
module HTTPTest
|
6
|
+
def serve_app(app)
|
7
|
+
@app = Rack::Test::Session.new(
|
8
|
+
Rack::MockSession.new(app)
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
def request(method, url, opts = {})
|
13
|
+
@app.request(url, opts.merge(method: method))
|
14
|
+
@app.last_response
|
15
|
+
end
|
16
|
+
|
17
|
+
def propfind(url, properties = :all, opts = {})
|
18
|
+
namespaces = {
|
19
|
+
'DAV:' => 'D',
|
20
|
+
'urn:ietf:params:xml:ns:carddav' => 'C',
|
21
|
+
'http://calendarserver.org/ns/' => 'APPLE1'
|
22
|
+
}
|
23
|
+
|
24
|
+
if properties == :all
|
25
|
+
body = "<D:allprop />"
|
26
|
+
|
27
|
+
else
|
28
|
+
properties = properties.map do |(name, ns)|
|
29
|
+
ns_short = namespaces[ns]
|
30
|
+
raise "unknown namespace: #{ns}" unless ns_short
|
31
|
+
%.<#{ns_short}:#{name}/>.
|
32
|
+
end
|
33
|
+
|
34
|
+
body = "<D:prop>#{properties.join("\n")}</D:prop>"
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
data = <<-EOS
|
39
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
40
|
+
<D:propfind xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav" xmlns:APPLE1="http://calendarserver.org/ns/">
|
41
|
+
#{body}
|
42
|
+
</D:propfind>
|
43
|
+
EOS
|
44
|
+
|
45
|
+
request('PROPFIND', url, opts.merge(input: data))
|
46
|
+
end
|
47
|
+
|
48
|
+
def ensure_element_exists(response, expr, namespaces = {'D' => 'DAV:'})
|
49
|
+
ret = Nokogiri::XML(response.body)
|
50
|
+
ret.css(expr, namespaces).tap{|elements| elements.should.not.be.empty? }
|
51
|
+
rescue EEtee::AssertionFailed => err
|
52
|
+
raise EEtee::AssertionFailed.new("XML did not match: #{expr}")
|
53
|
+
end
|
54
|
+
|
55
|
+
def ensure_element_does_not_exists(response, expr, namespaces = {})
|
56
|
+
ret = Nokogiri::XML(response.body)
|
57
|
+
ret.css(expr, namespaces).should.be.empty?
|
58
|
+
rescue EEtee::AssertionFailed => err
|
59
|
+
raise EEtee::AssertionFailed.new("XML did match: #{expr}")
|
60
|
+
end
|
61
|
+
|
62
|
+
def element_content(response, expr, namespaces = {})
|
63
|
+
ret = Nokogiri::XML(response.body)
|
64
|
+
elements = ret.css(expr, namespaces)
|
65
|
+
if elements.empty?
|
66
|
+
:missing
|
67
|
+
else
|
68
|
+
children = elements.first.element_children
|
69
|
+
if children.empty?
|
70
|
+
:empty
|
71
|
+
else
|
72
|
+
children.first.text
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
EEtee::Context.__send__(:include, HTTPTest)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module EEteeTimeHelpers
|
2
|
+
def time_block
|
3
|
+
started_at = Time.now
|
4
|
+
yield
|
5
|
+
(Time.now - started_at) * 1000
|
6
|
+
end
|
7
|
+
|
8
|
+
# load the mocha extension first to enable
|
9
|
+
# this.
|
10
|
+
if defined?(MochaCounterWrapper)
|
11
|
+
##
|
12
|
+
# Freeze the time, in this block Time.now
|
13
|
+
# will always return the same value.
|
14
|
+
def freeze_time(t = Time.now)
|
15
|
+
Time.stubs(:now).returns(t)
|
16
|
+
if block_given?
|
17
|
+
yield
|
18
|
+
Time.unstub(:now)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
EEtee::Context.__send__(:include, EEteeTimeHelpers)
|