diff --git a/spec/DomainLanguageSpec.hs b/spec/DomainLanguageSpec.hs index dc6273424..2038e5406 100644 --- a/spec/DomainLanguageSpec.hs +++ b/spec/DomainLanguageSpec.hs @@ -2,6 +2,7 @@ module DomainLanguageSpec (spec) where import Test.Hspec import Language.Mulang.Ast +import Language.Mulang.Inspector.Combiner (detect) import Language.Mulang.DomainLanguage (DomainLanguage(..), hasMisspelledIdentifiers, hasTooShortIdentifiers, hasWrongCaseIdentifiers) import Language.Mulang.Parsers.Haskell (hs) import Language.Mulang.Parsers.JavaScript (js) @@ -16,6 +17,7 @@ spec = do describe "hasTooShortIdentifiers" $ do let run = hasTooShortIdentifiers language + let runDetection = detect (hasTooShortIdentifiers language) it "is True when it is a one-char identifier" $ do run (hs "x = True") `shouldBe` True @@ -32,23 +34,35 @@ spec = do it "is False when it contains a short parameter name" $ do run (hs "aFunction a = a") `shouldBe` False - it "is True when it contains a short local variable name" $ do - run (js "function foo() { var x = 1; return x }") `shouldBe` True + it "is False when it contains a short local variable name, but it is detected" $ do + let sample = js "function foo() { var x = 1; return x }" + + run sample `shouldBe` False + runDetection sample `shouldBe` ["x"] it "is False when it uses a short named function" $ do run (hs "aFunction aNumber = f aNumber") `shouldBe` False - it "is False when it contains a short local variable name in a method" $ do - run (js "var pepita = {come:function(){var x = 1; }, vola:function(){}};") `shouldBe` True + it "is False when it contains a short local variable name in a method, but it is detected" $ do + let sample = js "var pepita = {come:function(){var x = 1; }, vola:function(){}};" + + runDetection sample `shouldBe` ["x"] + run sample `shouldBe` False it "is False when it contains a short local parameter name in a method" $ do run (js "var pepita = {come:function(x){ }, vola:function(){}};") `shouldBe` False - it "is True when it contains a short named method" $ do - run (js "var pepita = {x:function(){}, vola:function(){}};") `shouldBe` True + it "is False when it contains a short named method, but it is detected" $ do + let sample = js "var pepita = {x:function(){}, vola:function(){}};" + + runDetection sample `shouldBe` ["x"] + run sample `shouldBe` False it "is True when it contains a short named attribute" $ do - run (js "var pepita = {x: 2, vola:function(){}};") `shouldBe` True + let sample = js "var pepita = {x: 2, vola:function(){}};" + + runDetection sample `shouldBe` ["x"] + run sample `shouldBe` False it "is True when it contains a short variable name" $ do run (js "var x = 3;") `shouldBe` True diff --git a/spec/SmellsAnalyzerSpec.hs b/spec/SmellsAnalyzerSpec.hs index 36eb93793..493d80168 100644 --- a/spec/SmellsAnalyzerSpec.hs +++ b/spec/SmellsAnalyzerSpec.hs @@ -1,6 +1,7 @@ module SmellsAnalyzerSpec(spec) where import Language.Mulang.Analyzer hiding (result, spec) +import Language.Mulang.Ast import Test.Hspec result smellResults = AnalysisCompleted [] smellResults [] @@ -9,6 +10,21 @@ runExcept language content smells = analyse (smellsAnalysis (CodeSample language runOnly language content smells = analyse (smellsAnalysis (CodeSample language content) noSmells { include = Just smells }) spec = describe "SmellsAnalyzer" $ do + describe "Using domain language and nested structures" $ do + let runRuby sample = analyse (domainLanguageAnalysis (MulangSample sample) (DomainLanguage Nothing (Just RubyCase) (Just 3) Nothing)) + it "works with empty set" $ do + (runRuby (Sequence [ + (Object "Foo_Bar" (Sequence [ + (SimpleMethod "y" [] MuNull), + (SimpleMethod "aB" [] MuNull), + (SimpleMethod "fooBar" [] MuNull)])), + (Object "Foo" MuNull)])) `shouldReturn` (result [ + Expectation "y" "HasTooShortIdentifiers", + Expectation "aB" "HasTooShortIdentifiers", + Expectation "Foo_Bar" "HasWrongCaseIdentifiers", + Expectation "aB" "HasWrongCaseIdentifiers", + Expectation "fooBar" "HasWrongCaseIdentifiers"]) + describe "Using exclusion" $ do it "works with empty set" $ do (runExcept Haskell "fun x = if x then True else False" []) `shouldReturn` (result [Expectation "fun" "HasRedundantIf"]) diff --git a/src/Language/Mulang/Analyzer.hs b/src/Language/Mulang/Analyzer.hs index b0740cedc..86ef78764 100644 --- a/src/Language/Mulang/Analyzer.hs +++ b/src/Language/Mulang/Analyzer.hs @@ -6,6 +6,7 @@ module Language.Mulang.Analyzer ( emptyAnalysisSpec, emptyAnalysis, + domainLanguageAnalysis, expectationsAnalysis, smellsAnalysis, signaturesAnalysis, @@ -37,6 +38,9 @@ emptyAnalysisSpec = AnalysisSpec [] noSmells Nothing Nothing emptyAnalysis :: Sample -> Analysis emptyAnalysis code = Analysis code emptyAnalysisSpec +domainLanguageAnalysis :: Sample -> DomainLanguage -> Analysis +domainLanguageAnalysis code domainLanguage = Analysis code (emptyAnalysisSpec { domainLanguage = Just domainLanguage, smellsSet = allSmells }) + expectationsAnalysis :: Sample -> [Expectation] -> Analysis expectationsAnalysis code es = Analysis code (emptyAnalysisSpec { expectations = es }) diff --git a/src/Language/Mulang/DomainLanguage.hs b/src/Language/Mulang/DomainLanguage.hs index 65cc26f31..e3d05dd70 100644 --- a/src/Language/Mulang/DomainLanguage.hs +++ b/src/Language/Mulang/DomainLanguage.hs @@ -6,7 +6,7 @@ module Language.Mulang.DomainLanguage ( import Language.Mulang.Inspector (Inspection) import Language.Mulang.Ast (Expression) -import Language.Mulang.Generator (declaredIdentifiers) +import Language.Mulang.Generator (mainDeclaredIdentifiers) import Text.Dictionary (Dictionary, exists) @@ -22,7 +22,7 @@ data DomainLanguage = DomainLanguage { type DomainLanguageInspection = DomainLanguage -> Inspection hasTooShortIdentifiers :: DomainLanguageInspection -hasTooShortIdentifiers language = any isShort . declaredIdentifiers +hasTooShortIdentifiers language = any isShort . mainDeclaredIdentifiers where isShort identifier = length identifier < (minimumIdentifierSize language) && notJargonOf identifier language hasMisspelledIdentifiers :: DomainLanguageInspection @@ -32,10 +32,10 @@ hasMisspelledIdentifiers language = any isMisspelled . wordsOf language hasWrongCaseIdentifiers :: DomainLanguageInspection hasWrongCaseIdentifiers (DomainLanguage _ style _ _) - = any (not . canTokenize style) . declaredIdentifiers + = any (not . canTokenize style) . mainDeclaredIdentifiers wordsOf :: DomainLanguage -> Expression -> [String] -wordsOf (DomainLanguage _ style _ _) = concatMap (tokenize style) . declaredIdentifiers +wordsOf (DomainLanguage _ style _ _) = concatMap (tokenize style) . mainDeclaredIdentifiers emptyDictionary = null . dictionary diff --git a/src/Language/Mulang/Generator.hs b/src/Language/Mulang/Generator.hs index d88a23ef1..dc5e2409d 100644 --- a/src/Language/Mulang/Generator.hs +++ b/src/Language/Mulang/Generator.hs @@ -3,6 +3,7 @@ module Language.Mulang.Generator ( declarations, declarationsOf, declaredIdentifiers, + mainDeclaredIdentifiers, equationBodies, expressions, referencedIdentifiers, @@ -100,6 +101,10 @@ transitiveReferencedIdentifiers identifier code = expand (concatMap referencedI declaredIdentifiers :: Generator Identifier declaredIdentifiers = map fst . declarations +mainDeclaredIdentifiers :: Generator Identifier +mainDeclaredIdentifiers (Sequence _) = [] +mainDeclaredIdentifiers expression = take 1 . declaredIdentifiers $ expression + -- | Returns all the body equations of functions, procedures and methods equationBodies :: Generator EquationBody equationBodies = concatMap (bodiesOf . snd) . declarations