Robot Framework Integrated Development Environment (RIDE)
String.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from __future__ import absolute_import
17 
18 import os
19 import re
20 from fnmatch import fnmatchcase
21 from random import randint
22 from string import ascii_lowercase, ascii_uppercase, digits
23 
24 
25 from robotide.lib.robot.api import logger
26 from robotide.lib.robot.utils import (is_bytes, is_string, is_truthy, is_unicode, lower,
27  unic, Utf8Reader, PY3)
28 from robotide.lib.robot.version import get_version
29 
30 
31 
51 class String():
52  ROBOT_LIBRARY_SCOPE = 'GLOBAL'
53  ROBOT_LIBRARY_VERSION = get_version()
54 
55 
63  def convert_to_lowercase(self, string):
64  # Custom `lower` needed due to IronPython bug. See its code and
65  # comments for more details.
66  return lower(string)
67 
68 
76  def convert_to_uppercase(self, string):
77  return string.upper()
78 
79 
99  def encode_string_to_bytes(self, string, encoding, errors='strict'):
100  return bytes(string.encode(encoding, errors))
101 
102 
121  def decode_bytes_to_string(self, bytes, encoding, errors='strict'):
122  if PY3 and is_unicode(bytes):
123  raise TypeError('Can not decode strings on Python 3.')
124  return bytes.decode(encoding, errors)
125 
126 
149  def format_string(self, template, *positional, **named):
150  if os.path.isabs(template) and os.path.isfile(template):
151  template = template.replace('/', os.sep)
152  logger.info('Reading template from file <a href="%s">%s</a>.'
153  % (template, template), html=True)
154  with Utf8Reader(template) as reader:
155  template = reader.read()
156  return template.format(*positional, **named)
157 
158 
159  def get_line_count(self, string):
160  count = len(string.splitlines())
161  logger.info('%d lines' % count)
162  return count
163 
164 
184  def split_to_lines(self, string, start=0, end=None):
185  start = self._convert_to_index_convert_to_index(start, 'start')
186  end = self._convert_to_index_convert_to_index(end, 'end')
187  lines = string.splitlines()[start:end]
188  logger.info('%d lines returned' % len(lines))
189  return lines
190 
191 
203  def get_line(self, string, line_number):
204  line_number = self._convert_to_integer_convert_to_integer(line_number, 'line_number')
205  return string.splitlines()[line_number]
206 
207 
230  def get_lines_containing_string(self, string, pattern, case_insensitive=False):
231  if is_truthy(case_insensitive):
232  pattern = pattern.lower()
233  contains = lambda line: pattern in line.lower()
234  else:
235  contains = lambda line: pattern in line
236  return self._get_matching_lines_get_matching_lines(string, contains)
237 
238 
266  def get_lines_matching_pattern(self, string, pattern, case_insensitive=False):
267  if is_truthy(case_insensitive):
268  pattern = pattern.lower()
269  matches = lambda line: fnmatchcase(line.lower(), pattern)
270  else:
271  matches = lambda line: fnmatchcase(line, pattern)
272  return self._get_matching_lines_get_matching_lines(string, matches)
273 
274 
309  def get_lines_matching_regexp(self, string, pattern, partial_match=False):
310  if not is_truthy(partial_match):
311  pattern = '^%s$' % pattern
312  return self._get_matching_lines_get_matching_lines(string, re.compile(pattern).search)
313 
314  def _get_matching_lines(self, string, matches):
315  lines = string.splitlines()
316  matching = [line for line in lines if matches(line)]
317  logger.info('%d out of %d lines matched' % (len(matching), len(lines)))
318  return '\n'.join(matching)
319 
320 
348  def get_regexp_matches(self, string, pattern, *groups):
349  regexp = re.compile(pattern)
350  groups = [self._parse_group_parse_group(g) for g in groups]
351  return [m.group(*groups) for m in regexp.finditer(string)]
352 
353  def _parse_group(self, group):
354  try:
355  return int(group)
356  except ValueError:
357  return group
358 
359 
379  def replace_string(self, string, search_for, replace_with, count=-1):
380  count = self._convert_to_integer_convert_to_integer(count, 'count')
381  return string.replace(search_for, replace_with, count)
382 
383 
397  def replace_string_using_regexp(self, string, pattern, replace_with, count=-1):
398  count = self._convert_to_integer_convert_to_integer(count, 'count')
399  # re.sub handles 0 and negative counts differently than string.replace
400  if count == 0:
401  return string
402  return re.sub(pattern, replace_with, string, max(count, 0))
403 
404 
423  def remove_string(self, string, *removables):
424  for removable in removables:
425  string = self.replace_stringreplace_string(string, removable, '')
426  return string
427 
428 
437  def remove_string_using_regexp(self, string, *patterns):
438  for pattern in patterns:
439  string = self.replace_string_using_regexpreplace_string_using_regexp(string, pattern, '')
440  return string
441 
442 
461  def split_string(self, string, separator=None, max_split=-1):
462  if separator == '':
463  separator = None
464  max_split = self._convert_to_integer_convert_to_integer(max_split, 'max_split')
465  return string.split(separator, max_split)
466 
467 
476  def split_string_from_right(self, string, separator=None, max_split=-1):
477  if separator == '':
478  separator = None
479  max_split = self._convert_to_integer_convert_to_integer(max_split, 'max_split')
480  return string.rsplit(separator, max_split)
481 
482 
487  def split_string_to_characters(self, string):
488  return list(string)
489 
490 
497  def fetch_from_left(self, string, marker):
498  return string.split(marker)[0]
499 
500 
507  def fetch_from_right(self, string, marker):
508  return string.split(marker)[-1]
509 
510 
529  def generate_random_string(self, length=8, chars='[LETTERS][NUMBERS]'):
530  if length == '':
531  length = 8
532  length = self._convert_to_integer_convert_to_integer(length, 'length')
533  for name, value in [('[LOWER]', ascii_lowercase),
534  ('[UPPER]', ascii_uppercase),
535  ('[LETTERS]', ascii_lowercase + ascii_uppercase),
536  ('[NUMBERS]', digits)]:
537  chars = chars.replace(name, value)
538  maxi = len(chars) - 1
539  return ''.join(chars[randint(0, maxi)] for _ in range(length))
540 
541 
554  def get_substring(self, string, start, end=None):
555  start = self._convert_to_index_convert_to_index(start, 'start')
556  end = self._convert_to_index_convert_to_index(end, 'end')
557  return string[start:end]
558 
559 
581  def strip_string(self, string, mode='both', characters=None):
582  try:
583  method = {'BOTH': string.strip,
584  'LEFT': string.lstrip,
585  'RIGHT': string.rstrip,
586  'NONE': lambda characters: string}[mode.upper()]
587  except KeyError:
588  raise ValueError("Invalid mode '%s'." % mode)
589  return method(characters)
590 
591 
608  def should_be_string(self, item, msg=None):
609  if not is_string(item):
610  self._fail_fail(msg, "'%s' is not a string.", item)
611 
612 
620  def should_not_be_string(self, item, msg=None):
621  if is_string(item):
622  self._fail_fail(msg, "'%s' is a string.", item)
623 
624 
634  def should_be_unicode_string(self, item, msg=None):
635  if not is_unicode(item):
636  self._fail_fail(msg, "'%s' is not a Unicode string.", item)
637 
638 
648  def should_be_byte_string(self, item, msg=None):
649  if not is_bytes(item):
650  self._fail_fail(msg, "'%s' is not a byte string.", item)
651 
652 
662  def should_be_lowercase(self, string, msg=None):
663  if not string.islower():
664  self._fail_fail(msg, "'%s' is not lowercase.", string)
665 
666 
676  def should_be_uppercase(self, string, msg=None):
677  if not string.isupper():
678  self._fail_fail(msg, "'%s' is not uppercase.", string)
679 
680 
694  def should_be_titlecase(self, string, msg=None):
695  if not string.istitle():
696  self._fail_fail(msg, "'%s' is not titlecase.", string)
697 
698  def _convert_to_index(self, value, name):
699  if value == '':
700  return 0
701  if value is None:
702  return None
703  return self._convert_to_integer_convert_to_integer(value, name)
704 
705  def _convert_to_integer(self, value, name):
706  try:
707  return int(value)
708  except ValueError:
709  raise ValueError("Cannot convert '%s' argument '%s' to an integer."
710  % (name, value))
711 
712  def _fail(self, message, default_template, *items):
713  if not message:
714  message = default_template % tuple(unic(item) for item in items)
715  raise AssertionError(message)
A test library for string manipulation and verification.
Definition: String.py:51
def get_lines_matching_regexp(self, string, pattern, partial_match=False)
Returns lines of the given string that match the regexp pattern.
Definition: String.py:309
def get_regexp_matches(self, string, pattern, *groups)
Returns a list of all non-overlapping matches in the given string.
Definition: String.py:348
def get_lines_matching_pattern(self, string, pattern, case_insensitive=False)
Returns lines of the given string that match the pattern.
Definition: String.py:266
def format_string(self, template, *positional, **named)
Formats a template using the given positional and named arguments.
Definition: String.py:149
def split_string_from_right(self, string, separator=None, max_split=-1)
Splits the string using separator starting from right.
Definition: String.py:476
def generate_random_string(self, length=8, chars='[LETTERS][NUMBERS]')
Generates a string with a desired length from the given chars.
Definition: String.py:529
def split_string(self, string, separator=None, max_split=-1)
Splits the string using separator as a delimiter string.
Definition: String.py:461
def should_be_titlecase(self, string, msg=None)
Fails if given string is not title.
Definition: String.py:694
def remove_string_using_regexp(self, string, *patterns)
Removes patterns from the given string.
Definition: String.py:437
def replace_string_using_regexp(self, string, pattern, replace_with, count=-1)
Replaces pattern in the given string with replace_with.
Definition: String.py:397
def get_line(self, string, line_number)
Returns the specified line from the given string.
Definition: String.py:203
def split_to_lines(self, string, start=0, end=None)
Splits the given string to lines.
Definition: String.py:184
def get_lines_containing_string(self, string, pattern, case_insensitive=False)
Returns lines of the given string that contain the pattern.
Definition: String.py:230
def should_be_unicode_string(self, item, msg=None)
Fails if the given item is not a Unicode string.
Definition: String.py:634
def should_be_string(self, item, msg=None)
Fails if the given item is not a string.
Definition: String.py:608
def should_not_be_string(self, item, msg=None)
Fails if the given item is a string.
Definition: String.py:620
def split_string_to_characters(self, string)
Splits the given string to characters.
Definition: String.py:487
def get_line_count(self, string)
Returns and logs the number of lines in the given string.
Definition: String.py:159
def replace_string(self, string, search_for, replace_with, count=-1)
Replaces search_for in the given string with replace_with.
Definition: String.py:379
def convert_to_lowercase(self, string)
Converts string to lowercase.
Definition: String.py:63
def _get_matching_lines(self, string, matches)
Definition: String.py:314
def should_be_lowercase(self, string, msg=None)
Fails if the given string is not in lowercase.
Definition: String.py:662
def strip_string(self, string, mode='both', characters=None)
Remove leading and/or trailing whitespaces from the given string.
Definition: String.py:581
def should_be_byte_string(self, item, msg=None)
Fails if the given item is not a byte string.
Definition: String.py:648
def encode_string_to_bytes(self, string, encoding, errors='strict')
Encodes the given Unicode string to bytes using the given encoding.
Definition: String.py:99
def convert_to_uppercase(self, string)
Converts string to uppercase.
Definition: String.py:76
def _convert_to_integer(self, value, name)
Definition: String.py:705
def get_substring(self, string, start, end=None)
Returns a substring from start index to end index.
Definition: String.py:554
def should_be_uppercase(self, string, msg=None)
Fails if the given string is not in uppercase.
Definition: String.py:676
def remove_string(self, string, *removables)
Removes all removables from the given string.
Definition: String.py:423
def fetch_from_right(self, string, marker)
Returns contents of the string after the last occurrence of marker.
Definition: String.py:507
def fetch_from_left(self, string, marker)
Returns contents of the string before the first occurrence of marker.
Definition: String.py:497
def _convert_to_index(self, value, name)
Definition: String.py:698
def _fail(self, message, default_template, *items)
Definition: String.py:712
def decode_bytes_to_string(self, bytes, encoding, errors='strict')
Decodes the given bytes to a Unicode string using the given encoding.
Definition: String.py:121
def is_truthy(item)
Returns True or False depending is the item considered true or not.
Definition: robottypes.py:49
def get_version(naked=False)
Definition: version.py:24