12
返回列表 发新帖
楼主: Sky-Tiger

The MetaModel project accepted into the Apache Incubator

[复制链接]
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
11#
 楼主| 发表于 2013-7-8 19:56 | 只看该作者
Now, as part of our site we want to incorporate our test reports so that the kitten owners will have more
confidence in the site, that they can trust us.
Specs2 can actually generate an HTML report of the tests we've run, so lets use that as a basis of our reports.
First, we need to generate the html; this is done by specifying the html option to Specs2 in build.sbt:
testOptions in Test += Tests.Argument("html")
Specs2 uses pegdown, an html generator library, to generate the HTML, so for this to work we need to add another
dependency "org.pegdown" % "pegdown" % "1.0.2"; note that we're adding at test configuration.
libraryDependencies += "org.specs2" % "specs2_2.10" % "1.12.3" % "test"
libraryDependencies += "org.pegdown" % "pegdown" % "1.0.2" % "test"
When you reload and run the tests again, this produces a nice html report in target/specs2-
reports/LogicSpec.html, along with the images and css required; see figure 4.1.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
12#
 楼主| 发表于 2013-7-8 19:56 | 只看该作者
Scalacheck is a test framework which is designed for property based testing. The main difference between a more
traditional unit testing framework and a property based framework is that with a traditional framework, you have
to provide the data with which to test your classes. With a property based framework, it provides the data. You tell
it what sort of data you want, and then it generates a set of data, and runs the tests. You need to provide some
code that asserts that a combination of data is correct. Let's have an example. In chapter 1, we created a specs2
test to test the buyer kitten matching algorithm. It looked like this:
objectLogicSpec extends Specification {
"The 'matchLikelihood' method" should {
"be 100% when all attributes match" in {
val tabby = Kitten("1", List("male", "tabby"))
valprefs = BuyerPreferences(List("male", "tabby"))
Logic.matchLikelihood(tabby, prefs) must beGreaterThan(.999)
}
"be 0% when no attributes match" in {
val tabby = Kitten("1", List("male", "tabby"))
valprefs = BuyerPreferences(List("female", "calico"))
val result = Logic.matchLikelihood(tabby, prefs)
result must beLessThan(.001)
}
}
}
These are good tests, but two test cases to cover the logic in this test seems a bit light. So, to up our confidence in
the algorithm a bit, we can add tests for the same method using Scalacheck:

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
13#
 楼主| 发表于 2013-7-8 19:57 | 只看该作者
Since so many combinators can be written in terms of just these two functions,
there is a name for data types that can implement map2 and unit. They are called
applicative functors:
trait
def
def
def
}
Applicative[F[_]] extends Functor[F] {
map2[A,B](fa: F[A], fb: F[B])(f: (A, B) => C): F[C]
apply[A,B](fab: F[A => B])(fa: F[A]): F[B]
unit[A](a: A): F[A]
There is an additional combinator, apply, that we haven't yet discussed. The
map2 and apply combinators can be implemented in terms of each other, so a
minimal implementation of Applicative must provide one or the other.
EXERCISE 1: Implement map2 in terms of apply and unit. Then
implement apply in terms of map2 and unit.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
14#
 楼主| 发表于 2013-7-13 19:05 | 只看该作者
A ChannelPipeline is a list of ChannelHandler instances that handle or intercept
inbound and outbound operations of a channel. ChannelPipeline offers an advanced form
of the interception filter pattern, giving a user full control over how an event is handled and
how the ChannelHandlers in the ChannelPipeline interact with each other.
For each new channel, a new ChannelPipeline is created and attached to the channel.
Once attached, the coupling between the channel and the ChannelPipeline is permanent;
the channel cannot attach another ChannelPipeline to it or detach the current
ChannelPipeline from it. All of this is handled for you; you don’t need to take care of this.
Figure 6.1 describes how ChannelHandlers in a ChannelPipeline typically process
I/O. An I/O operation can be handled by either a ChannelInboundHandler or a
ChannelOutboundHandler and be forwarded to the closest handler by calling either one of
the methods defined in the ChannelInboundInvoker interface for inbound I/O or by one
of the methods defined in the ChannelOutboundInvoker interface for outbound I/O.
ChannelPipeline extends both of them.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
15#
 楼主| 发表于 2013-7-13 20:33 | 只看该作者
As shown in figure 6.1 a ChannelPipeline is mainly a list of ChannelHandlers. If an
inbound I/O event is triggered it’s passed from the beginning to the end of the
ChannelPipeline. For outbound I/O events it begins at the end of the ChannelPipeline
and process to the start. The ChannelPipeline itself knows if a ChannelHandler can
handle the event by checking its type. If it can’t handle it, it skips the ChannelHandler and
uses the next matching.
Modifications on the ChannelPipeline can be done on-the-fly, which means you can
add/remove/replace ChannelHandler even from within another ChannelHandler or have
it remove itself. This allows writing flexible logic, such as multiplexer, but I’ll go into more
detail later in this chapter.
For now, let’s look at how you can modify a ChannelPipeline.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
16#
 楼主| 发表于 2013-7-13 20:43 | 只看该作者
ChannelPipeline pipeline = ..;
FirstHandler firstHandler = new FirstHandler(); #1
pipeline.addLast(“handler1“, firstHandler); #2
pipeline.addFirst(“handler2“, new SecondHandler()); #3
pipeline.addLast(“handler3“, new ThirdHandler()); #4
pipeline.remove(“handler3“); #5
pipeline.remove(firstHandler); #6
pipeline.replace(“handler2“, “handler4“, new ForthHandler()); #7
#1 Create instance of FirstHandler
#2 Add FirstHandler to ChannelPipeline
#3 Add SecondHandler instance to ChannelPipeline using first position. This means it will be before
the already existing FirstHandler
#4 Add ThirdHandler to ChannelPipeline on the last position
#5 Remove ThirdHandler by using name it was added with
#6 Remove FirstHandler by using reference to instance
#7 Replace SecondHandler which was added with handler2 as name by FourthHandler and add it
with name handler4

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
17#
 楼主| 发表于 2013-7-13 20:49 | 只看该作者
As ChannelPipeline extends ChannelInboundInvoker and
ChannelOutboundInvoker, it exposes additional methods for invoking inbound and
outbound operations.
Table 6.3 lists all inbound operations that are exposed, as defined in the
ChannelInboundInvoker interface. In addition to ChannelPipeline,
ChannelHandlerContext extends ChannelInboundInvoker and exposes those.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
18#
 楼主| 发表于 2013-7-13 20:51 | 只看该作者
Name Description
fireChannelRegistered()
This results in having the
ChannelInboundHandler.channelRegistered(C
hannelHandlerContext) method call the next
ChannelStateHandler contained in the
ChannelPipeline.
fireChannelUnregistered()
This results in having the
ChannelInboundHandler.channelUnregistered
(ChannelHandlerContext) method call the next
ChannelStateHandler contained in the
ChannelPipeline.
fireChannelActive()
This results in having the
ChannelInboundHandler.channelActive(Channel
HandlerContext) method call the next
ChannelStateHandler contained in the
ChannelPipeline.
fireChannelInactive()

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表