seaweed 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/seaweed CHANGED
@@ -1,55 +1,28 @@
1
- #!/usr/bin/env jruby
2
- require 'rubygems'
3
- require 'bundler'
4
- require 'celerity'
5
- require 'watchr'
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
6
3
 
7
- require File.expand_path('../../lib/required_files', __FILE__)
8
- require File.expand_path('../../server/server', __FILE__)
9
- require 'net/http'
4
+ require "#{File.dirname(__FILE__)}/../lib/seaweed/runner.rb"
5
+ require 'optparse'
10
6
 
11
- PORT = 4567
12
-
13
- app = Rack::Builder.app do
14
- run Sinatra::Application
15
- end
16
-
17
- mode = case ARGV.first
18
- when 's', 'server'
19
- 'server'
20
- when 't', 'terminal'
21
- 'terminal'
22
- when 'a', 'auto'
23
- 'auto'
24
- else
25
- 'auto'
26
- end
27
-
28
- if mode == 'server'
29
- Rack::Handler.default.run app, :Port => PORT
30
- else
31
- Thread.new do
32
- Rack::Handler.default.run app, :Port => PORT
33
- end
34
-
35
- begin
36
- page = Net::HTTP.get URI.parse("http://localhost:#{PORT}/")
37
- rescue Errno::ECONNREFUSED
38
- sleep 1
39
- retry
7
+ options = {}
8
+ parser = OptionParser.new do |o|
9
+ o.banner = "Usage: #{$0} [options] mode\nPossible modes: server, terminal, auto"
10
+
11
+ options[:port] = nil
12
+ o.on '-p', '--port PORT', 'Override server port' do |port|
13
+ options[:port] = port
14
+ end
15
+
16
+ options[:version] = false
17
+ o.on '-v', '--version', 'Show version' do
18
+ options[:version] = true
40
19
  end
41
-
42
- browser = Celerity::Browser.new
43
- browser.goto "http://localhost:#{PORT}/#terminal"
44
- puts browser.text
45
20
 
46
- if mode == 'auto'
47
- script = Watchr::Script.new
48
- script.watch(/^(lib|spec)\/.*\.coffee$/) do
49
- browser.refresh
50
- puts browser.text
51
- end
52
- controller = Watchr::Controller.new(script, Watchr.handler.new)
53
- controller.run
21
+ o.on_tail '-h', '--help', 'Display this screen' do
22
+ puts o
23
+ exit
54
24
  end
