Skip to content

Commit

Permalink
Add numeric-constraints annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
earlbread committed May 12, 2018
1 parent 814f455 commit fb94472
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 3 deletions.
23 changes: 21 additions & 2 deletions src/Nirum/Targets/Python.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module Nirum.Targets.Python

import Control.Monad (forM)
import qualified Data.List as L
import Data.Maybe (catMaybes, fromMaybe)
import Data.Maybe (catMaybes, fromMaybe, isJust)
import GHC.Exts (IsList (toList))
import Text.Printf (printf)

Expand Down Expand Up @@ -462,13 +462,32 @@ compileTypeDeclaration src d@TypeDeclaration { typename = typename'
|]
compileTypeDeclaration src d@TypeDeclaration { typename = typename'
, type' = UnboxedType itype
, typeAnnotations = annots
} = do
let className = toClassName' typename'
itypeExpr <- compileTypeExpression' src (Just itype)
insertStandardImport "typing"
insertThirdPartyImports [("nirum.deserialize", ["deserialize_meta"])]
pyVer <- getPythonVersion
Validator typePred valueValidators' <- compileValidator' src itype "value"
Validator typePred valueValidatorsProto <-
compileValidator' src itype "value"
valueValidators' <- case A.lookup "numeric-constraints" annots of
Just A.Annotation { A.arguments = args } -> do
let constraintValidators =
[ case name' of
"min" -> Just $ ValueValidator
[qq|value >= ($value)|]
[qq|value is less than $value|]
"max" -> Just $ ValueValidator
[qq|value <= ($value)|]
[qq|value is greater than $value|]
_ -> Nothing
| (name', value) <- toList args
]
if all isJust constraintValidators
then return $ catMaybes constraintValidators
else fail "Unsupported arguments on @numeric-constraints"
Nothing -> return valueValidatorsProto
return $ toStrict $ renderMarkup $ [compileText|
class #{className}(object):
#{compileDocstring " " d}
Expand Down
15 changes: 15 additions & 0 deletions test/Nirum/Targets/PythonSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import System.FilePath ((</>))
import Test.Hspec.Meta
import Text.InterpolatedString.Perl6 (q)

import qualified Nirum.Constructs.Annotation as A
import Nirum.Constructs.Module (Module (Module))
import Nirum.Constructs.Name (Name (Name))
import Nirum.Constructs.TypeDeclaration
import Nirum.Package.Metadata (Target (compilePackage))
import Nirum.Targets.Python
( Source (Source)
Expand Down Expand Up @@ -169,3 +171,16 @@ spec = do
parseModulePath "foo..bar" `shouldBe` Nothing
parseModulePath "foo.bar>" `shouldBe` Nothing
parseModulePath "foo.bar-" `shouldBe` Nothing

describe "@numeric-constraints" $
it "fails if unsupported arguments are present" $ do
let Right annots = A.fromList
[ A.Annotation "numeric-constraints"
[("min", "1"), ("unsupported", "asdf")]
]
let unboxed = TypeDeclaration "foo" (UnboxedType "int32") annots
let (Source pkg _) = makeDummySource $ Module [unboxed] Nothing
let files = compilePackage pkg
let result = M.lookup ("src" </> "foo" </> "__init__.py") files
result `shouldBe`
Just (Left "Unsupported arguments on @numeric-constraints")
2 changes: 2 additions & 0 deletions test/nirum_fixture/fixture/constraints.nrm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@numeric-constraints(min="1", max="12")
unboxed month (int32);
16 changes: 16 additions & 0 deletions test/python/constraints_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-

from pytest import raises

from fixture.constraints import Month


def test_numeric_constraints():
month = Month(1)
assert month.value == 1

with raises(ValueError):
Month(0)

with raises(ValueError):
Month(13)
3 changes: 2 additions & 1 deletion test/python/setup_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_setup_metadata():
assert set(pkg['Provides']) == {
'fixture', 'fixture.foo', 'fixture.foo.bar', 'fixture.qux',
'fixture.reserved_keyword_enum', 'fixture.reserved_keyword_union',
'fixture.types', 'fixture.alias',
'fixture.types', 'fixture.alias', 'fixture.constraints',
'renamed', 'renamed.foo', 'renamed.foo.bar',
}
assert ['0.3.0'] == pkg['Version']
Expand All @@ -43,6 +43,7 @@ def test_module_entry_points():
'fixture.reserved-keyword-enum', 'fixture.reserved-keyword-union',
'fixture.types',
'fixture.alias',
'fixture.constraints',
'renames.test.foo', 'renames.test.foo.bar',
}
import fixture.foo
Expand Down

0 comments on commit fb94472

Please sign in to comment.