2014-02-16 5 views
2

구문 분석기가 문자열을 허용 할 수 있는지 여부를 검사하는 matcher를 정의하려고합니다. 나는 그랬지만 기분이 좋지 않았다.unittest에 대한 "accept"및 "notAccept"정규 표현식을 정의하는 더 나은 방법

다트 유닛 테스트 코드 :

library test_parser; 

import 'package:unittest/unittest.dart'; 
import '../lib/shark_parser.dart'; 

main() { 
    SharkParser parser; 
    setUp(() { 
    parser = new SharkParser(); 
    }); 
    tearDown(() { 
    parser = null; 
    }); 

    group("paramType parser",() { 
    test("should accept valid types",() { 
     expect(parser.paramType(), accept("String")); 
     expect(parser.paramType(), accept("int")); 
     expect(parser.paramType(), accept("List")); 
     expect(parser.paramType(), accept("List<User>")); 
    }); 
    test("should not accept invalid types",() { 
     expect(parser.paramType(), notAccept("#")); 
     expect(parser.paramType(), notAccept("0")); 
     expect(parser.paramType(), notAccept("String()")); 
     expect(parser.paramType(), notAccept("List<User>")); 
    }); 
    }); 
} 

사용자 정의 정합 :

Matcher accept(String matchingString) => new AcceptMatcher(matchingString); 

Matcher notAccept(String matchingString) => new NotAcceptMatcher(matchingString); 

class NotAcceptMatcher extends Matcher { 
    String matchingString; 

    NotAcceptMatcher(this.matchingString); 

    bool matches(item, Map matchState) { 
    return !item.end().accept(matchingString); 
    } 

    Description describe(Description description) { 
    return description.add("parser not accept string: $matchingString"); 
    } 

    Description describeMismatch(item, Description mismatchDescription, 
           Map matchState, bool verbose) { 
    mismatchDescription.add("accepts it"); 
    return mismatchDescription; 
    } 
} 

class AcceptMatcher extends Matcher { 

    String matchingString; 

    AcceptMatcher(this.matchingString); 

    bool matches(item, Map matchState) { 
    return item.end().accept(matchingString); 
    } 

    Description describe(Description description) { 
    return description.add("parser accept string: $matchingString"); 
    } 

    Description describeMismatch(item, Description mismatchDescription, 
           Map matchState, bool verbose) { 
    mismatchDescription.add("doesn't accept"); 
    return mismatchDescription; 
    } 

} 

당신은 내가 두 정합 기 NotAcceptMatcherAcceptMatcher을 정의해야 볼 수 있습니다. 논리는 꽤 비슷하지만 간단하게 만드는 방법을 모르겠습니다.

더 간단한 해결책이 있습니까? 그렇지 않을 수도

Matcher notAccept(String s) => isNot(accept(s)); 

expect(parser.paramType(), notAccept("#")); 

설명을 :

답변

2

당신은 당신의 accept 정규 반전하는 isNot 정규 표현을 사용할 수 있습니다

expect(parser.paramType(), isNot(accept("#"))); 

그것은 약간의 재미 읽습니다, 그래서 당신은 그것을 할 수있는 기능을 만들 수 있습니다 완벽하게 읽을 수는 있지만 일을 덜어줍니다.

Matchers가 길어 보일지 모르지만 원하는 경우 일부 형식 주석을 삭제하고 짧은 변수 이름을 사용하여 정규 표현식 정의를 좀 더 간결하게 만들 수 있습니다. 다른 사용자를 위해 문서화하는 것에 대해 걱정할 필요가 없기 때문에 프레임 워크에서 호출 할 클래스 나 함수를 작성할 때이 점이 잘 맞습니다.

Matcher accept(String s) => 
    predicate((i) => i.end().accept(s), "parser accepts $s"); 
:

class AcceptMatcher extends Matcher { 
    final acceptString; 

    AcceptMatcher(this.acceptString); 

    matches(item, _) => item.end().accept(acceptString); 

    describe(d) => d.add("parser accept string: $acceptString"); 

    describeMismatch(item, d, _, __) => d..add("doesn't accept"); 
} 

또 다른 옵션은 단지 predicate 정규를 사용하는 것입니다