четверг, 24 марта 2016 г.

New version of StateSpecs 2.0

I am finished new version of StateSpecs 2.0. 
With this library you can describe object state with first class specifications. For example there are SpecOfCollectionItem, SpecOfObjectClass and SpecOfObjectSuperclass. They can match and validate given objects. In case when object is not satisfied specification you will get failure result with detailed information about problem.
spec matches: anObject.
spec validate: anObject. "it returns validation result which can be success or particular failure"
To easily create specifications and validate objects by them StateSpecs provides two kind DSL: should expressions and "word" classes.
First allows you to write "assertions":
1 should be: 2
1 should equal: 10
And second allows you to instantiate specs by natural readable words:
Kind of: Number
Instance of: String
Equal to: 'test'
In new version new kind of should expressions added:

Boolean properties validation. You can send any message to "should be" which will be executed by receiver of "should" and then validated for truth:
1 should be between: 10 and: 50
#(1 2) should be isEmpty
Deep object state validation. You can send any series of messages to "object where" to write should expression for internal property:
(1@3) where x should be: 1
(0@1 corner: 10@20) where origin x should be: 0
Other expressions: 
1 should be: 2. "fail with message: Got '1' but it should be '2'"
1 should not be: 1. "fail with message: Got '1' but it should not be '1'"

3 should equal: 2. "fail with message: Got '3' but it should equal '2'"
3 should not equal: 3. "fail with message: Got '3' but it should equal '3'"

3 should beKindOf: String.
3 should not beKindOf: Number.

3 should beInstanceOf: Number.
3 should not beInstanceOf: SmallInteger.

#(1 2) should equal: #(10 20).
#(1 2) should equal: #(1 2) asOrderedCollection. "not fail because by default comparison not look at collection types"
#(1 2) should equal: #(1 2) asSet.
#(1 2) should equal: #(2 1). "not fail because by default equality between collections is not ordered"
#(1 2) should equalInOrder: #(2 1). "fail because it is explicit requirement for ordered equality"

#(1 2) should haveSize: 10.
#(1 2) should include: 10.
#(1 2) should include: 10 at: 1.
#(1 2) should include: (Instance of: String) at: 1.
#(1 2) should include: (Kind of: String) at: 2.

[1 + 2] should raise: ZeroDivide.
[1/0] should not raise: ZeroDivide.
[1/0] should raise: Error.
[1/0] should raise: (Kind of: Error).
[1/0] should fail.
[self error: 'test'] should raise: errorInstance. "fail because raised error is not the same as expected errorInstance"
[1 + 2] should not fail.

3 should be even.
2 should not be even.

3 should be between: 10 and: 50.
2 should not between: 1 and: 5.

#(1 2) should be isEmpty. "fail with message: #(1 2) should be isEmpty"
#() should not be isEmpty.

(1@3 corder: 20@30) where origin x should equal: 100. "fail with message: Got '1' from (1@3 corder: 20@30) origin x but it should equal: 100"
All expressions can be found in SpecOfShouldExpression class which you can extend with new keywords. SpecOfShouldExpressionTests describes them in tests.
Underhood should expression build concrete specification instance and validate subject of should expression by it.  Then concrete validation failure will signal SpecOfFailed exception. It makes possible to extend debugger tools to better analyse problem. Such tools can be specific for different kind of failures

Комментариев нет:

Отправить комментарий