sauce 0.7.2 → 0.8.0

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,119 @@
1
+ """Drop-in replacement for collections.OrderedDict by Raymond Hettinger
2
+
3
+ http://code.activestate.com/recipes/576693/
4
+
5
+ """
6
+ from UserDict import DictMixin
7
+
8
+ # Modified from original to support Python 2.4, see
9
+ # http://code.google.com/p/simplejson/issues/detail?id=53
10
+ try:
11
+ all
12
+ except NameError:
13
+ def all(seq):
14
+ for elem in seq:
15
+ if not elem:
16
+ return False
17
+ return True
18
+
19
+ class OrderedDict(dict, DictMixin):
20
+
21
+ def __init__(self, *args, **kwds):
22
+ if len(args) > 1:
23
+ raise TypeError('expected at most 1 arguments, got %d' % len(args))
24
+ try:
25
+ self.__end
26
+ except AttributeError:
27
+ self.clear()
28
+ self.update(*args, **kwds)
29
+
30
+ def clear(self):
31
+ self.__end = end = []
32
+ end += [None, end, end] # sentinel node for doubly linked list
33
+ self.__map = {} # key --> [key, prev, next]
34
+ dict.clear(self)
35
+
36
+ def __setitem__(self, key, value):
37
+ if key not in self:
38
+ end = self.__end
39
+ curr = end[1]
40
+ curr[2] = end[1] = self.__map[key] = [key, curr, end]
41
+ dict.__setitem__(self, key, value)
42
+
43
+ def __delitem__(self, key):
44
+ dict.__delitem__(self, key)
45
+ key, prev, next = self.__map.pop(key)
46
+ prev[2] = next
47
+ next[1] = prev
48
+
49
+ def __iter__(self):
50
+ end = self.__end
51
+ curr = end[2]
52
+ while curr is not end:
53
+ yield curr[0]
54
+ curr = curr[2]
55
+
56
+ def __reversed__(self):
57
+ end = self.__end
58
+ curr = end[1]
59
+ while curr is not end:
60
+ yield curr[0]
61
+ curr = curr[1]
62
+
63
+ def popitem(self, last=True):
64
+ if not self:
65
+ raise KeyError('dictionary is empty')
66
+ # Modified from original to support Python 2.4, see
67
+ # http://code.google.com/p/simplejson/issues/detail?id=53
68
+ if last:
69
+ key = reversed(self).next()
70
+ else:
71
+ key = iter(self).next()
72
+ value = self.pop(key)
73
+ return key, value
74
+
75
+ def __reduce__(self):
76
+ items = [[k, self[k]] for k in self]
77
+ tmp = self.__map, self.__end
78
+ del self.__map, self.__end
79
+ inst_dict = vars(self).copy()
80
+ self.__map, self.__end = tmp
81
+ if inst_dict:
82
+ return (self.__class__, (items,), inst_dict)
83
+ return self.__class__, (items,)
84
+
85
+ def keys(self):
86
+ return list(self)
87
+
88
+ setdefault = DictMixin.setdefault
89
+ update = DictMixin.update
90
+ pop = DictMixin.pop
91
+ values = DictMixin.values
92
+ items = DictMixin.items
93
+ iterkeys = DictMixin.iterkeys
94
+ itervalues = DictMixin.itervalues
95
+ iteritems = DictMixin.iteritems
96
+
97
+ def __repr__(self):
98
+ if not self:
99
+ return '%s()' % (self.__class__.__name__,)
100
+ return '%s(%r)' % (self.__class__.__name__, self.items())
101
+
102
+ def copy(self):
103
+ return self.__class__(self)
104
+
105
+ @classmethod
106
+ def fromkeys(cls, iterable, value=None):
107
+ d = cls()
108
+ for key in iterable:
109
+ d[key] = value
110
+ return d
111
+
112
+ def __eq__(self, other):
113
+ if isinstance(other, OrderedDict):
114
+ return len(self)==len(other) and \
115
+ all(p==q for p, q in zip(self.items(), other.items()))
116
+ return dict.__eq__(self, other)
117
+
118
+ def __ne__(self, other):
119
+ return not self == other
@@ -0,0 +1,77 @@
1
+ """JSON token scanner
2
+ """
3
+ import re
4
+ def _import_c_make_scanner():
5
+ try:
6
+ from simplejson._speedups import make_scanner
7
+ return make_scanner
8
+ except ImportError:
9
+ return None
10
+ c_make_scanner = _import_c_make_scanner()
11
+
12
+ __all__ = ['make_scanner']
13
+
14
+ NUMBER_RE = re.compile(
15
+ r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
16
+ (re.VERBOSE | re.MULTILINE | re.DOTALL))
17
+
18
+ def py_make_scanner(context):
19
+ parse_object = context.parse_object
20
+ parse_array = context.parse_array
21
+ parse_string = context.parse_string
22
+ match_number = NUMBER_RE.match
23
+ encoding = context.encoding
24
+ strict = context.strict
25
+ parse_float = context.parse_float
26
+ parse_int = context.parse_int
27
+ parse_constant = context.parse_constant
28
+ object_hook = context.object_hook
29
+ object_pairs_hook = context.object_pairs_hook
30
+ memo = context.memo
31
+
32
+ def _scan_once(string, idx):
33
+ try:
34
+ nextchar = string[idx]
35
+ except IndexError:
36
+ raise StopIteration
37
+
38
+ if nextchar == '"':
39
+ return parse_string(string, idx + 1, encoding, strict)
40
+ elif nextchar == '{':
41
+ return parse_object((string, idx + 1), encoding, strict,
42
+ _scan_once, object_hook, object_pairs_hook, memo)
43
+ elif nextchar == '[':
44
+ return parse_array((string, idx + 1), _scan_once)
45
+ elif nextchar == 'n' and string[idx:idx + 4] == 'null':
46
+ return None, idx + 4
47
+ elif nextchar == 't' and string[idx:idx + 4] == 'true':
48
+ return True, idx + 4
49
+ elif nextchar == 'f' and string[idx:idx + 5] == 'false':
50
+ return False, idx + 5
51
+
52
+ m = match_number(string, idx)
53
+ if m is not None:
54
+ integer, frac, exp = m.groups()
55
+ if frac or exp:
56
+ res = parse_float(integer + (frac or '') + (exp or ''))
57
+ else:
58
+ res = parse_int(integer)
59
+ return res, m.end()
60
+ elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
61
+ return parse_constant('NaN'), idx + 3
62
+ elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
63
+ return parse_constant('Infinity'), idx + 8
64
+ elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
65
+ return parse_constant('-Infinity'), idx + 9
66
+ else:
67
+ raise StopIteration
68
+
69
+ def scan_once(string, idx):
70
+ try:
71
+ return _scan_once(string, idx)
72
+ finally:
73
+ memo.clear()
74
+
75
+ return scan_once
76
+
77
+ make_scanner = c_make_scanner or py_make_scanner
@@ -0,0 +1,39 @@
1
+ r"""Command-line tool to validate and pretty-print JSON
2
+
3
+ Usage::
4
+
5
+ $ echo '{"json":"obj"}' | python -m simplejson.tool
6
+ {
7
+ "json": "obj"
8
+ }
9
+ $ echo '{ 1.2:3.4}' | python -m simplejson.tool
10
+ Expecting property name: line 1 column 2 (char 2)
11
+
12
+ """
13
+ import sys
14
+ import simplejson as json
15
+
16
+ def main():
17
+ if len(sys.argv) == 1:
18
+ infile = sys.stdin
19
+ outfile = sys.stdout
20
+ elif len(sys.argv) == 2:
21
+ infile = open(sys.argv[1], 'rb')
22
+ outfile = sys.stdout
23
+ elif len(sys.argv) == 3:
24
+ infile = open(sys.argv[1], 'rb')
25
+ outfile = open(sys.argv[2], 'wb')
26
+ else:
27
+ raise SystemExit(sys.argv[0] + " [infile [outfile]]")
28
+ try:
29
+ obj = json.load(infile,
30
+ object_pairs_hook=json.OrderedDict,
31
+ use_decimal=True)
32
+ except ValueError, e:
33
+ raise SystemExit(e)
34
+ json.dump(obj, outfile, sort_keys=True, indent=' ', use_decimal=True)
35
+ outfile.write('\n')
36
+
37
+
38
+ if __name__ == '__main__':
39
+ main()
@@ -8,6 +8,12 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
8
  require 'sauce'
