seaweed 0.1.1 → 0.1.2

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/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
+ }