rest-assured 1.1.2 → 1.1.3

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/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rest-assured (1.1.2)
4
+ rest-assured (1.1.3)
5
5
  activerecord (~> 3.2.0)
6
6
  activeresource (~> 3.2.0)
7
7
  childprocess (~> 0.3.0)
@@ -12,23 +12,23 @@ PATH
12
12
  GEM
13
13
  remote: http://rubygems.org/
14
14
  specs:
15
- activemodel (3.2.1)
16
- activesupport (= 3.2.1)
15
+ activemodel (3.2.2)
16
+ activesupport (= 3.2.2)
17
17
  builder (~> 3.0.0)
18
- activerecord (3.2.1)
19
- activemodel (= 3.2.1)
20
- activesupport (= 3.2.1)
21
- arel (~> 3.0.0)
18
+ activerecord (3.2.2)
19
+ activemodel (= 3.2.2)
20
+ activesupport (= 3.2.2)
21
+ arel (~> 3.0.2)
22
22
  tzinfo (~> 0.3.29)
23
- activeresource (3.2.1)
24
- activemodel (= 3.2.1)
25
- activesupport (= 3.2.1)
26
- activesupport (3.2.1)
23
+ activeresource (3.2.2)
24
+ activemodel (= 3.2.2)
25
+ activesupport (= 3.2.2)
26
+ activesupport (3.2.2)
27
27
  i18n (~> 0.6)
28
28
  multi_json (~> 1.0)
29
29
  addressable (2.2.7)
30
30
  archive-tar-minitar (0.5.2)
31
- arel (3.0.0)
31
+ arel (3.0.2)
32
32
  awesome_print (1.0.2)
33
33
  builder (3.0.0)
34
34
  capybara (1.1.2)
@@ -43,10 +43,10 @@ GEM
43
43
  childprocess (0.3.1)
44
44
  ffi (~> 1.0.6)
45
45
  columnize (0.3.6)
46
- cucumber (1.1.4)
46
+ cucumber (1.1.9)
47
47
  builder (>= 2.1.2)
48
48
  diff-lcs (>= 1.1.2)
49
- gherkin (~> 2.7.1)
49
+ gherkin (~> 2.9.0)
50
50
  json (>= 1.4.6)
51
51
  term-ansicolor (>= 1.0.6)
52
52
  daemons (1.1.8)
@@ -54,7 +54,7 @@ GEM
54
54
  diff-lcs (1.1.3)
55
55
  eventmachine (0.12.10)
56
56
  ffi (1.0.11)
57
- gherkin (2.7.7)
57
+ gherkin (2.9.0)
58
58
  json (>= 1.4.6)
59
59
  growl (1.0.3)
60
60
  guard (1.0.0)
@@ -72,12 +72,12 @@ GEM
72
72
  addressable (~> 2.2.6)
73
73
  linecache (0.46)
74
74
  rbx-require-relative (> 0.0.4)
75
- linecache19 (0.5.13)
75
+ linecache19 (0.5.12)
76
76
  ruby_core_source (>= 0.1.4)
77
77
  mime-types (1.17.2)
78
- multi_json (1.0.4)
78
+ multi_json (1.1.0)
79
79
  mysql2 (0.3.11)
80
- nokogiri (1.5.0)
80
+ nokogiri (1.5.2)
81
81
  pg (0.13.2)
82
82
  rack (1.4.1)
83
83
  rack-protection (1.2.0)
@@ -87,7 +87,7 @@ GEM
87
87
  rake (0.9.2.2)
88
88
  rb-fsevent (0.9.0)
89
89
  rb-readline (0.4.2)
90
- rbx-require-relative (0.0.5)
90
+ rbx-require-relative (0.0.9)
91
91
  relish (0.5.3)
92
92
  archive-tar-minitar (>= 0.5.2)
93
93
  json (>= 1.4.6)
@@ -107,7 +107,7 @@ GEM
107
107
  ruby-debug-base (~> 0.10.4.0)
108
108
  ruby-debug-base (0.10.4)
109
109
  linecache (>= 0.3)
110
- ruby-debug-base19 (0.11.26)
110
+ ruby-debug-base19 (0.11.25)
111
111
  columnize (>= 0.3.1)
112
112
  linecache19 (>= 0.5.11)
113
113
  ruby_core_source (>= 0.1.4)
