Implemented url_in, url_is and corresponding tests

Change-Id: I11f8b97715add1590e0d80a7865a1f3511a04750
diff --git a/rsync_url.py b/rsync_url.py
index 49b6a32..968a627 100644
--- a/rsync_url.py
+++ b/rsync_url.py
@@ -1,6 +1,8 @@
 #-*- coding: utf-8 -*-
 
+import os
 import re
+
 import utils
 
 
@@ -150,6 +152,28 @@
                 return False
         return True
 
+    def _url_join(self, *suburls):
+        url = self.url
+        if len(url) > 1:
+            while url.endswith(os.path.sep):
+                url = url[:-1]
+
+        subs = os.path.sep.join(suburls).split(os.path.sep)
+        subs = [_ for _ in subs if _]
+
+        result = re.sub(r'^//', r'/', os.path.sep.join([url, ] + subs))
+        result = re.sub(r'([^:])//', r'\1/', result)
+        return result
+
     @property
     def url(self):
         return self._url
+
+    def url_in(self, *path):
+        result = self._url_join(*path)
+        if not result.endswith('/'):
+            result += '/'
+        return result
+
+    def url_is(self, *path):
+        return self._url_join(*path)
diff --git a/test_rsync_url.py b/test_rsync_url.py
index 11727f4..19c73a8 100644
--- a/test_rsync_url.py
+++ b/test_rsync_url.py
@@ -62,6 +62,20 @@
         self.log_locals(url)
         self.assertEqual(url.url, expected_result)
 
+    def url_in(self, remote, expected_result):
+        logger.info('"{}" - {}'.format(remote, expected_result))
+        url = rsync_url.RsyncUrl(remote)
+        self.log_locals(url)
+        for par, er in expected_result.items():
+            self.assertEqual(url.url_in(par), er)
+
+    def url_is(self, remote, expected_result):
+        logger.info('"{}" - {}'.format(remote, expected_result))
+        url = rsync_url.RsyncUrl(remote)
+        self.log_locals(url)
+        for par, er in expected_result.items():
+            self.assertEqual(url.url_is(par), er)
+
 testdata = yaml.load(open('test_rsync_url.yaml'))
 
 index = 1
diff --git a/test_rsync_url.yaml b/test_rsync_url.yaml
index eda964e..8e205c2 100644
--- a/test_rsync_url.yaml
+++ b/test_rsync_url.yaml
@@ -7,6 +7,16 @@
 #     - results
 'ubuntu@172.18.66.89:~':
   url: 'ubuntu@172.18.66.89:~'
+  url_in:
+    '': 'ubuntu@172.18.66.89:~/'
+    '/': 'ubuntu@172.18.66.89:~/'
+    '/first/level/': 'ubuntu@172.18.66.89:~/first/level/'
+    'first/level': 'ubuntu@172.18.66.89:~/first/level/'
+  url_is:
+    '': 'ubuntu@172.18.66.89:~'
+    '/': 'ubuntu@172.18.66.89:~'
+    '/first/level/': 'ubuntu@172.18.66.89:~/first/level'
+    'first/level': 'ubuntu@172.18.66.89:~/first/level'
   exact_match_num: 1
   classed: 'ssh'
   parsed:
@@ -52,6 +62,16 @@
   valid: True
 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp':
   url: 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp'
+  url_in:
+    '': 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp/'
+    '/': 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp/'
+    '/first/level/': 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp/first/level/'
+    'first/level': 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp/first/level/'
+  url_is:
+    '': 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp'
+    '/': 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp'
+    '/first/level/': 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp/first/level'
+    'first/level': 'johnivanov@172.18.66.89::mirror-sync/otlichniy/reg/exp/first/level'
   exact_match_num: 1
   classed: 'rsync1'
   parsed_rsync:
@@ -104,6 +124,16 @@
   #valid: False
 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp':
   url: 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp'
+  url_in:
+    '': 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp/'
+    '/': 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp/'
+    '/first/level/': 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp/first/level/'
+    'first/level': 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp/first/level/'
+  url_is:
+    '': 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp'
+    '/': 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp'
+    '/first/level/': 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp/first/level'
+    'first/level': 'rsync://mirror-sync@172.18.66.89:7327/otlichniy/reg/exp/first/level'
   exact_match_num: 1
   classed: 'rsync2'
   parsed_rsync:
@@ -159,6 +189,16 @@
   valid: False
 '/':
   url: '/'
+  url_in:
+    '': '/'
+    '/': '/'
+    '/first/level/': '/first/level/'
+    'first/level': '/first/level/'
+  url_is:
+    '': '/'
+    '/': '/'
+    '/first/level/': '/first/level'
+    'first/level': '/first/level'
   exact_match_num: 1
   classed: 'path'
   parsed: