ospec 0.1.15

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.
@@ -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: []