9
9
 
10
10
  Sauce.config do |config|
11
- config.browsers = [['Windows 2003', 'firefox', '3.6.']]
12
- config.root_url = "http://saucelabs.com"
11
+ config.browsers = [
12
+ ["Windows 2003", "firefox", "3.6."],
13
+ ["Windows 2003", "safariproxy", "5."]
14
+ ]
15
+ config.browser_url = "http://saucelabs.com"
16
+
17
+ #config.application_host = "localhost"
18
+ #config.application_port = "4444"
13
19
  end
@@ -0,0 +1,25 @@
1
+ require 'helper'
2
+
3
+ class TestConnect < Test::Unit::TestCase
4
+ context "Sauce Connect" do
5
+ should "be running when ready" do
6
+ connect = Sauce::Connect.new(:host => "saucelabs.com", :port => 80)
7
+ assert_equal "uninitialized", connect.status
8
+ connect.wait_until_ready
9
+ assert_equal "running", connect.status
10
+ connect.status.should == "running"
11
+ connect.disconnect
12
+ end
13
+
14
+ should "set error flag if things don't go well" do
15
+ connect = Sauce::Connect.new(:host => "saucelabs.com", :port => 80, :username => 'fail')
16
+ start = Time.now
17
+ while Time.now-start < 20 && !connect.error
18
+ sleep 1
19
+ end
20
+
21
+ assert connect.error
22
+ connect.disconnect
23
+ end
24
+ end
25
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sauce
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 63
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 7
9
- - 2
10
- version: 0.7.2
8
+ - 8
9
+ - 0
10
+ version: 0.8.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sean Grove
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-10-25 00:00:00 -07:00
19
+ date: 2010-10-26 00:00:00 -07:00
20
20
  default_executable: sauce
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -143,15 +143,26 @@ files:
143
143
  - lib/sauce.rb