@@ -118,14 +118,14 @@ GEM
118
118
  ruby_core_source (0.1.5)
119
119
  archive-tar-minitar (>= 0.5.2)
120
120
  rubyzip (0.9.6.1)
121
- selenium-webdriver (2.19.0)
121
+ selenium-webdriver (2.20.0)
122
122
  childprocess (>= 0.2.5)
123
- ffi (~> 1.0.9)
124
- multi_json (~> 1.0.4)
123
+ ffi (~> 1.0)
124
+ multi_json (~> 1.0)
125
125
  rubyzip
126
126
  shoulda-matchers (1.0.0)
127
- simplecov (0.5.4)
128
- multi_json (~> 1.0.3)
127
+ simplecov (0.6.1)
128
+ multi_json (~> 1.0)
129
129
  simplecov-html (~> 0.5.3)
130
130
  simplecov-html (0.5.3)
131
131
  sinatra (1.3.2)
@@ -146,7 +146,7 @@ GEM
146
146
  rack (>= 1.0.0)
147
147
  thor (0.14.6)
148
148
  tilt (1.3.3)
149
- tzinfo (0.3.31)
149
+ tzinfo (0.3.32)
150
150
  xpath (0.1.4)
151
151
  nokogiri (~> 1.3)
152
152
 
data/README.markdown CHANGED
@@ -5,12 +5,16 @@
5
5
  ## Overview
6
6
 
7
7
  Stub/spy http(s) based external dependencies in your integration/acceptance tests.
8
- In essense, here is what it could be useful for:
9
8
 
10
- * stub out external data sources with predefined data
11
- * verify requests to external services (aka spying)
9
+ In a nutshell, here is how you can use it:
10
+
11
+ * replace external data sources with predefined data (stubbing)
12
+ * verify requests to external services (spying)
12
13
  * simulate different behavior of external services using web UI; useful in development
13
14
 
