Skip to content

Commit

Permalink
fix command bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiommendes committed Mar 26, 2017
1 parent d1030bd commit 2139348
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 82 deletions.
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
0.3.13
0.3.16
8 changes: 7 additions & 1 deletion pytest.ini
@@ -1,2 +1,8 @@
[pytest]
#addopts = --doctest-modules
env =
PYTHONPATH=src/:$PYTHONPATH
norecursedirs =
.tox
testpaths =
src/iospec
addopts = -p no:django --maxfail=2
2 changes: 1 addition & 1 deletion src/iospec/__meta__.py
@@ -1,3 +1,3 @@
# Automatically created. Please do not edit.
__version__ = u'0.3.13'
__version__ = u'0.3.16'
__author__ = u'F\xe1bio Mac\xeado Mendes'
42 changes: 22 additions & 20 deletions src/iospec/commands/all.py
@@ -1,4 +1,5 @@
import random as _random
import math as _math

from iospec.commands import base
from iospec.commands.utils import iscommand, parse_number as _parse_number
Expand Down Expand Up @@ -74,17 +75,14 @@ class Email(base.FakerString):
"""
A random e-mail.
$e-mail --> random string with a plausible e-mail.
$e-mail(xx) --> e-mail is truncated to have at most xx characters.
$email --> random string with a plausible e-mail.
$email(xx) --> e-mail is truncated to have at most xx characters.
Names generated with this function do not have any spaces.
"""

def fake(self):
name = ' '
while ' ' not in name:
name = _fake.email()
return name
return _fake.email()


@iscommand
Expand Down Expand Up @@ -155,12 +153,18 @@ def parse(self, attr):
'add_provider', 'format', 'get_formatter', 'get_providers' 'parse',
'provider', 'providers', 'set_formatter',
]
if attr.startswith('_') or attr not in dir(_fake) or attr in blacklist:
try:
getattr(_fake, attr)
except AttributeError:
blacklist.append(attr)

if attr.startswith('_') or attr in blacklist:
raise SyntaxError('invalid fake method: %s' % attr)
self.faker = attr

def generate(self):
return getattr(_fake, self.faker)()
faker = getattr(_fake, self.faker)
return faker()


@iscommand
Expand All @@ -170,18 +174,9 @@ class Int(base.NumericBase):
generate different intervals
$int --> any random integer
$int(+) --> positive random value (zero inclusive)
$int(-) --> negative value (zero inclusive)
$int(++) --> positive value (do not include zero)
$int(--) --> negative value (do not include zero)
$int(+a) --> positive values up to "a" (include zero)
$int(a) --> positive values up to "a" (include zero)
$int(-a) --> negative values up to "a" (include zero)
$int(++a) --> positive values up to "a" (do not include zero)
$int(--a) --> negative values up to "a" (do not include zero)
$int(a) --> symmetric interval (-a, a)
$int(a,b) --> interval (a, b) (inclusive)
$int(a..b) --> same as before
$int(a:b) --> interval a to b - 1. Like a Python range.
"""

def parse(self, arg):
Expand All @@ -204,8 +199,15 @@ def parse(self, arg):
minvalue=-2 ** 50, maxvalue=2 ** 50))

def generate(self):
return _random.uniform(self.start, self.stop)

number = _random.uniform(self.start, self.stop)
if _random.random() <= 0.25:
return float(_math.trunc(number))
else:
st = list(str(number))
if len(st) >= 6:
st[5:] = ['0' if x != '.' else '.' for x in st[5:]]
return float(''.join(st))
return round(number, 2)

@iscommand
class Digit(base.NoArgCommand):
Expand Down
83 changes: 31 additions & 52 deletions src/iospec/commands/utils.py
Expand Up @@ -3,6 +3,17 @@
COMMANDS_NAMESPACE = {}


def number(x):
"""
Convert string to number.
"""

try:
return int(x)
except ValueError:
return float(x)


def iscommand(cls):
"""
Register Command subclasses into the COMMANDS dict.
Expand All @@ -14,69 +25,37 @@ def iscommand(cls):
return cls


def parse_number(arg, number_class, minvalue=-2 ** 31, maxvalue=2 ** 31 - 1):
def parse_number(arg, number_class, minvalue=-1000000, maxvalue=1000000):
"""
Parse a string of text that represents a valid numeric range.
The syntax is:
==> (minvalue, maxvalue)
+ ==> (0, maxvalue)
- ==> (minvalue, 0)
++ ==> (1, maxvalue)
-- ==> (minvalue, -1)
+a ==> (0, a)
a ==> (0, a)
-a ==> (-a, 0)
a ==> (-a, a)
a..b ==> (a, b)
a,b ==> (a, b)
a:b ==> (a, b-1)
"""

arg = (arg or '').strip()

try:
if not arg:
pass
elif arg == '+':
minvalue = 0
elif arg == '-':
maxvalue = 0
elif arg == '++':
minvalue = 1
elif arg == '--':
maxvalue = -1
elif arg.startswith('-'):
maxvalue = 0
minvalue = -number_class(arg[1:])
elif arg.startswith('+'):
minvalue = 0
maxvalue = number_class(arg[1:])
elif arg.startswith('--'):
maxvalue = -1
minvalue = -number_class(arg[2:])
elif arg.startswith('++'):
minvalue = 1
maxvalue = number_class(arg[2:])

elif '..' in arg:
min, _, max = arg.partition('..')
minvalue = number_class(min)
maxvalue = number_class(max)
elif ':' in arg:
min, _, max = arg.partition(':')
minvalue = number_class(min)
maxvalue = number_class(max) - 1
elif ',' in arg:
min, _, max = arg.partition(',')
minvalue = number_class(min)
maxvalue = number_class(max)
else:
maxvalue = number_class(arg)
minvalue = -maxvalue
except ValueError:
raise SyntaxError('invalid interval specification: %s' % arg)

return (minvalue, maxvalue)
# Empty argument
if not arg:
return (minvalue, maxvalue)

# Interval
if ',' in arg:
x, y = arg.split(',')
x, y = number(x), number(y)
if x > y:
raise ValueError('first argument is greater then second')
return x, y

# Number
value = number(arg)
if value >= 0:
return 0, value
else:
return value, 0


def wrapped_command(cmd):
Expand Down
9 changes: 2 additions & 7 deletions src/iospec/tests/test_commands.py
Expand Up @@ -19,15 +19,10 @@ def test_parse_number():
func = lambda x: parse_number(x, int, -128, 127)

assert func('') == (-128, 127)
assert func('+') == (0, 127)
assert func('-') == (-128, 0)
assert func('++') == (1, 127)
assert func('--') == (-128, -1)
assert func('+10') == (0, 10)
assert func('-10') == (-10, 0)
assert func('10') == (-10, 10)
assert func('10..20') == (10, 20)
assert func('10:20') == (10, 19)
assert func('10') == (0, 10)
assert func('10,20') == (10, 20)


def test_integers():
Expand Down

0 comments on commit 2139348

Please sign in to comment.