144
144
  - lib/sauce/client.rb
145
145
  - lib/sauce/config.rb
146
+ - lib/sauce/connect.rb
146
147
  - lib/sauce/gateway_ext.rb
147
148
  - lib/sauce/heroku.rb
148
149
  - lib/sauce/integrations.rb
149
150
  - lib/sauce/job.rb
150
151
  - lib/sauce/selenium.rb
151
152
  - lib/sauce/tunnel.rb
153
+ - spec/other_spec.rb
154
+ - spec/saucelabs_spec.rb
155
+ - support/sauce_connect
156
+ - support/simplejson/LICENSE.txt
157
+ - support/simplejson/__init__.py
158
+ - support/simplejson/decoder.py
159
+ - support/simplejson/encoder.py
160
+ - support/simplejson/ordered_dict.py
161
+ - support/simplejson/scanner.py
162
+ - support/simplejson/tool.py
152
163
  - test/helper.rb
153
- - test/saucelabs_spec.rb
154
164
  - test/test_config.rb
165
+ - test/test_connect.rb
155
166
  - test/test_jobs.rb
156
167
  - test/test_selenium.rb
157
168
  - test/test_tunnels.rb
@@ -190,9 +201,11 @@ signing_key:
190
201
  specification_version: 3
191
202
  summary: Ruby access to Sauce Labs' features
192
203
  test_files:
204
+ - spec/other_spec.rb
205
+ - spec/saucelabs_spec.rb
193
206
  - test/helper.rb
194
- - test/saucelabs_spec.rb
195
207
  - test/test_config.rb
208
+ - test/test_connect.rb
196
209
  - test/test_jobs.rb
197
210
  - test/test_selenium.rb
198
211
  - test/test_tunnels.rb