ospec 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ .DS_Store
2
+ doc
3
+ /pkg
4
+ /*.js
5
+ /*.gem
6
+ /build
7
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ gem "opal", :git => 'git://github/opal/opal.git'
2
+ gem "rake"
@@ -0,0 +1,28 @@
1
+ opal-spec
2
+ =========
3
+
4
+ opal-spec is a minimal spec lib for opal, inspired by RSpec and MSpec.
5
+ It is designed to run on [opal](http://opalrb.org), and provides the
6
+ bare minimum to get specs running.
7
+
8
+ Change Log
9
+ ----------
10
+
11
+ ### Edge
12
+
13
+ * BrowserFormatter is now default
14
+
15
+ ### 0.0.3
16
+
17
+ * Allow group names to be non-strings
18
+ * Nested groups now have outer group name as prefix
19
+ * Nested groups should inherit `before` and `after` blocks
20
+
21
+ ### 0.0.2
22
+
23
+ * Added seperate BrowserFormatter class for cleaner output
24
+ * Update Rake tasks to use new Opal::Builder class
25
+
26
+ ### 0.0.1
27
+
28
+ Initial release
@@ -0,0 +1 @@
1
+ require 'opal'
@@ -0,0 +1,10 @@
1
+ require 'opal-spec/example'
2
+ require 'opal-spec/example_group'
3
+ require 'opal-spec/matchers'
4
+ require 'opal-spec/runner'
5
+ require 'opal-spec/scratch_pad'
6
+ require 'opal-spec/expectations'
7
+ require 'opal-spec/browser_formatter'
8
+ require 'opal-spec/phantom_formatter'
9
+ require 'opal-spec/kernel'
10
+ require 'opal-spec/version'
@@ -0,0 +1,183 @@
1
+ module OSpec
2
+ class BrowserFormatter
3
+ CSS = <<-EOS
4
+
5
+ body {
6
+ font-size: 14px;
7
+ font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
8
+ }
9
+
10
+ pre {
11
+ font-family: "Bitstream Vera Sans Mono", Monaco, "Lucida Console", monospace;
12
+ font-size: 12px;
13
+ color: #444444;
14
+ white-space: pre;
15
+ padding: 3px 0px 3px 12px;
16
+ margin: 0px 0px 8px;
17
+
18
+ background: #FAFAFA;
19
+ -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
20
+ -webkit-border-radius: 3px;
21
+ -moz-border-radius: 3px;
22
+ border-radius: 3px;
23
+ border: 1px solid #DDDDDD;
24
+ }
25
+
26
+ ul.example_groups {
27
+ list-style-type: none;
28
+ }
29
+
30
+ li.group.passed .group_description {
31
+ color: #597800;
32
+ font-weight: bold;
33
+ }
34
+
35
+ li.group.failed .group_description {
36
+ color: #FF000E;
37
+ font-weight: bold;
38
+ }
39
+
40
+ li.example.passed {
41
+ color: #597800;
42
+ }
43
+
44
+ li.example.failed {
45
+ color: #FF000E;
46
+ }
47
+
48
+ .examples {
49
+ list-style-type: none;
50
+ }
51
+ EOS
52
+
53
+ def initialize
54
+ @examples = []
55
+ @failed_examples = []
56
+ end
57
+
58
+ def start
59
+ %x{
60
+ if (!document || !document.body) {
61
+ #{ raise "Not running in browser." };
62
+ }
63
+
64
+ var summary_element = document.createElement('p');
65
+ summary_element.className = 'summary';
66
+
67
+ var groups_element = document.createElement('ul');
68
+ groups_element.className = 'example_groups';
69
+
70
+ var target = document.getElementById('opal-spec-output');
71
+
72
+ if (!target) {
73
+ target = document.body;
74
+ }
75
+
76
+ target.appendChild(summary_element);
77
+ target.appendChild(groups_element);
78
+
79
+ var styles = document.createElement('style');
80
+ styles.innerHTML = #{ CSS };
81
+ document.head.appendChild(styles);
82
+ }
83
+
84
+ @start_time = Time.now.to_f
85
+ @groups_element = `groups_element`
86
+ @summary_element = `summary_element`
87
+ end
88
+
89
+ def finish
90
+ time = Time.now.to_f - @start_time
91
+ text = "\n#{example_count} examples, #{@failed_examples.size} failures (time taken: #{time})"
92
+ `#{@summary_element}.innerHTML = text`
93
+ end
94
+
95
+ def example_group_started group
96
+ @example_group = group
97
+ @example_group_failed = false
98
+
99
+ %x{
100
+ var group_element = document.createElement('li');
101
+
102
+ var description = document.createElement('span');
103
+ description.className = 'group_description';
104
+ description.innerHTML = #{group.description};
105
+ group_element.appendChild(description);
106
+
107
+ var example_list = document.createElement('ul');
108
+ example_list.className = 'examples';
109
+ group_element.appendChild(example_list);
110
+
111
+ #@groups_element.appendChild(group_element);
112
+ }
113
+
114
+ @group_element = `group_element`
115
+ @example_list = `example_list`
116
+ end
117
+
118
+ def example_group_finished group
119
+ if @example_group_failed
120
+ `#@group_element.className = 'group failed';`
121
+ else
122
+ `#@group_element.className = 'group passed';`
123
+ end
124
+ end
125
+
126
+ def example_started example
127
+ @examples << example
128
+ @example = example
129
+ end
130
+
131
+ def example_failed example
132
+ @failed_examples << example
133
+ @example_group_failed = true
134
+
135
+ exception = example.exception
136
+
137
+ case exception
138
+ when OSpec::ExpectationNotMetError
139
+ output = exception.message
140
+ else
141
+ output = "#{exception.class}: #{exception.message}\n"
142
+ output += " #{exception.backtrace.join "\n "}\n"
143
+ end
144
+
145
+ %x{
146
+ var wrapper = document.createElement('li');
147
+ wrapper.className = 'example failed';
148
+
149
+ var description = document.createElement('span');
150
+ description.className = 'example_description';
151
+ description.innerHTML = #{example.description};
152
+
153
+ var exception = document.createElement('pre');
154
+ exception.className = 'exception';
155
+ exception.innerHTML = output;
156
+
157
+ wrapper.appendChild(description);
158
+ wrapper.appendChild(exception);
159
+
160
+ #@example_list.appendChild(wrapper);
161
+ #@example_list.style.display = 'list-item';
162
+ }
163
+ end
164
+
165
+ def example_passed example
166
+ %x{
167
+ var wrapper = document.createElement('li');
168
+ wrapper.className = 'example passed';
169
+
170
+ var description = document.createElement('span');
171
+ description.className = 'example_description';
172
+ description.innerHTML = #{example.description};
173
+
174
+ wrapper.appendChild(description);
175
+ #@example_list.appendChild(wrapper);
176
+ }
177
+ end
178
+
179
+ def example_count
180
+ @examples.size
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,45 @@
1
+ module OSpec
2
+ class Example
3
+ attr_reader :description, :example_group, :exception
4
+
5
+ def initialize(group, desc, block)
6
+ @example_group = group
7
+ @description = desc
8
+ @__block__ = block
9
+ end
10
+
11
+ def run_before_hooks
12
+ @example_group.before_hooks.each do |before|
13
+ instance_eval &before
14
+ end
15
+ end
16
+
17
+ def run_after_hooks
18
+ @example_group.after_hooks.each do |after|
19
+ instance_eval &after
20
+ end
21
+ end
22
+
23
+ def run runner
24
+ begin
25
+ runner.example_started self
26
+ run_before_hooks
27
+ instance_eval &@__block__
28
+ rescue => e
29
+ @exception = e
30
+ ensure
31
+ begin
32
+ run_after_hooks
33
+ rescue => e
34
+ @exception = e
35
+ end
36
+ end
37
+
38
+ if @exception
39
+ runner.example_failed self
40
+ else
41
+ runner.example_passed self
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,62 @@
1
+ module OSpec
2
+ class ExampleGroup
3
+ @example_groups = []
4
+ def self.example_groups
5
+ @example_groups
6
+ end
7
+
8
+ @stack = []
9
+ def self.create desc, block
10
+ group = self.new desc, @stack.last
11
+ @example_groups << group
12
+
13
+ @stack << group
14
+ group.instance_eval &block
15
+ @stack.pop
16
+ end
17
+
18
+ def initialize desc, parent
19
+ @desc = desc.to_s
20
+ @parent = parent
21
+ @examples = []
22
+
23
+ @before_hooks = []
24
+ @after_hooks = []
25
+ end
26
+
27
+ def it desc, &block
28
+ @examples << Example.new(self, desc, block)
29
+ end
30
+
31
+ def it_behaves_like(*objs)
32
+ end
33
+
34
+ def before type = :each, &block
35
+ raise "unsupported before type: #{type}" unless type == :each
36
+ @before_hooks << block
37
+ end
38
+
39
+ def after type = :each, &block
40
+ raise "unsupported after type: #{type}" unless type == :each
41
+ @after_hooks << block
42
+ end
43
+
44
+ def before_hooks
45
+ @parent ? [].concat(@parent.before_hooks).concat(@before_hooks) : @before_hooks
46
+ end
47
+
48
+ def after_hooks
49
+ @parent ? [].concat(@parent.after_hooks).concat(@after_hooks) : @after_hooks
50
+ end
51
+
52
+ def run runner
53
+ runner.example_group_started self
54
+ @examples.each { |example| example.run runner }
55
+ runner.example_group_finished self
56
+ end
57
+
58
+ def description
59
+ @parent ? "#{@parent.description} #{@desc}" : @desc
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,49 @@
1
+ module OSpec
2
+ class ExpectationNotMetError < StandardError; end
3
+
4
+ module Expectations
5
+ def should matcher = nil
6
+ if matcher
7
+ matcher.match self
8
+ else
9
+ OSpec::PositiveOperatorMatcher.new self
10
+ end
11
+ end
12
+
13
+ def should_not matcher = nil
14
+ if matcher
15
+ matcher.not_match self
16
+ else
17
+ OSpec::NegativeOperatorMatcher.new self
18
+ end
19
+ end
20
+
21
+ def be_kind_of expected
22
+ OSpec::BeKindOfMatcher.new expected
23
+ end
24
+
25
+ def be_nil
26
+ OSpec::BeNilMatcher.new nil
27
+ end
28
+
29
+ def be_true
30
+ OSpec::BeTrueMatcher.new true
31
+ end
32
+
33
+ def be_false
34
+ OSpec::BeFalseMatcher.new false
35
+ end
36
+
37
+ def equal expected
38
+ OSpec::EqualMatcher.new expected
39
+ end
40
+
41
+ def raise_error expected
42
+ OSpec::RaiseErrorMatcher.new expected
43
+ end
44
+ end
45
+ end
46
+
47
+ class Object
48
+ include OSpec::Expectations
49
+ end
@@ -0,0 +1,9 @@
1
+ module Kernel
2
+ def describe desc, &block
3
+ OSpec::ExampleGroup.create desc, block
4
+ end
5
+
6
+ def mock obj
7
+ Object.new
8
+ end
9
+ end
@@ -0,0 +1,90 @@
1
+ module OSpec
2
+ class Matcher
3
+ def initialize actual
4
+ @actual = actual
5
+ end
6
+
7
+ def failure message
8
+ raise OSpec::ExpectationNotMetError, message
9
+ end
10
+ end
11
+
12
+ class PositiveOperatorMatcher < Matcher
13
+ def == expected
14
+ if @actual == expected
15
+ true
16
+ else
17
+ failure "expected: #{expected.inspect}, got: #{@actual.inspect} (using ==)."
18
+ end
19
+ end
20
+ end
21
+
22
+ class NegativeOperatorMatcher < Matcher
23
+ def == expected
24
+ if @actual == expected
25
+ failure "expected: #{expected.inspect} not to be #{@actual.inspect} (using ==)."
26
+ end
27
+ end
28
+ end
29
+
30
+ class BeKindOfMatcher < Matcher
31
+ def match expected
32
+ unless expected.kind_of? @actual
33
+ failure "expected #{expected.inspect} to be a kind of #{@actual}, not #{expected.class}."
34
+ end
35
+ end
36
+ end
37
+
38
+ class BeNilMatcher < Matcher
39
+ def match expected
40
+ unless expected.nil?
41
+ failure "expected #{expected.inspect} to be nil."
42
+ end
43
+ end
44
+ end
45
+
46
+ class BeTrueMatcher < Matcher
47
+ def match expected
48
+ unless expected == true
49
+ failure "expected #{expected.inspect} to be true."
50
+ end
51
+ end
52
+ end
53
+
54
+ class BeFalseMatcher < Matcher
55
+ def match expected
56
+ unless expected == false
57
+ failure "expected #{expected.inspect} to be false."
58
+ end
59
+ end
60
+ end
61
+
62
+ class EqualMatcher < Matcher
63
+ def match expected
64
+ unless expected.equal? @actual
65
+ failure "expected #{@actual.inspect} to be the same as #{expected.inspect}."
66
+ end
67
+ end
68
+
69
+ def not_match expected
70
+ if expected.equal? @actual
71
+ failure "expected #{@actual.inspect} not to be equal to #{expected.inspect}."
72
+ end
73
+ end
74
+ end
75
+
76
+ class RaiseErrorMatcher < Matcher
77
+ def match block
78
+ should_raise = false
79
+ begin
80
+ block.call
81
+ should_raise = true
82
+ rescue => e
83
+ end
84
+
85
+ if should_raise
86
+ failure "expected #{@actual} to be raised, but nothing was."
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,78 @@
1
+ module OSpec
2
+ class PhantomFormatter
3
+ def initialize
4
+ @examples = []
5
+ @failed_examples = []
6
+ end
7
+
8
+ def log_green(str)
9
+ `console.log('\\033[92m' + str + '\\033[0m')`
10
+ end
11
+
12
+ def log_red(str)
13
+ `console.log('\\033[31m' + str + '\\033[0m')`
14
+ end
15
+
16
+ def log(str)
17
+ `console.log(str)`
18
+ end
19
+
20
+ def start
21
+ end
22
+
23
+ def finish
24
+ if @failed_examples.empty?
25
+ log "\nFinished"
26
+ log_green "#{example_count} examples, 0 failures"
27
+ `phantom.exit(0)`
28
+ else
29
+ log "\nFailures:"
30
+ @failed_examples.each_with_index do |example, idx|
31
+ log "\n #{idx+1}. #{example.example_group.description} #{example.description}"
32
+
33
+ exception = example.exception
34
+ case exception
35
+ when OSpec::ExpectationNotMetError
36
+ output = exception.message
37
+ else
38
+ output = "#{exception.class}: #{exception.message}\n"
39
+ output += " #{exception.backtrace.join "\n "}\n"
40
+ end
41
+ log_red " #{output}"
42
+ end
43
+
44
+ log "\nFinished"
45
+ log_red "#{example_count} examples, #{@failed_examples.size} failures"
46
+ `phantom.exit(1)`
47
+ end
48
+ end
49
+
50
+ def example_group_started group
51
+ @example_group = group
52
+ @example_group_failed = false
53
+ log "\n#{group.description}"
54
+ end
55
+
56
+ def example_group_finished group
57
+ end
58
+
59
+ def example_started example
60
+ @examples << example
61
+ @example = example
62
+ end
63
+
64
+ def example_failed example
65
+ @failed_examples << example
66
+ @example_group_failed = true
67
+ log_red " #{example.description}"
68
+ end
69
+
70
+ def example_passed example
71
+ log_green " #{example.description}"
72
+ end
73
+
74
+ def example_count
75
+ @examples.size
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,70 @@
1
+ module OSpec
2
+ class Runner
3
+ def self.in_browser?
4
+ %x{
5
+ if (typeof(window) !== 'undefined' && typeof(document) !== 'undefined') {
6
+ return true;
7
+ }
8
+
9
+ return false;
10
+ }
11
+ end
12
+
13
+ def self.in_phantom?
14
+ %x{
15
+ if (typeof(phantom) !== 'undefined' && phantom.exit) {
16
+ return true;
17
+ }
18
+
19
+ return false;
20
+ }
21
+ end
22
+
23
+ def self.autorun
24
+ if in_browser?
25
+ %x{
26
+ setTimeout(function() {
27
+ #{ Runner.new.run };
28
+ }, 0);
29
+ }
30
+ else
31
+ Runner.new.run
32
+ end
33
+ end
34
+
35
+ def initialize
36
+ if Runner.in_phantom?
37
+ @formatter = PhantomFormatter.new
38
+ elsif Runner.in_browser?
39
+ @formatter = BrowserFormatter.new
40
+ end
41
+ end
42
+
43
+ def run
44
+ groups = ExampleGroup.example_groups
45
+ @formatter.start
46
+ groups.each { |group| group.run self }
47
+ @formatter.finish
48
+ end
49
+
50
+ def example_group_started group
51
+ @formatter.example_group_started group
52
+ end
53
+
54
+ def example_group_finished group
55
+ @formatter.example_group_finished group
56
+ end
57
+
58
+ def example_started example
59
+ @formatter.example_started example
60
+ end
61
+
62
+ def example_passed example
63
+ @formatter.example_passed example
64
+ end
65
+
66
+ def example_failed example
67
+ @formatter.example_failed example
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,17 @@
1
+ module ScratchPad
2
+ def self.clear
3
+ @record = nil
4
+ end
5
+
6
+ def self.record(arg)
7
+ @record = arg
8
+ end
9
+
10
+ def self.<<(arg)
11
+ @record << arg
12
+ end
13
+
14
+ def self.recorded
15
+ @record
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module OSpec
2
+ VERSION = "0.1.15"
3
+ end
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/ospec/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'ospec'
6
+ s.version = OSpec::VERSION
7
+ s.author = 'Adam Beynon'
8
+ s.email = 'adam@adambeynon.com'
9
+ s.homepage = 'http://opalrb.org'
10
+ s.summary = 'Opal compatible spec'
11
+ s.description = 'Opal compatible spec library'
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.require_paths = ['lib']
15
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ospec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.15
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Beynon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-11 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: Opal compatible spec library
15
+ email: adam@adambeynon.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - .gitignore
21
+ - Gemfile
22
+ - README.md
23
+ - Rakefile
24
+ - lib/ospec.rb
25
+ - lib/ospec/browser_formatter.rb
26
+ - lib/ospec/example.rb
27
+ - lib/ospec/example_group.rb
28
+ - lib/ospec/expectations.rb
29
+ - lib/ospec/kernel.rb
30
+ - lib/ospec/matchers.rb
31
+ - lib/ospec/phantom_formatter.rb
32
+ - lib/ospec/runner.rb
33
+ - lib/ospec/scratch_pad.rb
34
+ - lib/ospec/version.rb
35
+ - ospec.gemspec
36
+ homepage: http://opalrb.org
37
+ licenses: []
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 1.8.11
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: Opal compatible spec
60
+ test_files: []