55
- end
25
+ end
26
+ parser.parse!
27
+
28
+ Seaweed::Runner.new ARGV.first, options, parser
@@ -0,0 +1,53 @@
1
+ window.Spec ||= {}
2
+ window.Spec.ObjectExtensions = {
3
+ # Tests for a positive match
4
+ should: (matcher) ->
5
+ result = Spec.findMatcher(matcher)(this)
6
+ Spec.fail "expected #{result[1]}" unless result[0]
7
+
8
+ # Tests for a negative match
9
+ shouldNot: (matcher) ->
10
+ result = Spec.findMatcher(matcher)(this)
11
+ Spec.fail "expected not #{result[1]}" if result[0]
12
+
13
+ # Creates a stub method, with an expectation of no calls
14
+ shouldNotReceive: (name) ->
15
+ @shouldReceive(name).exactly(0).times
16
+
17
+ # Creates a stub method with an expectation
18
+ shouldReceive: (name) ->
19
+ object = this
20
+
21
+ received = expectation "to receive “#{name}”"
22
+
23
+ passthrough = object[name]
24
+ object[name] = -> received.meet()
25
+
26
+ received.with = (expectArgs...) ->
27
+ object[name] = (args...) ->
28
+ received.meet()
29
+ correct = true
30
+ correct = false if expectArgs.length != args.length
31
+ if correct
32
+ for i in [0..args.length]
33
+ correct = false unless String(expectArgs[i]) == String(args[i])
34
+ unless correct
35
+ Spec.fail "expected ##{name} to be called with arguments “#{expectArgs.join ', '}”, actual arguments: “#{args.join ', '}”"
36
+ received
37
+
38
+ received.andReturn = (returnValue) ->
39
+ fn = object[name]
40
+ object[name] = ->
41
+ fn.apply this, arguments
42
+ returnValue
43
+ received
44
+
45
+ received.andPassthrough = ->
46
+ fn = object[name]
47
+ object[name] = ->
48
+ fn.apply this, arguments
49
+ passthrough.apply this, arguments
50
+ received
51
+
52
+ received
53
+ }
@@ -0,0 +1,252 @@
1
+ window.Spec ||= {}
2
+ window.Spec.WindowExtensions = {
3
+ SpecObject: (object) ->
4
+ $.extend this, object if object
5
+ this
6
+
7
+ # Tests if matched value === expected value
8
+ be: (expected) ->
9
+ (value) ->
10
+ [value is expected, "to be #{Spec.inspect expected}, actual #{Spec.inspect value}"]
11
+
12
+ # Tests if matched value is a boolean
13
+ beABoolean: (value) ->
14
+ [typeof value is 'boolean', "to have type “boolean”, actual “#{typeof value}”"]
15
+
16
+ # Tests if matched value is a function
17
+ beAFunction: (value) ->
18
+ [typeof value is 'function', "to have type “function”, actual “#{typeof value}”"]
19
+
20
+ # Tests if matched value is a number
21
+ beANumber: (value) ->
22
+ [typeof value is 'number', "to have type “number”, actual “#{typeof value}”"]
23
+
24
+ # Tests if matched value is a string
25
+ beAString: (value) ->
26
+ [typeof value is 'string', "to have type “string”, actual “#{typeof value}”"]
27
+
28
+ # Tests if matched value is an instance of class
29
+ beAnInstanceOf: (klass) ->
30
+ (value) ->
31
+ [value instanceof klass, "to be an instance of “#{klass}”"]
32
+
33
+ # Tests if matched value is an object
34
+ beAnObject: (value) ->
35
+ [typeof value is 'object', "to have type “object”, actual “#{typeof value}”"]
36
+
37
+ # Tests if given attribute is true
38
+ beAttribute: (attribute) ->
39
+ (value) ->
40
+ result = value[attribute]
41
+ result = result.call value if typeof result is 'function'
42
+ [!!result, "to be #{attribute}"]
43
+
44
+ # Tests if matched value is boolean false
45
+ beFalse: (value) ->
46
+ [String(value) == 'false', "to be false, got #{Spec.inspect value}"]
47
+
48
+ # Adds a setup step to the current test case
49
+ before: (action) ->
50
+ test = Spec.testStack[Spec.testStack.length - 1]
51
+ test.before.push action
52
+
53
+ # Tests if matched value is boolean true
54
+ beTrue: (value) ->
55
+ [String(value) == 'true', "to be true, got #{Spec.inspect value}"]
56
+
57
+ context: () ->
58
+ describe.apply this, arguments
59
+
60
+ # Prepares a sub-test of the current test case
61
+ describe: (title, definition) ->
62
+ parent = Spec.testStack[Spec.testStack.length - 1]
63
+
64
+ ul = $('<ul></ul>')
65
+ switch Spec.Format
66
+ when 'ul'
67
+ parent.ul.append($('<li>' + title + '</li>').append(ul))
68
+ when 'terminal'
69
+ $('.results').append(Spec.pad(title, parent.ul.depth) + "<br>")
70
+ ul.depth = parent.ul.depth + 2
71
+
72
+ Spec.testStack.push {
73
+ title: title
74
+ ul: ul
75
+ before: []
76
+ }
77
+ definition()
78
+ Spec.testStack.pop()
79
+
80
+ # Tests if matched value == expected value
81
+ equal: (expected) ->
82
+ (value) ->
83
+ [String(value) == String(expected), "to match &ldquo;#{$.trim diffString(String(value), String(expected))}&rdquo;"]
84
+
85
+ # Allows an assertion on a non-object value
86
+ expect: (object) ->
87
+ {
88
+ to: (matcher) ->
89
+ result = Spec.findMatcher(matcher)(object)
90
+ Spec.fail "expected #{result[1]}" unless result[0]
91
+ notTo: (matcher) ->
92
+ result = Spec.findMatcher(matcher)(object)
93
+ Spec.fail "expected not #{result[1]}" if result[0]
94
+ }
95
+
96
+ # Sets up an expectation
97
+ expectation: (message) ->
98
+ exp = {
99
+ message: message
100
+ meet: -> @met++
101
+ met: 0
102
+ desired: 1
103
+ twice: ->
104
+ @desired = 2
105
+ this
106
+ exactly: (times) ->
107
+ @desired = times
108
+ {times: this}
109
+ timesString: (times) ->
110
+ switch times
111
+ when 0
112
+ 'not at all'
113
+ when 1
114
+ 'once'
115
+ when 2
116
+ 'twice'
117
+ else
118
+ "#{times} times"
119
+ check: ->
120
+ if @met != @desired
121
+ Spec.fail "expected #{message} #{@timesString @desired}, actually received #{@timesString @met}"
122
+ }
123
+ Spec.expectations.push exp
124
+ exp
125
+
126
+ finishTest: ->
127
+ for expectation in Spec.expectations
128
+ expectation.check()
129
+
130
+ reportTestResult(if Spec.passed then "passed" else "failed")
131
+
132
+ delete Spec.expectations
133
+ delete Spec.testTitle
134
+ window.onerror = -> null
135
+
136
+ Spec.env.sandbox.empty().remove()
137
+
138
+ # Syntactic sugar to create a before method that prepares a variable
139
+ #
140
+ # Example:
141
+ # given 'dog', -> new Dog()
142
+ given: (name, definition) ->
143
+ before ->
144
+ @[name] = definition.call Spec.env
145
+
146
+ haveHtml: (expected) ->
147
+ (value) ->
148
+ div = $(document.createElement 'div')
149
+ div.html expected
150
+ normalized = div.html()
151
+ actual = value.html()
152
+ [actual == normalized, "to have html &ldquo;#{$.trim diffString(actual, normalized)}&rdquo;"]
153
+
154
+ # All-purpose inclusion matcher
155
+ include: (expected) ->
156
+ if expected instanceof Array
157
+ (value) ->
158
+ match = true
159
+ for test in expected
160
+ match = false unless (value.indexOf && value.indexOf(test) >= 0) || value[test]?
161
+ [match, "to include #{Spec.inspect expected}, actual #{Spec.inspect value}"]
162
+ else if typeof expected == 'object'
163
+ (value) ->
164
+ missing = {}
165
+ match = true
166
+ for test of expected
167
+ if expected.hasOwnProperty test
168
+ unless value[test] isnt undefined && String(value[test]) == String(expected[test])
169
+ match = false
170
+ missing[test] = expected[test]
171
+ [match, "to include #{Spec.inspect expected}, actual #{Spec.inspect value}, missing #{Spec.inspect missing}"]
172
+ else
173
+ include([expected])
174
+
175
+ # Creates a specificaition
176
+ it: (title, definition) ->
177
+ # Automatically choose a title when only definition supplied
178
+ if typeof title is 'function'
179
+ definition = title
180
+ title = Spec.descriptionize title
181
+
182
+ test = Spec.testStack[Spec.testStack.length - 1]
183
+ if definition?
184
+ Spec.env = {sandbox: $('<div/>').appendTo document.body}
185
+ for aTest in Spec.testStack
186
+ for action in aTest.before
187
+ action.call Spec.env
188
+
189
+ Spec.expectations = []
190
+ Spec.testTitle = title
191
+
192
+ window.onerror = (message, url, line) ->
193
+ Spec.fail message, "#{url.replace(document.location, '')}:#{line}"
194
+ Spec.passed = false
195
+ finishTest()
196
+
197
+ Spec.passed = true
198
+ definition.call Spec.env
199
+ finishTest()
200
+ else
201
+ reportTestResult "pending"
202
+
203
+ # Creates a specification that tests an attribute of subject
204
+ #
205
+ # Example:
206
+ # subject -> new Employee('Fred')
207
+ # its 'name', -> should equal('Fred')
208
+ its: (attribute, definition) ->
209
+ it "#{attribute} #{Spec.descriptionize definition}", ->
210
+ value = @subject[attribute]
211
+ value = value.call @subject if typeof value is 'function'
212
+ @subject = value
213
+ definition.call Spec.env
214
+
215
+ reportTestResult: (status) ->
216
+ test = Spec.testStack[Spec.testStack.length - 1]
217
+
218
+ switch Spec.Format
219
+ when 'ul'
220
+ test.ul.append '<li class="' + status + '">' + Spec.testTitle + '</li>'
221
+ when 'terminal'
222
+ s = Spec.testTitle
223
+ color = switch status
224
+ when 'passed' then 32
225
+ when 'failed' then 31
226
+ when 'pending' then 33
227
+ $('.results').append Spec.pad("&#x1b;[#{color}m#{s}&#x1b;[0m<br>", test.ul.depth)
228
+
229
+ Spec.counts[status]++
230
+ Spec.counts.total++
231
+
232
+ # Runs a test against @subject
233
+ #
234
+ # Example
235
+ # subject -> new Employee()
236
+ # it -> should beAnInstanceOf(Employee)
237
+ should: (matcher) ->
238
+ expect(Spec.env.subject).to matcher
239
+
240
+ # Runs a negative test against @subject
241
+ #
242
+ # Example
243
+ # subject -> new Employee()
244
+ # it -> shouldNot be(null)
245
+ shouldNot: (matcher) ->
246
+ expect(Spec.env.subject).notTo matcher
247
+
248
+ # Creates a before method to prepare the @subject variable
249
+ subject: (definition) ->
250
+ given 'subject', definition
251
+
252
+ }