15
+ Check out [example](https://github.com/artemave/REST-assured-example)
16
+
17
+
14
18
  ## Usage
15
19
 
16
20
  You are going to need MRI ruby >= 1.8.7 on Linux/MacOS.
@@ -32,7 +36,7 @@ Then install gem and run:
32
36
 
33
37
  Or clone and run:
34
38
 
35
- bash$ git clone git@github.com:BBC/rest-assured.git
39
+ bash$ git clone git://github.com/BBC/REST-assured.git
36
40
  bash$ cd rest-assured && bundle install
37
41
  bash$ ./bin/rest-assured -d :memory: & # in-memory sqlite db
38
42
 
@@ -42,7 +46,7 @@ Various options (such as ssl, port, db credentials, etc.) are available through
42
46
 
43
47
  You can also deploy it to heroku:
44
48
 
45
- bash$ git clone git@github.com:BBC/rest-assured.git
49
+ bash$ git clone git://github.com/BBC/REST-assured.git
46
50
  bash$ cd rest-assured
47
51
 
48
52
  bash$ gem install heroku
@@ -57,7 +61,7 @@ Double is a stub/spy of HTTP request. Create a double that has the same request
57
61
 
58
62
  ### Ruby Client API
59
63
 
60
- Rest-assured provides client library to work with doubles. Check out 'Ruby API' section in [documentation](https://www.relishapp.com/artemave/rest-assured) for full reference.
64
+ Rest-assured provides client library to work with doubles. Check out 'Ruby API' section in [live documentation](https://www.relishapp.com/artemave/rest-assured) for full reference.
61
65
 
62
66
  Start up the server:
63
67
 
@@ -209,7 +213,7 @@ Here is the rest API for managing redirects:
209
213
 
210
214
  Tests require there to be mysql database `rest_assured_test` accessible by `root` with no password. Cucumber tests also need firefox.
211
215
 
212
- bash$ git clone git@github.com:BBC/rest-assured.git
216
+ bash$ git clone git://github.com/BBC/REST-assured.git
213
217
  bash$ cd rest-assured && bundle install
214
218
  bash$ bundle exec rspec spec
215
219
  bash$ bundle exec cucumber
@@ -0,0 +1,9 @@
1
+ class ChangeFullpathToText < ActiveRecord::Migration
2
+ def self.up
3
+ change_column :doubles, :fullpath, :text
4
+ end
5
+
6
+ def self.down
7
+ change_column :doubles, :fullpath, :string
8
+ end
9
+ end
@@ -46,19 +46,17 @@ Given /^I choose to delete redirect with pattern "([^"]*)"$/ do |pattern|
46
46
  end
47
47
 
48
48
  When /^I reorder second redirect to be the first one$/ do
49
- handler = find("#redirects #redirect_#{RestAssured::Models::Redirect.last.id} td.handle")
50
- target = find('#redirects thead')
51
-
52
- handler.drag_to target
49
+ page.execute_script %{
50
+ $('#redirects #redirect_#{RestAssured::Models::Redirect.order('position').last.id}').simulateDragSortable({move: -1, handle: '.handle'})
51
+ }
52
+ sleep 2
53
53
  end
54
54
 
55
55
  Then /^"([^"]*)" should be redirected to "([^"]*)"$/ do |missing_request, url|
56
- pending('This does not pass due to Capybara/Selelium broken drag and drop support')
57
-
58
56
  get missing_request
59
57
  follow_redirect!
60
58
 
61
- last_request.url.should == "#{url}#{missing_request}"
59
+ last_request.url.should == url
62
60
  end
63
61
 
64
62
  Given /^blank slate$/ do
@@ -49,9 +49,9 @@ Feature: manage redirects via ui
49
49
  | /api/bbb | http://twitter.com/api |
50
50
  And I am on "redirects" page
51
51
  When I reorder second redirect to be the first one
52
- Then "/api/bbb" should be redirected to "http://twitter.com/api"
52
+ Then "/api/bbb/ccc" should be redirected to "http://twitter.com/api/ccc"
53
53
  When I reorder second redirect to be the first one
54
- Then "/api/bbb" should be redirected to "http://google.com/api"
54
+ Then "/api/bbb/ccc" should be redirected to "http://google.com/api"
55
55
 
56
56
  @javascript
57
57
  Scenario: delete redirect
@@ -1,3 +1,3 @@
1
1
  module RestAssured
2
- VERSION = '1.1.2'
2
+ VERSION = '1.1.3'
3
3
  end
@@ -0,0 +1,235 @@
1
+ (function($) {
2
+ /*
3
+ * Simulate drag of a JQuery UI sortable list
4
+ * Repository: https://github.com/mattheworiordan/jquery.simulate.drag-sortable.js
5
+ * Author: http://mattheworiordan.com
6
+ *
7
+ * options are:
8
+ * - move: move item up (positive) or down (negative) by Integer amount
9
+ * - dropOn: move item to a new linked list, move option now represents position in the new list (zero indexed)
10
+ * - handle: selector for the draggable handle element (optional)
11
+ * - listItem: selector to limit which sibling items can be used for reordering
12
+ * - placeHolder: if a placeholder is used during dragging, we need to consider it's height
13
+ * - tolerance: (optional) number of pixels to overlap by instead of the default 50% of the element height
14
+ *
15
+ */
16
+ $.fn.simulateDragSortable = function(options) {
17
+ // build main options before element iteration
18
+ var opts = $.extend({}, $.fn.simulateDragSortable.defaults, options);
19
+
20
+ applyDrag = function(options) {
21
+ // allow for a drag handle if item is not draggable
22
+ var that = this,
23
+ options = options || opts, // default to plugin opts unless options explicitly provided
24
+ handle = options.handle ? $(this).find(options.handle)[0] : $(this)[0],
25
+ listItem = options.listItem,
26
+ placeHolder = options.placeHolder,
27
+ sibling = $(this),
28
+ moveCounter = Math.floor(options.move),
29
+ direction = moveCounter > 0 ? 'down' : 'up',
30
+ moveVerticalAmount = 0,
31
+ initialVerticalPosition = 0,
32
+ extraDrag = !isNaN(parseInt(options.tolerance, 10)) ? function() { return Number(options.tolerance); } : function(obj) { return ($(obj).outerHeight() / 2) + 5; },
33
+ dragPastBy = 0, // represents the additional amount one drags past an element and bounce back
34
+ dropOn = options.dropOn ? $(options.dropOn) : false,
35
+ center = findCenter(handle),
36
+ x = Math.floor(center.x),
37
+ y = Math.floor(center.y),
38
+ mouseUpAfter = (opts.debug ? 2500 : 10);
39
+
40
+ if (dropOn) {
41
+ if (dropOn.length === 0) {
42
+ if (console && console.log) { console.log('simulate.drag-sortable.js ERROR: Drop on target could not be found'); console.log(options.dropOn); }
43
+ return;
44
+ }
45
+ sibling = dropOn.find('>*:last');
46
+ moveCounter = -(dropOn.find('>*').length + 1) + (moveCounter + 1); // calculate length of list after this move, use moveCounter as a positive index position in list to reverse back up
47
+ if (dropOn.offset().top - $(this).offset().top < 0) {
48
+ // moving to a list above this list, so move to just above top of last item (tried moving to top but JQuery UI wouldn't bite)
49
+ initialVerticalPosition = sibling.offset().top - $(this).offset().top - extraDrag(this);
50
+ } else {
51
+ // moving to a list below this list, so move to bottom and work up (JQuery UI does not trigger new list below unless you move past top item first)
52
+ initialVerticalPosition = sibling.offset().top - $(this).offset().top - $(this).height();
53
+ }
54
+ } else if (moveCounter === 0) {
55
+ if (console && console.log) { console.log('simulate.drag-sortable.js WARNING: Drag with move set to zero has no effect'); }
56
+ return;
57
+ } else {
58
+ while (moveCounter !== 0) {
59
+ if (direction === 'down') {
60
+ if (sibling.next(listItem).length) {
61
+ sibling = sibling.next(listItem);
62
+ moveVerticalAmount += sibling.outerHeight();
63
+ }
64
+ moveCounter -= 1;
65
+ } else {
66
+ if (sibling.prev(listItem).length) {
67
+ sibling = sibling.prev(listItem);
68
+ moveVerticalAmount -= sibling.outerHeight();
69
+ }
70
+ moveCounter += 1;
71
+ }
72
+ }
73
+ }
74
+
75
+ dispatchEvent(handle, 'mousedown', createEvent('mousedown', handle, { clientX: x, clientY: y }));
76
+ // simulate drag start
77
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x+1, clientY: y+1 }));
78
+
79
+ if (dropOn) {
80
+ // jump to top or bottom of new list but do it in increments so that JQuery UI registers the drag events
81
+ slideUpTo(x, y, initialVerticalPosition);
82
+
83
+ // reset y position to top or bottom of list and move from there
84
+ y += initialVerticalPosition;
85
+
86
+ // now call regular shift/down in a list
87
+ options = jQuery.extend(options, { move: moveCounter });
88
+ delete options.dropOn;
89
+
90
+ // add some delays to allow JQuery UI to catch up
91
+ setTimeout(function() {
92
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y }));
93
+ }, 5);
94
+ setTimeout(function() {
95
+ dispatchEvent(handle, 'mouseup', createEvent('mouseup', handle, { clientX: x, clientY: y }));
96
+ setTimeout(function() {
97
+ if (options.move) {
98
+ applyDrag.call(that, options);
99
+ }
100
+ }, 5);
101
+ }, mouseUpAfter);
102
+
103
+ // stop execution as applyDrag has been called again
104
+ return;
105
+ }
106
+
107
+ // Sortable is using a fixed height placeholder meaning items jump up and down as you drag variable height items into fixed height placeholder
108
+ placeHolder = placeHolder && $(this).parent().find(placeHolder);
109
+
110
+ if (!placeHolder && (direction === 'down')) {
111
+ // need to move at least as far as this item and or the last sibling
112
+ if ($(this).outerHeight() > $(sibling).outerHeight()) {
113
+ moveVerticalAmount += $(this).outerHeight() - $(sibling).outerHeight();
114
+ }
115
+ moveVerticalAmount += extraDrag(sibling);
116
+ dragPastBy += extraDrag(sibling);
117
+ } else if (direction === 'up') {
118
+ // move a little extra to ensure item clips into next position
119
+ moveVerticalAmount -= Math.max(extraDrag(this), 5);
120
+ } else if (direction === 'down') {
121
+ // moving down with a place holder
122
+ if (placeHolder.height() < $(this).height()) {
123
+ moveVerticalAmount += Math.max(placeHolder.height(), 5);
124
+ } else {
125
+ moveVerticalAmount += extraDrag(sibling);
126
+ }
127
+ }
128
+
129
+ if (sibling[0] !== $(this)[0]) {
130
+ // step through so that the UI controller can determine when to show the placeHolder
131
+ slideUpTo(x, y, moveVerticalAmount, dragPastBy);
132
+ } else {
133
+ if (window.console) {
134
+ console.log('simulate.drag-sortable.js WARNING: Could not move as at top or bottom already');
135
+ }
136
+ }
137
+
138
+ setTimeout(function() {
139
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + moveVerticalAmount }));
140
+ }, 5);
141
+ setTimeout(function() {
142
+ dispatchEvent(handle, 'mouseup', createEvent('mouseup', handle, { clientX: x, clientY: y + moveVerticalAmount }));
143
+ }, mouseUpAfter);
144
+ };
145
+
146
+ // iterate and move each matched element
147
+ return this.each(applyDrag);
148
+ };
149
+
150
+ // fire mouse events, go half way, then the next half, so small mouse movements near target and big at the start
151
+ function slideUpTo(x, y, targetOffset, goPastBy) {
152
+ var moveBy, offset;
153
+
154
+ if (!goPastBy) { goPastBy = 0; }
155
+ if ((targetOffset < 0) && (goPastBy > 0)) { goPastBy = -goPastBy; } // ensure go past is in the direction as often passed in from object height so always positive
156
+
157
+ // go forwards including goPastBy
158
+ for (offset = 0; Math.abs(offset) + 1 < Math.abs(targetOffset + goPastBy); offset += ((targetOffset + goPastBy - offset)/2) ) {
159
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + Math.ceil(offset) }));
160
+ }
161
+ offset = targetOffset + goPastBy;
162
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + offset }));
163
+
164
+ // now bounce back
165
+ for (; Math.abs(offset) - 1 >= Math.abs(targetOffset); offset += ((targetOffset - offset)/2) ) {
166
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + Math.ceil(offset) }));
167
+ }
168
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + targetOffset }));
169
+ }
170
+
171
+ function createEvent(type, target, options) {
172
+ var evt;
173
+ var e = $.extend({
174
+ target: target,
175
+ preventDefault: function() { },
176
+ stopImmediatePropagation: function() { },
177
+ stopPropagation: function() { },
178
+ isPropagationStopped: function() { return true; },
179
+ isImmediatePropagationStopped: function() { return true; },
180
+ isDefaultPrevented: function() { return true; },
181
+ bubbles: true,
182
+ cancelable: (type != "mousemove"),
183
+ view: window,
184
+ detail: 0,
185
+ screenX: 0,
186
+ screenY: 0,
187
+ clientX: 0,
188
+ clientY: 0,
189
+ ctrlKey: false,
190
+ altKey: false,
191
+ shiftKey: false,
192
+ metaKey: false,
193
+ button: 0,
194
+ relatedTarget: undefined
195
+ }, options || {});
196
+
197
+ if ($.isFunction(document.createEvent)) {
198
+ evt = document.createEvent("MouseEvents");
199
+ evt.initMouseEvent(type, e.bubbles, e.cancelable, e.view, e.detail,
200
+ e.screenX, e.screenY, e.clientX, e.clientY,
201
+ e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
202
+ e.button, e.relatedTarget || document.body.parentNode);
203
+ } else if (document.createEventObject) {
204
+ evt = document.createEventObject();
205
+ $.extend(evt, e);
206
+ evt.button = { 0:1, 1:4, 2:2 }[evt.button] || evt.button;
207
+ }
208
+ return evt;
209
+ }
210
+
211
+ function dispatchEvent(el, type, evt) {
212
+ if (el.dispatchEvent) {
213
+ el.dispatchEvent(evt);
214
+ } else if (el.fireEvent) {
215
+ el.fireEvent('on' + type, evt);
216
+ }
217
+ return evt;
218
+ }
219
+
220
+ function findCenter(el) {
221
+ var elm = $(el),
222
+ o = elm.offset();
223
+ return {
224
+ x: o.left + elm.outerWidth() / 2,
225
+ y: o.top + elm.outerHeight() / 2
226
+ };
227
+ }
228
+
229
+ //
230
+ // plugin defaults
231
+ //
232
+ $.fn.simulateDragSortable.defaults = {
233
+ move: 0
234
+ };
235
+ })(jQuery);