bubble-wrap 0.3.1 → 0.4.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.
- data/CHANGELOG.md +5 -0
- data/README.md +183 -66
- data/Rakefile +6 -6
- data/bubble-wrap.gemspec +10 -5
- data/lib/bubble-wrap.rb +4 -39
- data/lib/bubble-wrap/core.rb +7 -0
- data/lib/bubble-wrap/ext.rb +2 -0
- data/lib/bubble-wrap/ext/motion_project_app.rb +26 -0
- data/lib/bubble-wrap/ext/motion_project_config.rb +21 -0
- data/lib/bubble-wrap/http.rb +2 -249
- data/lib/bubble-wrap/loader.rb +23 -0
- data/lib/bubble-wrap/requirement.rb +88 -0
- data/lib/bubble-wrap/requirement/path_manipulation.rb +40 -0
- data/lib/bubble-wrap/version.rb +1 -1
- data/lib_spec/bubble-wrap/requirement/path_manipulation_spec.rb +51 -0
- data/lib_spec/bubble-wrap/requirement_spec.rb +72 -0
- data/lib_spec/bubble-wrap_spec.rb +17 -0
- data/lib_spec/motion_stub.rb +12 -0
- data/{lib/bubble-wrap/module.rb → motion/core.rb} +0 -0
- data/{lib/bubble-wrap → motion/core}/app.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/device.rb +0 -16
- data/{lib/bubble-wrap → motion/core}/device/screen.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/gestures.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/json.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ns_index_path.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ns_notification_center.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ns_user_defaults.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/persistence.rb +0 -0
- data/{lib → motion/core}/pollute.rb +1 -1
- data/motion/core/string.rb +38 -0
- data/{lib/bubble-wrap → motion/core}/time.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ui_control.rb +0 -0
- data/{lib/bubble-wrap → motion/core}/ui_view_controller.rb +0 -0
- data/motion/http.rb +249 -0
- data/spec/{app_spec.rb → core/app_spec.rb} +2 -2
- data/spec/{device → core/device}/screen_spec.rb +0 -0
- data/spec/{device_spec.rb → core/device_spec.rb} +0 -0
- data/spec/{gestures_spec.rb → core/gestures_spec.rb} +0 -0
- data/spec/{json_spec.rb → core/json_spec.rb} +0 -0
- data/spec/{ns_index_path_spec.rb → core/ns_index_path_spec.rb} +0 -0
- data/spec/{ns_notification_center_spec.rb → core/ns_notification_center_spec.rb} +0 -0
- data/spec/{persistence_spec.rb → core/persistence_spec.rb} +0 -0
- data/spec/core/string_spec.rb +69 -0
- data/spec/{time_spec.rb → core/time_spec.rb} +0 -0
- data/spec/{ui_control_spec.rb → core/ui_control_spec.rb} +0 -0
- data/spec/{module_spec.rb → core_spec.rb} +0 -0
- data/spec/http_spec.rb +300 -280
- metadata +115 -42
@@ -0,0 +1,21 @@
|
|
1
|
+
module Motion
|
2
|
+
module Project
|
3
|
+
class Config
|
4
|
+
# HACK NEEDED since RubyMotion doesn't support full path
|
5
|
+
# dependencies.
|
6
|
+
def files_dependencies(deps_hash)
|
7
|
+
res_path = lambda do |x|
|
8
|
+
path = /^\.?\//.match(x) ? x : File.join('.', x)
|
9
|
+
unless @files.include?(path)
|
10
|
+
App.fail "Can't resolve dependency `#{x}' because #{path} is not in #{@files.inspect}"
|
11
|
+
end
|
12
|
+
path
|
13
|
+
end
|
14
|
+
deps_hash.each do |path, deps|
|
15
|
+
deps = [deps] unless deps.is_a?(Array)
|
16
|
+
@dependencies[res_path.call(path)] = deps.map(&res_path)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/bubble-wrap/http.rb
CHANGED
@@ -1,249 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
SETTINGS = {}
|
4
|
-
|
5
|
-
# The HTTP module provides a simple interface to make HTTP requests.
|
6
|
-
#
|
7
|
-
# TODO: preflight support, easier/better cookie support, better error handling
|
8
|
-
module HTTP
|
9
|
-
|
10
|
-
# Make a GET request and process the response asynchronously via a block.
|
11
|
-
#
|
12
|
-
# @examples
|
13
|
-
# # Simple GET request printing the body
|
14
|
-
# BubbleWrap::HTTP.get("https://api.github.com/users/mattetti") do |response|
|
15
|
-
# p response.body.to_str
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# # GET request with basic auth credentials
|
19
|
-
# BubbleWrap::HTTP.get("https://api.github.com/users/mattetti", {credentials: {username: 'matt', password: 'aimonetti'}}) do |response|
|
20
|
-
# p response.body.to_str # prints the response's body
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
def self.get(url, options={}, &block)
|
24
|
-
delegator = block_given? ? block : options.delete(:action)
|
25
|
-
HTTP::Query.new( url, :get, options.merge({:action => delegator}) )
|
26
|
-
end
|
27
|
-
|
28
|
-
# Make a POST request
|
29
|
-
def self.post(url, options={}, &block)
|
30
|
-
delegator = block_given? ? block : options.delete(:action)
|
31
|
-
HTTP::Query.new( url, :post, options.merge({:action => delegator}) )
|
32
|
-
end
|
33
|
-
|
34
|
-
# Make a PUT request
|
35
|
-
def self.put(url, options={}, &block)
|
36
|
-
delegator = block_given? ? block : options.delete(:action)
|
37
|
-
HTTP::Query.new( url, :put, options.merge({:action => delegator}) )
|
38
|
-
end
|
39
|
-
|
40
|
-
# Make a DELETE request
|
41
|
-
def self.delete(url, options={}, &block)
|
42
|
-
delegator = block_given? ? block : options.delete(:action)
|
43
|
-
HTTP::Query.new( url, :delete, options.merge({:action => delegator}) )
|
44
|
-
end
|
45
|
-
|
46
|
-
# Make a HEAD request
|
47
|
-
def self.head(url, options={}, &block)
|
48
|
-
delegator = block_given? ? block : options.delete(:action)
|
49
|
-
HTTP::Query.new( url, :head, options.merge({:action => delegator}) )
|
50
|
-
end
|
51
|
-
|
52
|
-
# Make a PATCH request
|
53
|
-
def self.patch(url, options={}, &block)
|
54
|
-
delegator = block_given? ? block : options.delete(:action)
|
55
|
-
HTTP::Query.new( url, :patch, options.merge({:action => delegator}) )
|
56
|
-
end
|
57
|
-
|
58
|
-
# Response class wrapping the results of a Query's response
|
59
|
-
class Response
|
60
|
-
attr_reader :body
|
61
|
-
attr_reader :headers
|
62
|
-
attr_accessor :status_code, :error_message
|
63
|
-
attr_reader :url
|
64
|
-
|
65
|
-
def initialize(values={})
|
66
|
-
self.update(values)
|
67
|
-
end
|
68
|
-
|
69
|
-
def update(values)
|
70
|
-
values.each do |k,v|
|
71
|
-
self.instance_variable_set("@#{k}", v)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def ok?
|
76
|
-
status_code.to_s =~ /20\d/ ? true : false
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
# Class wrapping NSConnection and often used indirectly by the BubbleWrap::HTTP module methods.
|
82
|
-
class Query
|
83
|
-
attr_accessor :request
|
84
|
-
attr_accessor :connection
|
85
|
-
attr_accessor :credentials # username & password has a hash
|
86
|
-
attr_accessor :proxy_credential # credential supplied to proxy servers
|
87
|
-
attr_accessor :post_data
|
88
|
-
attr_reader :method
|
89
|
-
|
90
|
-
attr_reader :response
|
91
|
-
attr_reader :status_code
|
92
|
-
attr_reader :response_headers
|
93
|
-
attr_reader :response_size
|
94
|
-
attr_reader :options
|
95
|
-
|
96
|
-
# ==== Parameters
|
97
|
-
# url<String>:: url of the resource to download
|
98
|
-
# http_method<Symbol>:: Value representing the HTTP method to use
|
99
|
-
# options<Hash>:: optional options used for the query
|
100
|
-
#
|
101
|
-
# ==== Options
|
102
|
-
# :payload<String> - data to pass to a POST, PUT, DELETE query.
|
103
|
-
# :delegator - Proc, class or object to call when the file is downloaded.
|
104
|
-
# a proc will receive a Response object while the passed object
|
105
|
-
# will receive the handle_query_response method
|
106
|
-
# :headers<Hash> - headers send with the request
|
107
|
-
# Anything else will be available via the options attribute reader.
|
108
|
-
#
|
109
|
-
def initialize(url, http_method = :get, options={})
|
110
|
-
@method = http_method.upcase.to_s
|
111
|
-
@delegator = options.delete(:action) || self
|
112
|
-
@payload = options.delete(:payload)
|
113
|
-
@credentials = options.delete(:credentials) || {}
|
114
|
-
@credentials = {:username => '', :password => ''}.merge(@credentials)
|
115
|
-
@timeout = options.delete(:timeout) || 30.0
|
116
|
-
headers = options.delete(:headers)
|
117
|
-
if headers
|
118
|
-
@headers = {}
|
119
|
-
headers.each{|k,v| @headers[k] = v.gsub("\n", '\\n') } # escaping LFs
|
120
|
-
end
|
121
|
-
@cachePolicy = options.delete(:cache_policy) || NSURLRequestUseProtocolCachePolicy
|
122
|
-
@options = options
|
123
|
-
@response = HTTP::Response.new
|
124
|
-
initiate_request(url)
|
125
|
-
connection.start
|
126
|
-
UIApplication.sharedApplication.networkActivityIndicatorVisible = true
|
127
|
-
connection
|
128
|
-
end
|
129
|
-
|
130
|
-
def generate_get_params(payload, prefix=nil)
|
131
|
-
list = []
|
132
|
-
payload.each do |k,v|
|
133
|
-
if v.is_a?(Hash)
|
134
|
-
new_prefix = prefix ? "#{prefix}[#{k.to_s}]" : k.to_s
|
135
|
-
param = generate_get_params(v, new_prefix)
|
136
|
-
else
|
137
|
-
param = prefix ? "#{prefix}[#{k}]=#{v}" : "#{k}=#{v}"
|
138
|
-
end
|
139
|
-
list << param
|
140
|
-
end
|
141
|
-
return list.flatten
|
142
|
-
end
|
143
|
-
|
144
|
-
def initiate_request(url_string)
|
145
|
-
# http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/nsrunloop_Class/Reference/Reference.html#//apple_ref/doc/constant_group/Run_Loop_Modes
|
146
|
-
# NSConnectionReplyMode
|
147
|
-
|
148
|
-
unless @payload.nil?
|
149
|
-
if @payload.is_a?(Hash)
|
150
|
-
params = generate_get_params(@payload)
|
151
|
-
@payload = params.join("&")
|
152
|
-
end
|
153
|
-
url_string = "#{url_string}?#{@payload}" if @method == "GET"
|
154
|
-
end
|
155
|
-
|
156
|
-
p "BubbleWrap::HTTP building a NSRequest for #{url_string}" if SETTINGS[:debug]
|
157
|
-
@url = NSURL.URLWithString(url_string.stringByAddingPercentEscapesUsingEncoding NSUTF8StringEncoding)
|
158
|
-
@request = NSMutableURLRequest.requestWithURL(@url,
|
159
|
-
cachePolicy:@cachePolicy,
|
160
|
-
timeoutInterval:@timeout)
|
161
|
-
@request.setHTTPMethod @method
|
162
|
-
@request.setAllHTTPHeaderFields(@headers) if @headers
|
163
|
-
|
164
|
-
# @payload needs to be converted to data
|
165
|
-
unless @method == "GET" || @payload.nil?
|
166
|
-
@payload = @payload.to_s.dataUsingEncoding(NSUTF8StringEncoding)
|
167
|
-
@request.setHTTPBody @payload
|
168
|
-
end
|
169
|
-
|
170
|
-
# NSHTTPCookieStorage.sharedHTTPCookieStorage
|
171
|
-
|
172
|
-
@connection = create_connection(request, self)
|
173
|
-
@request.instance_variable_set("@done_loading", false)
|
174
|
-
def @request.done_loading; @done_loading; end
|
175
|
-
def @request.done_loading!; @done_loading = true; end
|
176
|
-
end
|
177
|
-
|
178
|
-
def connection(connection, didReceiveResponse:response)
|
179
|
-
@status_code = response.statusCode
|
180
|
-
@response_headers = response.allHeaderFields
|
181
|
-
@response_size = response.expectedContentLength.to_f
|
182
|
-
end
|
183
|
-
|
184
|
-
# This delegate method get called every time a chunk of data is being received
|
185
|
-
def connection(connection, didReceiveData:received_data)
|
186
|
-
@received_data ||= NSMutableData.new
|
187
|
-
@received_data.appendData(received_data)
|
188
|
-
end
|
189
|
-
|
190
|
-
def connection(connection, willSendRequest:request, redirectResponse:redirect_response)
|
191
|
-
p "HTTP redirected #{request.description}" if SETTINGS[:debug]
|
192
|
-
new_request = request.mutableCopy
|
193
|
-
# new_request.setValue(@credentials.inspect, forHTTPHeaderField:'Authorization') # disabled while we figure this one out
|
194
|
-
new_request.setAllHTTPHeaderFields(@headers) if @headers
|
195
|
-
@connection.cancel
|
196
|
-
@connection = create_connection(new_request, self)
|
197
|
-
new_request
|
198
|
-
end
|
199
|
-
|
200
|
-
def connection(connection, didFailWithError: error)
|
201
|
-
UIApplication.sharedApplication.networkActivityIndicatorVisible = false
|
202
|
-
@request.done_loading!
|
203
|
-
NSLog"HTTP Connection failed #{error.localizedDescription}" if SETTINGS[:debug]
|
204
|
-
@response.error_message = error.localizedDescription
|
205
|
-
call_delegator_with_response
|
206
|
-
end
|
207
|
-
|
208
|
-
|
209
|
-
# The transfer is done and everything went well
|
210
|
-
def connectionDidFinishLoading(connection)
|
211
|
-
UIApplication.sharedApplication.networkActivityIndicatorVisible = false
|
212
|
-
@request.done_loading!
|
213
|
-
# copy the data in a local var that we will attach to the response object
|
214
|
-
response_body = NSData.dataWithData(@received_data) if @received_data
|
215
|
-
@response.update(status_code: status_code, body: response_body, headers: response_headers, url: @url)
|
216
|
-
|
217
|
-
call_delegator_with_response
|
218
|
-
end
|
219
|
-
|
220
|
-
def connection(connection, didReceiveAuthenticationChallenge:challenge)
|
221
|
-
|
222
|
-
if (challenge.previousFailureCount == 0)
|
223
|
-
# by default we are keeping the credential for the entire session
|
224
|
-
# Eventually, it would be good to let the user pick one of the 3 possible credential persistence options:
|
225
|
-
# NSURLCredentialPersistenceNone,
|
226
|
-
# NSURLCredentialPersistenceForSession,
|
227
|
-
# NSURLCredentialPersistencePermanent
|
228
|
-
p "auth challenged, answered with credentials: #{credentials.inspect}" if SETTINGS[:debug]
|
229
|
-
new_credential = NSURLCredential.credentialWithUser(credentials[:username], password:credentials[:password], persistence:NSURLCredentialPersistenceForSession)
|
230
|
-
challenge.sender.useCredential(new_credential, forAuthenticationChallenge:challenge)
|
231
|
-
else
|
232
|
-
challenge.sender.cancelAuthenticationChallenge(challenge)
|
233
|
-
p 'Auth Failed :('
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
def call_delegator_with_response
|
238
|
-
if @delegator.respond_to?(:call)
|
239
|
-
@delegator.call( @response, self )
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
# This is a temporary method used for mocking.
|
244
|
-
def create_connection(request, delegate)
|
245
|
-
NSURLConnection.connectionWithRequest(request, delegate:delegate)
|
246
|
-
end
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end
|
1
|
+
require File.expand_path('../loader.rb', __FILE__)
|
2
|
+
BubbleWrap.require('motion/http.rb')
|
@@ -0,0 +1,23 @@
|
|
1
|
+
unless defined?(Motion::Project::Config)
|
2
|
+
raise "This file must be required within a RubyMotion project Rakefile."
|
3
|
+
end
|
4
|
+
|
5
|
+
require File.expand_path('../version', __FILE__) unless defined?(BubbleWrap::VERSION)
|
6
|
+
require File.expand_path('../ext', __FILE__)
|
7
|
+
require File.expand_path('../requirement', __FILE__)
|
8
|
+
|
9
|
+
module BubbleWrap
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
def root
|
14
|
+
File.expand_path('../../../', __FILE__)
|
15
|
+
end
|
16
|
+
|
17
|
+
def require(file_spec, &block)
|
18
|
+
Requirement.scan(caller.first, file_spec, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
BW = BubbleWrap
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.expand_path "../requirement/path_manipulation", __FILE__
|
2
|
+
|
3
|
+
module BubbleWrap
|
4
|
+
class Requirement
|
5
|
+
extend PathManipulation
|
6
|
+
include PathManipulation
|
7
|
+
|
8
|
+
attr_accessor :file, :root
|
9
|
+
attr_writer :file_dependencies
|
10
|
+
|
11
|
+
def initialize(file,root)
|
12
|
+
self.file = file
|
13
|
+
self.root = root
|
14
|
+
end
|
15
|
+
|
16
|
+
def relative
|
17
|
+
convert_to_relative(file, root)
|
18
|
+
end
|
19
|
+
|
20
|
+
def depends_on(file_or_paths)
|
21
|
+
paths = file_or_paths.respond_to?(:each) ? file_or_paths : [ file_or_paths ]
|
22
|
+
self.file_dependencies += paths.map do |f|
|
23
|
+
f = self.class.file(f) unless f.is_a? Requirement
|
24
|
+
f unless f.file == file
|
25
|
+
end.compact
|
26
|
+
self.file_dependencies.uniq!(&:to_s)
|
27
|
+
end
|
28
|
+
|
29
|
+
def uses_framework(framework_name)
|
30
|
+
self.frameworks << framework_name
|
31
|
+
end
|
32
|
+
|
33
|
+
def dependencies
|
34
|
+
return {} if file_dependencies.empty?
|
35
|
+
{ file => file_dependencies.map(&:to_s) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
file
|
40
|
+
end
|
41
|
+
|
42
|
+
def file_dependencies
|
43
|
+
@file_dependencies ||= []
|
44
|
+
end
|
45
|
+
|
46
|
+
def frameworks
|
47
|
+
@frameworks ||= []
|
48
|
+
end
|
49
|
+
|
50
|
+
class << self
|
51
|
+
|
52
|
+
attr_accessor :paths
|
53
|
+
|
54
|
+
def scan(caller_location, file_spec, &block)
|
55
|
+
root = convert_caller_to_root_path caller_location
|
56
|
+
self.paths ||= {}
|
57
|
+
Dir.glob(File.expand_path(file_spec, root)).each do |file|
|
58
|
+
p = new(file,root)
|
59
|
+
self.paths[p.relative] = p
|
60
|
+
end
|
61
|
+
self.class_eval(&block) if block
|
62
|
+
end
|
63
|
+
|
64
|
+
def file(relative)
|
65
|
+
paths.fetch(relative)
|
66
|
+
end
|
67
|
+
|
68
|
+
def files
|
69
|
+
paths.values.map(&:to_s)
|
70
|
+
end
|
71
|
+
|
72
|
+
def files_dependencies
|
73
|
+
deps = {}
|
74
|
+
paths.each_value do |file|
|
75
|
+
deps.merge! file.dependencies
|
76
|
+
end
|
77
|
+
deps
|
78
|
+
end
|
79
|
+
|
80
|
+
def frameworks
|
81
|
+
frameworks = ['UIKit', 'Foundation', 'CoreGraphics'] +
|
82
|
+
paths.values.map(&:frameworks)
|
83
|
+
frameworks.flatten.compact.sort.uniq
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module BubbleWrap
|
2
|
+
class Requirement
|
3
|
+
module PathManipulation
|
4
|
+
|
5
|
+
def convert_caller_to_root_path(path)
|
6
|
+
path = convert_caller_to_path path
|
7
|
+
path = convert_to_absolute_path path
|
8
|
+
strip_up_to_last_lib path
|
9
|
+
end
|
10
|
+
|
11
|
+
def convert_caller_to_path(string)
|
12
|
+
chunks = string.split(':')
|
13
|
+
return chunks[0..-3].join(':') if chunks.size >= 3
|
14
|
+
string
|
15
|
+
end
|
16
|
+
|
17
|
+
def convert_to_absolute_path(path)
|
18
|
+
File.expand_path(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def strip_up_to_last_lib(path)
|
22
|
+
path = path.split('lib')
|
23
|
+
path = if path.size > 1
|
24
|
+
path[0..-2].join('lib')
|
25
|
+
else
|
26
|
+
path[0]
|
27
|
+
end
|
28
|
+
path = path[0..-2] if path[-1] == '/'
|
29
|
+
path
|
30
|
+
end
|
31
|
+
|
32
|
+
def convert_to_relative(path,root)
|
33
|
+
path = path.gsub(root,'')
|
34
|
+
path = path[1..-1] if path[0] == '/'
|
35
|
+
path
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/bubble-wrap/version.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path('../../../../lib/bubble-wrap/requirement/path_manipulation', __FILE__)
|
2
|
+
|
3
|
+
describe BubbleWrap::Requirement::PathManipulation do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
o = Object.new
|
7
|
+
o.extend BubbleWrap::Requirement::PathManipulation
|
8
|
+
o
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#convert_caller_to_path' do
|
12
|
+
it 'strips off from the second-to-last colon' do
|
13
|
+
subject.convert_caller_to_path("/fake/:path:91:in `fake_method'").
|
14
|
+
should == '/fake/:path'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'leaves plain old paths unmolested' do
|
18
|
+
subject.convert_caller_to_path("/fake/path").
|
19
|
+
should == '/fake/path'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#convert_to_absolute_path' do
|
24
|
+
it 'converts relative paths to absolute paths' do
|
25
|
+
subject.convert_to_absolute_path('foo')[0].should == '/'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "doesn't modify absolute paths" do
|
29
|
+
subject.convert_to_absolute_path('/foo').should == '/foo'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#strip_up_to_last_lib' do
|
34
|
+
it 'strips off from the last lib' do
|
35
|
+
subject.strip_up_to_last_lib('/fake/lib/dir/lib/foo').
|
36
|
+
should == '/fake/lib/dir'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "doesn't modify the path otherwise" do
|
40
|
+
subject.strip_up_to_last_lib('/fake/path').
|
41
|
+
should == '/fake/path'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#convert_to_relative" do
|
46
|
+
it 'strips off the root portion' do
|
47
|
+
subject.convert_to_relative('/foo/bar/baz', '/foo').
|
48
|
+
should == 'bar/baz'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|