Writing Queries
One of the most important things to grasp using Nest is how to write queries. Nest offers you several possibilities. By the way all examples on this page assume being wrapped in
var result = client.Search<ElasticSearchProject>(s=>s
.From(0)
.Size(10)
///EXAMPLE HERE
);
Raw strings
Although not preffered by me personally many folks like to build their own json strings and just pass that along.
.QueryRaw("\"match_all\" : { }")
.FilterRaw("\"match_all\" : { }")
Nest does not modify this in anyway and just writes this straight into the json output.
Query DSL
The preffered way to write queries since it gives you alot of cool feautures.
Lambda expressions
.Query(q=>q
.Term(p=>p.Name, "NEST")
)
Here you'll see we can use expressions to adres properties in a type safe matter. This also works for IEnumerable
types i.e
.Query(q=>q
.Term(p=>p.Followers.First().FirstName, "NEST")
)
Because these property lookups are expressions you dont have to do any null checks. The previous would expand to the followers.firstName
property name.
Of course if you need to pass the property name as string Nest will allow you to do so.
.Query(q=>q
.Term("followers.firstName", "martijn")
)
Static query/filter generator.
Sometimes you'll need to resuse a filter or query often. To aid with this you can also write queries like this:
var termQuery = Query<ElasticSearchProject>
.Term(p=>p.Followers.First().FirstName, "martijn")
...
.Query(q=>q
.Bool(bq=>bq
.Must(
mq=>mq.MatchAll()
, termQuery
)
)
)
similarly Filter<T>.[Filter]()
methods exist for filters.
Boolean queries
As can be seen in the previous example writing out boolean queries can turn into a really tedious and verbose effort. Luckily Nest supports bitwise operators and so we can rewrite the previous as such:
.Query(q=>q.MatchAll() && termQuery)
Note how we are mixing and matching the lambda and static queries here
Similary an OR
looks like this
.Query(q=>q
q.Term("name", "Nest")
|| q.Term("name", "Elastica")
)
NOT
's are also supported
.Query(q=>q
q.Term("language", "php")
&& !q.Term("name", "Elastica")
)
This will query for all the php clients except Elastica
You can mix and match this to any complexity until it satisfies your query requirements.
.Query(q=>q
(q.Term("language", "php")
&& !q.Term("name", "Elastica")
)
||
q.Term("name", "Nest")
)
will query all php clients except elastica or where the name equals Nest.
Clean output support
Normally writing three boolean must clauses looks like this (psuedo code)
must
clause1
clause2
clause3
A naive implemenation of the bitwise operators would make all the queries sent to elasticsearch look like
must
must
clause1
clause2
clause3
This degrades rather rapidly so and makes inspecting generated queries quite a chore. Nest does it's best to detect these cases and always write them in the first clean form.
Conditionless queries
Writing complex boolean queries is one thing but more often then not you'll want to make decisions on how to query based on user input.
public class UserInput
{
public string Name { get; set; }
public string FirstName { get; set; }
public int? LOC { get; set; }
}
and then
.Query(q=> {
QueryDescriptor<ElasticSearch> query = null;
if (!string.IsNullOrEmpty(userInput.Name))
query &= q.Term(p=>p.Name, userInput.Name);
if (!string.IsNullOrEmpty(userInput.FirstName))
query &= q
.Term("followers.firstName", userInput.FirstName);
if (userInput.LOC.HasValue)
query &= q.Range(r=>r.OnField(p=>p.Loc).From(userInput.Loc.Value))
return query;
})
This again turns tedious and verbose rather quickly too. Therefor nest allows you to write the previous query as:
.Query(q=>
q.Term(p=>p.Name, userInput.Name);
&& q.Term("followers.firstName", userInput.FirstName)
&& q.Range(r=>r.OnField(p=>p.Loc).From(userInput.Loc))
)
If any of the queries would result in an empty query they won't be sent to elasticsearch.
So if all the terms are null (or empty string) on userInput
except userInput.Loc
it wouldn't even wrap the range query in a boolean query but just issue a plain range query.
If all of them empty it will result in a match_all
query.
This conditionless behavior is turned on by default but can be turned of like so:
var result = client.Search<ElasticSearchProject>(s=>s
.From(0)
.Size(10)
.Strict() //disable conditionlessqueries by default
///EXAMPLE HERE
);
However queries themselves can opt back in or out.
.Query(q=>
q.Strict().Term(p=>p.Name, userInput.Name);
&& q.Term("followers.firstName", userInput.FirstName)
&& q.Strict(false).Range(r=>r.OnField(p=>p.Loc).From(userInput.Loc))
)
In this example if userInput.Name
is null or empty it will result in a DslException
. The range query will use conditionless logic no matter if the SearchDescriptor uses .Strict()
or not.
Also good to note is that conditionless query logic propagates:
q.Strict().Term(p=>p.Name, userInput.Name);
&& q.Term("followers.firstName", userInput.FirstName)
&& q.Filtered(fq => fq
.Query(qff =>
qff.Terms(p => p.Country, userInput.Countries)
&& qff.Terms(p => p.Loc, userInput.Loc)
)
)
If both userInput.Countries
and userInput.Loc
are null or empty the entire filtered
query will be not be issued.


Welcome to PhotoGallery!
Login to continue!
Fill in your details here:
Email :
Password :
Are you a new user?


--- layout: post title: 'Perl practice: daily mail of all movies aired on Spanish TV' date: 2012-09-16 20:57:37.000000000 +02:00 type: post published: true status: publish categories: - Coding tags: - movies - perl - scripting - spanish tv meta: _edit_last: '1' _thumbnail_id: '2179' dsq_thread_id: '846783468' author: login: bbWebdesign email<EMAIL_ADDRESS>display_name: Bob first_name: Bob last_name: Belderbos ---
I like to solve common day problems, at the same time learning more coding. Learning to code is all about practice. Today I show you a Perl script to get a daily email listing all movies broadcasted by Spanish TV in the coming 24 hours.
I tried to do this some time ago - BeautifulSoup is very powerful for html parsing, but with the typical tv guide I had to rely on a class "cine inactiu" to filter the movies out. This worked pretty well, but it was not complete and as the movie names are in Spanish I linked to imdbapi for more info which usually did not yield any result. So I needed to redo this exercise ...
I didn't start scripting. First I looked for a better source which I found. This page does half of the work finding all movies to be aired today on Spanish TV. Usually it is not necessary to code everything! What I wanted to add on top of this was:
#!/usr/bin/perl -w # author: bob belderbos # v0.1 sept 2012 # purpose: send an email with all movies on Spanish TV in the next 24 hours # sincroguia.tv has a pretty complete list # this script servers best in a daily cronjob # use strict; use Data::Dumper; use LWP::Simple; use Encode qw(encode decode); # http://perlgeek.de/en/article/encodings-and-unicode my $enc = 'utf-8'; my $output; my $email =<EMAIL_ADDRESS>my @html = getUrl("http://www.sincroguia.tv/todas-las-peliculas.html"); # movie lines start with hh:mm timestamps for (grep {/^d{2}:d{2}|^<br/} @html){ # separate days if(/^<br/){ s/
//g; $output .= createHeader($_, "*"); next; } # parse movies m/(d{2}:d{2}) - <a.*?"([^"]+)" href="([^"]+)".*- ([^<]+).*/; my ($time, $title, $url, $channel) = ($1, $2, $3, $4); $output .= encode($enc, createHeader("$time / $channel / $title") . "$urln" . getMovieInfo($url) . "nn"); } # send me the generated movielist sendEmail($email, $output); sub getUrl { my $url = shift; my @html = split /</?li[> ]/, get($url); return @html; } sub getMovieInfo { my $url = shift; my $info; for(getUrl($url)){ next if(! /column/); for my $line (split /</?h3[> ]/, $_){ if($line =~ /Director:|rpretes|Idioma|Nacionalidad|Añ/){ $line =~ s/.*?strong>(.*)(.*)/$1$2n/g; $line =~ s/Año/Estreno/g; $info .= $line ; } } last; } return $info; } sub createHeader { my $str = shift; my $delimiter = shift // "="; my $width = 70; my $output = "n" . $delimiter x $width . "n" . $str . "n" . $delimiter x $width . "n"; return $output; } sub sendEmail { my ($to, $output) = @_; my $subject = "Today's movies Spanish TV"; # on mail pipe: http://objectmix.com/perl/380680-sending-email-perl-using-pipe-mailx.html open my $pipe, '|-', 'mailx', '-s', $subject, # char issue mailx: http://forums.opensuse.org/english/other-forums/development/programming-scripting/419802-charset-problem-mailx.html '-S', 'ttycharset=utf-8', '-S', 'sendcharsets=utf-8', '-S', 'encoding=8bit', $to or die "can't open pipe to mailx: $!n"; print $pipe $output; close $pipe; }
Having the time coded as hh:mm, Apple mail recognizes this and when clicking it you can add an event to your calendar. This way I can easily put a reminder of a movie I potentially want to see later in the evening.
The movie page does not always give the English movie name and sometimes it has a generic term like "La película de la semana" which doesn't give any clew. So I did some more parsingto include the movie name, original name and plot info. I also included the Twitter and Facebook sharing links which are on each movie page at the bottom, example:


We create awesome templates for you.
We create awesome templates for you.
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer
Architect & Engineer


--- layout: default ---
The encryption algorithms in Miscreant were purposefully designed to gracefully tolerate a wide spectrum of mistakes by users, most notably nonce-reuse misuse resistance, considered the gold standard in symmetric cryptography today.
By utilizing a provably secure cryptographic construction called STREAM, Miscreant's cryptographic operations can be performed in an incremental streaming manner without sacrificing security.
Minimal code size and simplicity are two of Miscreant's design goals. It's been designed with embedded/IoT devices in mind, and only depends on a hardware accelerated AES function.


Lily Allen posts fake video of her shedding tears over Labour manifesto and hits out at those declaring it genuine
Singer also recently called for 'Rule Britannia' to be banned
Lily Allen has hit out after she posted a fake video of herself seemingly shedding tears over Labour’s manifesto.
The singer posted a clip using AR filters on social media declaring: “Guys I just watched the Labour manifesto and I think it’s the best manifesto I’ve ever seen.”
Shortly after the post, a number of newspapers reported that she was shedding tears over the manifesto and many social media users also thought she was genuinely emotional in the clip.
One user wrote: “Lily Allen needs psychiatric help. There has never been a more hypocritical, self involved, champagne socialist than this creature,” while another also said: “Lily Allen. Crap singer and an attention seeker.”
Many others were quick to point out that the video was fake and the singer has now criticised those for not realising it was.
She also drew attention to the Tories recently causing a backlash after they confused users by changing their official press office Twitter account to FactCheckUK, to make it appear like an official fact checking site.

Allen also went on to criticise those who thought she was crying real tears and those who support a no-deal Brexit.
She added: “What’s the difference between people who thought I was crying real tears in my TikTok video today, and people who believe that cancelling our membership with the biggest trading bloc in the world, with no deal, is a good idea ? I’ll wait.”
It comes just days after Allen faced a barrage of criticism after calling for ‘Rule Britannia’ to be banned.
Taking aim at the track, which originated from a poem by James Thomson, she singled out the lyrics: “Britons never, never, never shall be slaves. The nations, not so blest as thee, Must in their turn, to tyrants fall, While thous shalt flourish, shalt flourish great and free.”
Allen said: “Sorry what? Britannia rule the waves… I think we should not read this song anymore.”
The singer is currently living in the US, having vowed not to permanently return to the UK until “Brexit is sorted”.
She recently also backed an open letter backing Extinction Rebellion, which was signed by a string of celebrities who admitted they were “hypocrites” for demanding change.


You need to enable JavaScript to run this app.
estimator
ID
-
Company
-
Customer
-
Get an Estimate
Tax
Tax
Tax
Add an Item
Add file
Description
Evaluation
Questions
Timeline
Materials
Labor
Equipment
Competition
Profit Margin
Payment Terms
Benefits
Circumstances
History
Signatures
subTotal
totalTax
total


@TestFor(BookController)
@Mock([Book, Author, BookService])
15.1 Unit Testing
Version: 3.2.11
Table of Contents
15.1 Unit Testing
Unit testing are tests at the "unit" level. In other words you are testing individual methods or blocks of code without consideration for surrounding infrastructure. Unit tests are typically run without the presence of physical resources that involve I/O such databases, socket connections or files. This is to ensure they run as quick as possible since quick feedback is important.
The Test Mixins
Since Grails 2.0, a collection of unit testing mixins is provided by Grails that lets you enhance the behavior of a typical JUnit 3, JUnit 4 or Spock test. The following sections cover the usage of these mixins.
You won’t normally have to import any of the testing classes because Grails does that for you. But if you find that your IDE for example can’t find the classes, here they all are:
-
grails.test.mixin.TestFor
-
grails.test.mixin.Mock
-
grails.test.mixin.TestMixin
-
grails.test.mixin.support.GrailsUnitTestMixin
-
grails.test.mixin.domain.DomainClassUnitTestMixin
-
grails.test.mixin.services.ServiceUnitTestMixin
-
grails.test.mixin.web.ControllerUnitTestMixin
-
grails.test.mixin.web.InterceptorUnitTestMixin
-
grails.test.mixin.web.GroovyPageUnitTestMixin
-
grails.test.mixin.web.UrlMappingsUnitTestMixin
-
grails.test.mixin.hibernate.HibernateTestMixin
Note that you’re only ever likely to use the first two explicitly. The rest are there for reference.
Test Mixin Basics
Most testing can be achieved via the TestFor
annotation in combination with the Mock
annotation for mocking collaborators. For example, to test a controller and associated domains you would define the following:
The TestFor
annotation defines the class under test and will automatically create a field for the type of class under test. For example in the above case a "controller" field will be present, however if TestFor
was defined for a service a "service" field would be created and so on.
The Mock
annotation creates mock version of any collaborators. There is an in-memory implementation of GORM that will simulate most interactions with the GORM API.
doWithSpring and doWithConfig callback methods, FreshRuntime annotation
The doWithSpring
callback method can be used to add beans with the BeanBuilder DSL. There is the doWithConfig
callback method for changing the grailsApplication.config values before the grailsApplication instance of the test runtime gets initialized.
import grails.test.mixin.support.GrailsUnitTestMixin
import org.junit.ClassRule
import org.junit.rules.TestRule
import spock.lang.Ignore;
import spock.lang.IgnoreRest
import spock.lang.Shared;
import spock.lang.Specification
@TestMixin(GrailsUnitTestMixin)
class StaticCallbacksSpec extends Specification {
static doWithSpring = {
myService(MyService)
}
static doWithConfig(c) {
c.myConfigValue = 'Hello'
}
def "grailsApplication is not null"() {
expect:
grailsApplication != null
}
def "doWithSpring callback is executed"() {
expect:
grailsApplication.mainContext.getBean('myService') != null
}
def "doWithConfig callback is executed"(){
expect:
config.myConfigValue == 'Hello'
}
}
You can also use these callbacks without "static" together with the FreshRuntime annotation. In this case, a clean application context and grails application instance is initialized for each test method call.
import grails.test.mixin.support.GrailsUnitTestMixin
import grails.test.runtime.FreshRuntime;
import org.junit.ClassRule
import org.junit.rules.TestRule
import spock.lang.Ignore;
import spock.lang.IgnoreRest
import spock.lang.Shared;
import spock.lang.Specification
@FreshRuntime
@TestMixin(GrailsUnitTestMixin)
class TestInstanceCallbacksSpec extends Specification {
def doWithSpring = {
myService(MyService)
}
def doWithConfig(c) {
c.myConfigValue = 'Hello'
}
def "grailsApplication is not null"() {
expect:
grailsApplication != null
}
def "doWithSpring callback is executed"() {
expect:
grailsApplication.mainContext.getBean('myService') != null
}
def "doWithConfig callback is executed"(){
expect:
config.myConfigValue == 'Hello'
}
}
You can use InstanceFactoryBean together with doWithSpring and the FreshRuntime annotation to mock beans in tests.
import grails.test.mixin.support.GrailsUnitTestMixin
import grails.test.runtime.FreshRuntime
import org.grails.spring.beans.factory.InstanceFactoryBean
import org.junit.ClassRule
import spock.lang.Shared
import spock.lang.Specification
@FreshRuntime
@TestMixin(GrailsUnitTestMixin)
class MockedBeanSpec extends Specification {
def myService=Mock(MyService)
def doWithSpring = {
myService(InstanceFactoryBean, myService, MyService)
}
def "doWithSpring callback is executed"() {
when:
def myServiceBean=grailsApplication.mainContext.getBean('myService')
myServiceBean.prova()
then:
1 * myService.prova() >> { true }
}
}
The DirtiesRuntime annotation
Test methods may be marked with the DirtiesRuntime annotation to indicate that the test modifies the runtime in ways which might be problematic for other tests and as such the runtime should be refreshed after this test method runs.
import grails.test.mixin.TestFor
import spock.lang.Specification
import grails.test.runtime.DirtiesRuntime
@TestFor(PersonController)
class PersonControllerSpec extends Specification {
@DirtiesRuntime
void "a test method which modifies the runtime"() {
when:
Person.metaClass.someMethod = { ... }
// ...
then:
// ...
}
void "a test method which should not be affected by the previous test method"() {
// ...
}
}
Sharing test runtime grailsApplication instance and beans for several test classes
It’s possible to share a single grailsApplication instance and beans for several test classes. This feature is activated by the SharedRuntime annotation. This annotation takes an optional class parameter implements SharedRuntimeConfigurer interface. All test classes referencing the same SharedRuntimeConfigurer implementation class will share the same runtime during a single test run. The value class for SharedRuntimeConfigurer annotation can also implement TestEventInterceptor . In this case the instance of the class will be registered as a test event interceptor for the test runtime.
Loading application beans in unit tests
Adding static loadExternalBeans = true
field definition to a unit test class makes the Grails unit test runtime load all bean definitions from grails-app/conf/spring/resources.groovy
and grails-app/conf/spring/resources.xml
files.
import spock.lang.Issue
import spock.lang.Specification
import grails.test.mixin.support.GrailsUnitTestMixin
@TestMixin(GrailsUnitTestMixin)
class LoadExternalBeansSpec extends Specification {
static loadExternalBeans = true
void "should load external beans"(){
expect:
applicationContext.getBean('simpleBean') == 'Hello world!'
}
}
15.1.1 Unit Testing Controllers
The Basics
You use the grails.test.mixin.TestFor
annotation to unit test controllers. Using TestFor
in this manner activates the grails.test.mixin.web.ControllerUnitTestMixin
and its associated API. For example:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void "test something"() {
}
}
Adding the TestFor
annotation to a controller causes a new controller
field to be automatically created for the controller under test.
The TestFor annotation will also automatically annotate any public methods starting with "test" with JUnit 4’s @Test annotation. If any of your test method don’t start with "test" just add this manually
|
To test the simplest "Hello World"-style example you can do the following:
// Test class
class SimpleController {
def hello() {
render "hello"
}
}
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void "test hello"() {
when:
controller.hello()
then:
response.text == 'hello'
}
}
The response
object is an instance of GrailsMockHttpServletResponse
(from the package org.codehaus.groovy.grails.plugins.testing
) which extends Spring’s MockHttpServletResponse
class and has a number of useful methods for inspecting the state of the response.
For example to test a redirect you can use the redirectedUrl
property:
class SimpleController {
def index() {
redirect action: 'hello'
}
...
}
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test index'() {
when:
controller.index()
then:
response.redirectedUrl == '/simple/hello'
}
}
Many actions make use of the parameter data associated with the request. For example, the 'sort', 'max', and 'offset' parameters are quite common. Providing these in the test is as simple as adding appropriate values to a special params
variable:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(PersonController)
class PersonControllerSpec extends Specification {
void 'test list'() {
when:
params.sort = 'name'
params.max = 20
params.offset = 0
controller.list()
then:
// ...
}
}
You can even control what type of request the controller action sees by setting the method
property of the mock request:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(PersonController)
class PersonControllerSpec extends Specification {
void 'test save'() {
when:
request.method = 'POST'
controller.save()
then:
// ...
}
}
This is particularly important if your actions do different things depending on the type of the request. Finally, you can mark a request as AJAX like so:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(PersonController)
class PersonControllerSpec extends Specification {
void 'test list'() {
when:
request.method = 'POST'
request.makeAjaxRequest()
controller.getPage()
then:
// ...
}
}
You only need to do this though if the code under test uses the xhr
property on the request.
Testing View Rendering
To test view rendering you can inspect the state of the controller’s modelAndView
property (an instance of org.springframework.web.servlet.ModelAndView
) or you can use the view
and model
properties provided by the mixin:
class SimpleController {
def home() {
render view: "homePage", model: [title: "Hello World"]
}
...
}
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test home'() {
when:
controller.home()
then:
view == '/simple/homePage'
model.title == 'Hello World'
}
}
Note that the view string is the absolute view path, so it starts with a '/' and will include path elements, such as the directory named after the action’s controller.
Testing Template Rendering
Unlike view rendering, template rendering will actually attempt to write the template directly to the response rather than returning a ModelAndView
hence it requires a different approach to testing.
Consider the following controller action:
class SimpleController {
def display() {
render template:"snippet"
}
}
In this example the controller will look for a template in grails-app/views/simple/_snippet.gsp
. You can test this as follows:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test display'() {
when:
controller.display()
then:
response.text == 'contents of the template'
}
}
However, you may not want to render the real template, but just test that it was rendered. In this case you can provide mock Groovy Pages:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test display with mock template'() {
when:
views['/simple/_snippet.gsp'] = 'mock template contents'
controller.display()
then:
response.text == 'mock template contents'
}
}
Testing Actions Which Return A Map
When a controller action returns a java.util.Map
that Map
may be inspected directly to assert that it contains the expected data:
class SimpleController {
def showBookDetails() {
[title: 'The Nature Of Necessity', author: 'Alvin Plantinga']
}
}
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test show book details'() {
when:
def model = controller.showBookDetails()
then:
model.author == 'Alvin Plantinga'
}
}
Testing XML and JSON Responses
XML and JSON response are also written directly to the response. Grails' mocking capabilities provide some conveniences for testing XML and JSON response. For example consider the following action:
def renderXml() {
render(contentType:"text/xml") {
book(title:"Great")
}
}
This can be tested using the xml
property of the response:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test render xml'() {
when:
controller.renderXml()
then:
response.text == "<book title='Great'/>"
response.xml.@title.text() == 'Great'
}
}
The xml
property is a parsed result from Groovy’s XmlSlurper class which is very convenient for parsing XML.
Testing JSON responses is pretty similar, instead you use the json
property:
// controller action
def renderJson() {
render(contentType:"application/json") {
book "Great"
}
}
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test render json'() {
when:
controller.renderJson()
then:
response.text == '{"book":"Great"}'
response.json.book == 'Great'
}
}
The json
property is an instance of org.codehaus.groovy.grails.web.json.JSONElement
which is a map-like structure that is useful for parsing JSON responses.
Testing XML and JSON Requests
Grails provides various convenient ways to automatically parse incoming XML and JSON packets. For example you can bind incoming JSON or XML requests using Grails' data binding:
def consumeBook(Book b) {
render "The title is ${b.title}."
}
To test this Grails provides an easy way to specify an XML or JSON packet via the xml
or json
properties. For example the above action can be tested by specifying a String containing the XML:
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(SimpleController)
@Mock([Book])
class SimpleControllerSpec extends Specification {
void 'test consume book xml'() {
when:
request.xml = '<book><title>Wool</title></book>'
controller.consumeBook()
then:
response.text == 'The title is Wool.'
}
}
Or alternatively a domain instance can be specified and it will be auto-converted into the appropriate XML request:
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(SimpleController)
@Mock([Book])
class SimpleControllerSpec extends Specification {
void 'test consume book xml'() {
when:
request.xml = new Book(title: 'Shift')
controller.consumeBook()
then:
response.text == 'The title is Shift.'
}
}
The same can be done for JSON requests:
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(SimpleController)
@Mock([Book])
class SimpleControllerSpec extends Specification {
void 'test consume book json'() {
when:
request.json = new Book(title: 'Shift')
controller.consumeBook()
then:
response.text == 'The title is Shift.'
}
}
If you prefer not to use Grails' data binding but instead manually parse the incoming XML or JSON that can be tested too. For example consider the controller action below:
def consume() {
request.withFormat {
xml {
render "The XML Title Is<EMAIL_ADDRESS>}
json {
render "The JSON Title Is ${request.JSON.title}."
}
}
}
To test the XML request you can specify the XML as a string:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test consume xml'() {
when:
request.xml = '<book title="The Stand"/>'
controller.consume()
then:
response.text == 'The XML Title Is The Stand.'
}
void 'test consume json'() {
when:
request.json = '{title:"The Stand"}'
controller.consume()
then:
response.text == 'The JSON Title Is The Stand.'
}
}
Testing Mime Type Handling
You can test mime type handling and the withFormat
method quite simply by setting the request’s contentType
attribute:
// controller action
def sayHello() {
def data = [Hello:"World"]
request.withFormat {
xml { render data as grails.converters.XML }
json { render data as grails.converters.JSON }
html data
}
}
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test say hello xml'() {
when:
request.contentType = 'application/xml'
controller.sayHello()
then:
response.text == '<?xml version="1.0" encoding="UTF-8"?><map><entry key="Hello">World</entry></map>'
}
void 'test say hello json'() {
when:
request.contentType = 'application/json'
controller.sayHello()
then:
response.text == '{"World"}'[Hello] }
}
There are constants provided by ControllerUnitTestMixin
for all of the common common content types as shown below:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test say hello xml'() {
when:
request.contentType = XML_CONTENT_TYPE
controller.sayHello()
then:
response.text == '<?xml version="1.0" encoding="UTF-8"?><map><entry key="Hello">World</entry></map>'
}
void 'test say hello json'() {
when:
request.contentType = JSON_CONTENT_TYPE
controller.sayHello()
then:
response.text == '{"World"}'[Hello] }
}
The defined constants are listed below:
| Constant | Value |
|---|---|
ALL_CONTENT_TYPE |
*/\* |
FORM_CONTENT_TYPE |
application/x-www-form-urlencoded |
MULTIPART_FORM_CONTENT_TYPE |
multipart/form-data |
HTML_CONTENT_TYPE |
text/html |
XHTML_CONTENT_TYPE |
application/xhtml+xml |
XML_CONTENT_TYPE |
application/xml |
JSON_CONTENT_TYPE |
application/json |
TEXT_XML_CONTENT_TYPE |
text/xml |
TEXT_JSON_CONTENT_TYPE |
text/json |
HAL_JSON_CONTENT_TYPE |
application/hal+json |
HAL_XML_CONTENT_TYPE |
application/hal+xml |
ATOM_XML_CONTENT_TYPE |
application/atom+xml |
Testing Duplicate Form Submissions
Testing duplicate form submissions is a little bit more involved. For example if you have an action that handles a form such as:
def handleForm() {
withForm {
render "Good"
}.invalidToken {
render "Bad"
}
}
you want to verify the logic that is executed on a good form submission and the logic that is executed on a duplicate submission. Testing the bad submission is simple. Just invoke the controller:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test duplicate form submission'() {
when:
controller.handleForm()
then:
response.text == 'Bad'
}
}
Testing the successful submission requires providing an appropriate SynchronizerToken
:
import grails.test.mixin.TestFor
import spock.lang.Specification
import org.codehaus.groovy.grails.web.servlet.mvc.SynchronizerTokensHolder
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test valid form submission'() {
when:
def tokenHolder = SynchronizerTokensHolder.store(session)
params[SynchronizerTokensHolder.TOKEN_URI] = '/controller/handleForm'
params[SynchronizerTokensHolder.TOKEN_KEY] = tokenHolder.generateToken(params[SynchronizerTokensHolder.TOKEN_URI])
controller.handleForm()
then:
response.text == 'Good'
}
}
If you test both the valid and the invalid request in the same test be sure to reset the response between executions of the controller:
import grails.test.mixin.TestFor
import spock.lang.Specification
import org.codehaus.groovy.grails.web.servlet.mvc.SynchronizerTokensHolder
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test form submission'() {
when:
controller.handleForm()
then:
response.text == 'Bad'
when:
response.reset()
def tokenHolder = SynchronizerTokensHolder.store(session)
params[SynchronizerTokensHolder.TOKEN_URI] = '/controller/handleForm'
params[SynchronizerTokensHolder.TOKEN_KEY] = tokenHolder.generateToken(params[SynchronizerTokensHolder.TOKEN_URI])
controller.handleForm()
then:
response.text == 'Good'
}
}
Testing File Upload
You use the GrailsMockMultipartFile
class to test file uploads. For example consider the following controller action:
def uploadFile() {
MultipartFile file = request.getFile("myFile")
file.transferTo(new File("/local/disk/myFile"))
}
To test this action you can register a GrailsMockMultipartFile
with the request:
import grails.test.mixin.TestFor
import spock.lang.Specification
import org.codehaus.groovy.grails.plugins.testing.GrailsMockMultipartFile
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test file upload'() {
when:
def file = new GrailsMockMultipartFile('myFile', 'some file contents'.bytes)
request.addFile file
controller.uploadFile()
then:
file.targetFileLocation.path == '/local/disk/myFile'
}
}
The GrailsMockMultipartFile
constructor arguments are the name and contents of the file. It has a mock implementation of the transferTo
method that simply records the targetFileLocation
and doesn’t write to disk.
Testing Command Objects
Special support exists for testing command object handling with the mockCommandObject
method. For example consider the following action:
class SimpleController {
def handleCommand(SimpleCommand simple) {
if(simple.hasErrors()) {
render 'Bad'
} else {
render 'Good'
}
}
}
class SimpleCommand {
String name
static constraints = {
name blank: false
}
}
To test this you mock the command object, populate it and then validate it as follows:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test valid command object'() {
given:
def simpleCommand = new SimpleCommand(name: 'Hugh')
simpleCommand.validate()
when:
controller.handleCommand(simpleCommand)
then:
response.text == 'Good'
}
void 'test invalid command object'() {
given:
def simpleCommand = new SimpleCommand(name: '')
simpleCommand.validate()
when:
controller.handleCommand(simpleCommand)
then:
response.text == 'Bad'
}
}
The testing framework also supports allowing Grails to create the command object instance automatically. To test this invoke the no-arg version of the controller action method. Grails will create an instance of the command object, perform data binding on it using the request parameters and validate the object just like it does when the application is running. See the test below.
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test valid command object'() {
when:
params.name = 'Hugh'
controller.handleCommand()
then:
response.text == 'Good'
}
void 'test invalid command object'() {
when:
params.name = ''
controller.handleCommand()
then:
response.text == 'Bad'
}
}
Testing allowedMethods
The unit testing environment respects the allowedMethods property in controllers. If a controller action is limited to be accessed with certain request methods, the unit test must be constructed to deal with that.
package com.demo
class DemoController {
static allowedMethods = [save: 'POST', update: 'PUT', delete: 'DELETE']
def save() {
render 'Save was successful!'
}
// ...
}
package com.demo
import grails.test.mixin.TestFor
import spock.lang.Specification
import static javax.servlet.http.HttpServletResponse.*
@TestFor(DemoController)
class DemoControllerSpec extends Specification {
void "test a valid request method"() {
when:
request.method = 'POST'
controller.save()
then:
response.status == SC_OK
response.text == 'Save was successful!'
}
void "test an invalid request method"() {
when:
request.method = 'DELETE'
controller.save()
then:
response.status == SC_METHOD_NOT_ALLOWED
}
}
Testing Calling Tag Libraries
You can test calling tag libraries using ControllerUnitTestMixin
, although the mechanism for testing the tag called varies from tag to tag. For example to test a call to the message
tag, add a message to the messageSource
. Consider the following action:
def showMessage() {
render g.message(code: "foo.bar")
}
This can be tested as follows:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {
void 'test render message tag'() {
given:
messageSource.addMessage 'foo.bar', request.locale, 'Hello World'
when:
controller.showMessage()
then:
response.text == 'Hello World'
}
}
See unit testing tag libraries for more information.
15.1.2 Unit Testing Tag Libraries
The Basics
Tag libraries and GSP pages can be tested with the grails.test.mixin.web.GroovyPageUnitTestMixin
mixin. To use the mixin declare which tag library is under test with the TestFor
annotation:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleTagLib)
class SimpleTagLibSpec extends Specification {
void "test something"() {
}
}
Adding the TestFor
annotation to a TagLib class causes a new tagLib
field to be automatically created for the TagLib class under test.
The tagLib field can be used to test calling tags as function calls. The return value of a function call is either a StreamCharBuffer instance or
the object returned from the tag closure when returnObjectForTags feature is used.
Note that if you are testing invocation of a custom tag from a controller you can combine the ControllerUnitTestMixin
and the GroovyPageUnitTestMixin
using the Mock
annotation:
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(SimpleController)
@Mock(SimpleTagLib)
class SimpleControllerSpec extends Specification {
}
Testing Custom Tags
The core Grails tags don’t need to be enabled during testing, however custom tag libraries do. The GroovyPageUnitTestMixin
class provides a mockTagLib()
method that you can use to mock a custom tag library. For example consider the following tag library:
class SimpleTagLib {
static namespace = 's'
def hello = { attrs, body ->
out << "Hello ${attrs.name ?: 'World'}"
}
def bye = { attrs, body ->
out << "Bye ${attrs.author.name ?: 'World'}"
}
}
You can test this tag library by using TestFor
and supplying the name of the tag library:
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleTagLib)
class SimpleTagLibSpec extends Specification {
void "test hello tag"() {
expect:
applyTemplate('<s:hello />') == 'Hello World'
applyTemplate('<s:hello name="Fred" />') == 'Hello Fred'
applyTemplate('<s:bye author="${author}" />', [author: new Author(name: 'Fred')]) == 'Bye Fred'
}
void "test tag calls"() {
expect:
tagLib.hello().toString() == 'Hello World'
tagLib.hello(name: 'Fred').toString() == 'Hello Fred'
tagLib.bye(author: new Author(name: 'Fred')).toString == 'Bye Fred'
}
}
Alternatively, you can use the TestMixin
annotation and mock multiple tag libraries using the mockTagLib()
method:
import spock.lang.Specification
import grails.test.mixin.TestMixin
import grails.test.mixin.web.GroovyPageUnitTestMixin
@TestMixin(GroovyPageUnitTestMixin)
class MultipleTagLibSpec extends Specification {
void "test multiple tags"() {
given:
mockTagLib(SomeTagLib)
mockTagLib(SomeOtherTagLib)
expect:
// ...
}
}
The GroovyPageUnitTestMixin
provides convenience methods for asserting that the template output equals or matches an expected value.
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(SimpleTagLib)
class SimpleTagLibSpec extends Specification {
void "test hello tag"() {
expect:
assertOutputEquals ('Hello World', '<s:hello />')
assertOutputMatches (/.*Fred.*/, '<s:hello name="Fred" />')
}
}
Testing View and Template Rendering
You can test rendering of views and templates in grails-app/views
via the render(Map)
method provided by GroovyPageUnitTestMixin
:
import spock.lang.Specification
import grails.test.mixin.TestMixin
import grails.test.mixin.web.GroovyPageUnitTestMixin
@TestMixin(GroovyPageUnitTestMixin)
class RenderingSpec extends Specification {
void "test rendering template"() {
when:
def result = render(template: '/simple/hello')
then:
result == 'Hello World!'
}
}
This will attempt to render a template found at the location grails-app/views/simple/_hello.gsp
. Note that if the template depends on any custom tag libraries you need to call mockTagLib
as described in the previous section.
Some core tags use the active controller and action as input. In GroovyPageUnitTestMixin tests, you can manually set the active controller and action name by setting controllerName and actionName properties on the webRequest object:
webRequest.controllerName = 'simple'
webRequest.actionName = 'hello'
15.1.3 Unit Testing Domains
Overview
Domain class interaction can be tested without involving a real database connection using DomainClassUnitTestMixin
.
The GORM implementation in DomainClassUnitTestMixin is using a simple in-memory ConcurrentHashMap
implementation. Note that this has limitations compared to a real GORM implementation.
A large, commonly-used portion of the GORM API can be mocked using DomainClassUnitTestMixin
including:
-
Simple persistence methods like
save()
,delete()
etc. -
Dynamic Finders
-
Named Queries
-
Query-by-example
-
GORM Events
If you wish to test GORM using a real database then it is recommended to use one of the following super classes:
-
grails.test.hibernate.HibernateSpec
- Sets up Hibernate for the current test -
grails.test.mongodb.MongoSpec
- Sets up MongoDB for the current test
All features of GORM for Hibernate can be tested within a HibernateSpec
unit test including:
-
String-based HQL queries
-
composite identifiers
-
dirty checking methods
-
any direct interaction with Hibernate
The implementation behind HibernateSpec
takes care of setting up the Hibernate with the in-memory H2 database.
DomainClassUnitTestMixin Basics
DomainClassUnitTestMixin
is typically used in combination with testing either a controller, service or tag library where the domain is a mock collaborator defined by the Mock
annotation:
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(BookController)
@Mock(Book)
class BookControllerSpec extends Specification {
// ...
}
The example above tests the BookController
class and mocks the behavior of the Book
domain class as well. For example consider a typical scaffolded save
controller action:
class BookController {
def save() {
def book = new Book(params)
if (book.save(flush: true)) {
flash.message = message(
code: 'default.created.message',
args: [message(code: 'book.label', default: 'Book'), book.id])
redirect(action: "show", id: book.id)
}
else {
render(view: "create", model: [bookInstance: book])
}
}
}
Tests for this action can be written as follows:
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(BookController)
@Mock(Book)
class BookControllerSpec extends Specification {
void "test saving an invalid book"() {
when:
controller.save()
then:
model.bookInstance != null
view == '/book/create'
}
void "test saving a valid book"() {
when:
params.title = "The Stand"
params.pages = "500"
controller.save()
then:
response.redirectedUrl == '/book/show/1'
flash.message != null
Book.count() == 1
}
}
Mock
annotation also supports a list of mock collaborators if you have more than one domain to mock:
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(BookController)
@Mock([Book, Author])
class BookControllerSpec extends Specification {
// ...
}
Alternatively you can also use the DomainClassUnitTestMixin
directly with the TestMixin
annotation and then call the mockDomain
method to mock domains during your test:
import grails.test.mixin.TestFor
import grails.test.mixin.TestMixin
import spock.lang.Specification
import grails.test.mixin.domain.DomainClassUnitTestMixin
@TestFor(BookController)
@TestMixin(DomainClassUnitTestMixin)
class BookControllerSpec extends Specification {
void setupSpec() {
mockDomain(Book)
}
void "test saving an invalid book"() {
when:
controller.save()
then:
model.bookInstance != null
view == '/book/create'
}
void "test saving a valid book"() {
when:
params.title = "The Stand"
params.pages = "500"
controller.save()
then:
response.redirectedUrl == '/book/show/1'
flash.message != null
Book.count() == 1
}
}
The mockDomain
method also includes an additional parameter that lets you pass a List of Maps to configure a domain, which is useful for fixture-like data:
mockDomain(Book, [
[title: "The Stand", pages: 1000],
[title: "The Shining", pages: 400],
[title: "Along Came a Spider", pages: 300] ])
Testing Constraints
There are 3 types of validateable classes:
-
Domain classes
-
Classes which implement the
Validateable
trait -
Command Objects which have been made validateable automatically
These are all easily testable in a unit test with no special configuration necessary as long as the test method is marked with TestFor
or explicitly applies the GrailsUnitTestMixin
using TestMixin
. See the examples below.
package com.demo
class MyValidateable implements grails.validation.Validateable {
String name
Integer age
static constraints = {
name matches: /[A-Z].*/
age range: 1..99
}
}
package com.demo
class Person {
String name
static constraints = {
name matches: /[A-Z].*/
}
}
package com.demo
class DemoController {
def addItems(MyCommandObject co) {
if(co.hasErrors()) {
render 'something went wrong'
} else {
render 'items have been added'
}
}
}
class MyCommandObject {
Integer numberOfItems
static constraints = {
numberOfItems range: 1..10
}
}
package com.demo
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(Person)
class PersonSpec extends Specification {
void "Test that name must begin with an upper case letter"() {
when: 'the name begins with a lower letter'
def p = new Person(name: 'jeff')
then: 'validation should fail'
!p.validate()
when: 'the name begins with an upper case letter'
p = new Person(name: 'Jeff')
then: 'validation should pass'
p.validate()
}
}
package com.demo
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(DemoController)
class DemoControllerSpec extends Specification {
void 'Test an invalid number of items'() {
when:
params.numberOfItems = 42
controller.addItems()
then:
response.text == 'something went wrong'
}
void 'Test a valid number of items'() {
when:
params.numberOfItems = 8
controller.addItems()
then:
response.text == 'items have been added'
}
}
package com.demo
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification
@TestMixin(GrailsUnitTestMixin)
class MyValidateableSpec extends Specification {
void 'Test validate can be invoked in a unit test with no special configuration'() {
when: 'an object is valid'
def validateable = new MyValidateable(name: 'Kirk', age: 47)
then: 'validate() returns true and there are no errors'
validateable.validate()
!validateable.hasErrors()
validateable.errors.errorCount == 0
when: 'an object is invalid'
validateable.name = 'kirk'
then: 'validate() returns false and the appropriate error is created'
!validateable.validate()
validateable.hasErrors()
validateable.errors.errorCount == 1
validateable.errors['name'].code == 'matches.invalid'
when: 'the clearErrors() is called'
validateable.clearErrors()
then: 'the errors are gone'
!validateable.hasErrors()
validateable.errors.errorCount == 0
when: 'the object is put back in a valid state'
validateable.name = 'Kirk'
then: 'validate() returns true and there are no errors'
validateable.validate()
!validateable.hasErrors()
validateable.errors.errorCount == 0
}
}
package com.demo
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification
@TestMixin(GrailsUnitTestMixin)
class MyCommandObjectSpec extends Specification {
void 'Test that numberOfItems must be between 1 and 10'() {
when: 'numberOfItems is less than 1'
def co = new MyCommandObject()
co.numberOfItems = 0
then: 'validation fails'
!co.validate()
co.hasErrors()
co.errors['numberOfItems'].code == 'range.toosmall'
when: 'numberOfItems is greater than 10'
co.numberOfItems = 11
then: 'validation fails'
!co.validate()
co.hasErrors()
co.errors['numberOfItems'].code == 'range.toobig'
when: 'numberOfItems is greater than 1'
co.numberOfItems = 1
then: 'validation succeeds'
co.validate()
!co.hasErrors()
when: 'numberOfItems is greater than 10'
co.numberOfItems = 10
then: 'validation succeeds'
co.validate()
!co.hasErrors()
}
}
That’s it for testing constraints. One final thing we would like to say is that testing the constraints in this way catches a common error: typos in the "constraints" property name which is a mistake that is easy to make and equally easy to overlook. A unit test for your constraints will highlight the problem straight away.
HibernateSpec and MongoSpec Basics
HibernateSpec
allows Hibernate to be used in Grails unit tests. It uses a H2 in-memory database. The following documentation covers HibernateSpec
, but the same concepts can be applied to MongoSpec
.
package example
import grails.test.hibernate.HibernateSpec
import spock.lang.Specification
class PersonSpec extends HibernateSpec {
void "Test count people"() {
expect: "Test execute Hibernate count query"
Person.count() == 0
sessionFactory != null
transactionManager != null
hibernateSession != null
}
}
By default HibernateSpec
will scan for domain classes within the package specified by the grails.codegen.defaultPackage
configuration option or if not specified the same package as the test.
Configuring domain classes for HibernateSpec tests
If you only wish to test a limited set of domain classes you can override the getDomainClasses
method to specify exactly which ones you wish to test:
package example
import grails.test.hibernate.HibernateSpec
class PersonSpec extends HibernateSpec {
...
List<Class> getDomainClasses() { [ Person ] }
}
Testing Controllers and Services with HibernateSpec
If you wish to test a controller or a service with HibernateSpec
generally you can combine HibernateSpec
with Grails' default test mixins:
package example
import grails.test.hibernate.HibernateSpec
@TestFor(BookController)
class BookControllerUnitSpec extends HibernateSpec {
...
}
However, if the controller or service uses @Transactional
you will need to assign the transaction manager within the unit test’s setup
method:
def setup() {
controller.transactionManager = transactionManager
}
15.1.4 Unit Testing Filters
Unit testing filters is typically a matter of testing a controller where a filter is a mock collaborator. For example consider the following filters class:
class CancellingFilters {
def filters = {
all(controller:"simple", action:"list") {
before = {
redirect(controller:"book")
return false
}
}
}
}
This filter interceptors the list
action of the simple
controller and redirects to the book
controller. To test this filter you start off with a test that targets the SimpleController
class and add the CancellingFilters
as a mock collaborator:
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(SimpleController)
@Mock(CancellingFilters)
class SimpleControllerSpec extends Specification {
// ...
}
You can then implement a test that uses the withFilters
method to wrap the call to an action in filter execution:
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(SimpleController)
@Mock(CancellingFilters)
class SimpleControllerSpec extends Specification {
void "test list action is filtered"() {
when:
withFilters(action:"list") {
controller.list()
}
then:
response.redirectedUrl == '/book'
}
}
Note that the action
parameter is required because it is unknown what the action to invoke is until the action is actually called. The controller
parameter is optional and taken from the controller under test. If it is another controller you are testing then you can specify it:
withFilters(controller:"book",action:"list") {
controller.list()
}
15.1.5 Unit Testing URL Mappings
The Basics
Testing URL mappings can be done with the TestFor
annotation testing a particular URL mappings class. For example to test the default URL mappings you can do the following:
import com.demo.SimpleController
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(UrlMappings)
@Mock(SimpleController)
class UrlMappingsSpec extends Specification {
// ...
}
As you can see, any controller that is the target of a URL mapping that you’re testing must be added to the @Mock
annotation.
Note that since the default UrlMappings class is in the default package your test must also be in the default package
|
With that done there are a number of useful methods that are defined by the grails.test.mixin.web.UrlMappingsUnitTestMixin
for testing URL mappings. These include:
-
assertForwardUrlMapping
- Asserts a URL mapping is forwarded for the given controller class (note that controller will need to be defined as a mock collaborate for this to work) -
assertReverseUrlMapping
- Asserts that the given URL is produced when reverse mapping a link to a given controller and action -
assertUrlMapping
- Asserts a URL mapping is valid for the given URL. This combines theassertForwardUrlMapping
andassertReverseUrlMapping
assertions
Asserting Forward URL Mappings
You use assertForwardUrlMapping
to assert that a given URL maps to a given controller. For example, consider the following URL mappings:
static mappings = {
"/actionOne"(controller: "simple", action: "action1")
"/actionTwo"(controller: "simple", action: "action2")
}
The following test can be written to assert these URL mappings:
import com.demo.SimpleController
import grails.test.mixin.TestFor
import grails.test.mixin.Mock
import spock.lang.Specification
@TestFor(UrlMappings)
@Mock(SimpleController)
class UrlMappingsSpec extends Specification {
void "test forward mappings"() {
expect:
assertForwardUrlMapping("/actionOne", controller: 'simple', action: "action1")
assertForwardUrlMapping("/actionTwo", controller: 'simple', action: "action2")
}
}
Assert Reverse URL Mappings
You use assertReverseUrlMapping
to check that correct links are produced for your URL mapping when using the link
tag in GSP views. An example test is largely identical to the previous listing except you use assertReverseUrlMapping
instead of assertForwardUrlMapping
. Note that you can combine these 2 assertions with assertUrlMapping
.
15.1.6 Mocking Collaborators
The Spock Framework manual has a chapter on Interaction Based Testing which also explains mocking collaborators.
15.1.7 Mocking Codecs
The GrailsUnitTestMixin
provides a mockCodec
method for mocking custom codecs which may be invoked while a unit test is running.
mockCodec(MyCustomCodec)
Failing to mock a codec which is invoked while a unit test is running may result in a MissingMethodException.
15.1.8 Unit Test Metaprogramming
If runtime metaprogramming needs to be done in a unit test it needs to be done early in the process before the unit testing environment is fully initialized. This should be done when the unit test class is being initialized. For a Spock based test this should be done in the setupSpec()
method. For a JUnit test this should be done in a method marked with @BeforeClass
.
package myapp
import grails.test.mixin.*
import spock.lang.Specification
@TestFor(SomeController)
class SomeControllerSpec extends Specification {
def setupSpec() {
SomeClass.metaClass.someMethod = { ->
// do something here
}
}
// ...
}
package myapp
import grails.test.mixin.*
import org.junit.*
@TestFor(SomeController)
class SomeControllerTests {
@BeforeClass
static void metaProgramController() {
SomeClass.metaClass.someMethod = { ->
// do something here
}
}
// ...
}


Quick Start¶
Create a very basic scraper to scrape github search result page:
from scrapex import Scraper
#create a scraper, the central object
s = Scraper(
dir = '.', #define the project directory, by default: use the current working directory
use_cache = True, #enable the cache system
use_cookie = True, #enable cookies
delay = 0.1, # add 0.1 second delay between network requests
retries = 2, #tries 2 more times if a http request failed
log_file = 'log.txt', #enable default logging settings; set to None if you want to set logging yourself
proxy_file = 'path/to/proxy.txt', #each line contains a proxy in host:port format
proxy_auth = 'user:pass' # or None if no authentication required
)
logger = s.logger
#load a page
doc = s.load('https://github.com/search?q=python+web+scraping&type=Repositories&ref=searchresults')
#extract the headline using xpath
headline = doc.x("//h3[contains(text(), 'result')]").trim()
logger.info(headline)
#extract the result count from the headline using regex
logger.info('result count: %s', headline.subreg('([\d\,]+)'))
#select all result nodes. q means query
rs = doc.q("//ul[@class='repo-list js-repo-list']/li")
logger.info('# of listings on first page: %s', len(rs))
#loop through each result, and save details to a csv file
for r in rs:
s.save([
# a list of name,value pairs.
# the names will become the csv's column names
'title', r.x(".//h3"),
'url', r.x(".//h3/a/@href"),
'short description', r.x("p"),
#firstly query all the tag links INSIDE this r node, then join the link text by a comma
'tags', r.q("div/a[contains(@class, 'topic-tag')]").join(', ')
],
#the csv filename, located inside the project's directory
'result.csv'
)
==> The console screen:
INFO: start
INFO: We’ve found 763 repository results
INFO: result count: 763
INFO: # of listings on first page: 10
INFO: Completed successfully
INFO: time elapsed: 0.0 minutes 0.17 seconds


In the example above, we let the ul element and the a element float to the left. li elements will be displayed as inline elements (no line break before or after the element). This forces the list to be on one line. The ul element has a width of 100% and each hyperlink in the list has a width of 6em (6 times the size of the current font). We add some colors and borders to make it more fancy.


| From Address | To Address | Value | Fee | Date Created | Mined in block |
|---|---|---|---|---|---|
|
{{transactions.fromAddress}} |
{{transactions.toAddress}} |
{{transactions.value}} | {{transactions.fee}} | {{transactions.dateCreated | date: 'dd/MM/yyyy HH:mm:ss'}} | {{transactions.minedInBlockIndex}} |


Welcome to the best place on the net to find an informative list of various live-action movie adaptations of video game stories! Not all of these "priceless gems" are what many critics and/or fans of the original source material would call "good", but who knows, you may be someone who ends up liking some of them. Whether you "like" any of these movies ironically or unironically is up to you!
Below is an ongoing list of well-known video game movie adaptations that have been released in theaters. The information this database currently provides includes:
Here is the list of currently released movie adaptations of video games:
| Movie | Original Video Game Series | Movie Release Date |
|---|---|---|
| Assassin's Creed | Assassin's Creed series | Dec 21, 2016 |
| Doom | Doom series | Oct 21, 2005 |
| Final Fantasy: The Spirits Within | Final Fantasy series | Jul 11, 2001 |
| Hitman | Hitman series | Nov 21, 2007 |
| Hitman: Agent 47 | Hitman series | Aug 21, 2015 |
| Lara Croft Tomb Raider: The Cradle of Life | Tomb Raider series | Jul 25, 2003 |
| Lara Croft: Tomb Raider | Tomb Raider series | Jun 15, 2001 |
| Max Payne | Max Payne series | Oct 17, 2008 |
| Mortal Kombat | Mortal Kombat series | Aug 18, 1995 |
| Mortal Kombat: Annihilation | Mortal Kombat series | Nov 21, 1997 |
| Need for Speed | Need for Speed series | Mar 14, 2014 |
| Prince of Persia: The Sands of Time | Prince of Persia series | May 28, 2010 |
| Resident Evil | Resident Evil series | Mar 15, 2002 |
| Resident Evil: Afterlife | Resident Evil series | Sep 10, 2010 |
| Resident Evil: Apocalypse | Resident Evil series | Sep 10, 2004 |
| Resident Evil: Extinction | Resident Evil series | Sep 21, 2007 |
| Resident Evil: Retribution | Resident Evil series | Sep 14, 2012 |
| Resident Evil: The Final Chapter | Resident Evil series | Jan 27, 2017 |
| Silent Hill | Silent Hill series | Apr 21, 2006 |
| Silent Hill: Revelation | Silent Hill series | Oct 26, 2012 |
| Street Fighter | Street Fighter series | Dec 23, 1994 |
| Street Fighter: The Legend of Chun-Li | Street Fighter series | Feb 27, 2009 |
| Super Mario Bros. | Mario series | May 28, 1993 |
| The Angry Birds Movie | Angry Birds series | May 20, 2016 |
| Warcraft | Warcraft series | Jun 10, 2016 |
| Wing Commander | Wing Commander series | Mar 12, 1999 |


Is there a Discord server?
Yes there is, and you can join
it right
here! You are free to send bug reports or just interact with
other members!
How do I play?
The default buttons are the left and right mouse buttons and the Z and X keys, which can be changed in the
settings.
The circles that appear on the game screen are called strike circles. When the circle outside the circle
shrinks and just falls on the circle, click the circle.
Some circles are long sliders, you need to hold down click on the circle and follow it to comple the slider.
When a large blue circle appears on the screen, click and hold the then quickly spin around the center of
the circle.
The cursor movement seems to be a bit delayed?
Try to enable the "Enable system cursor" option in the settings, which can reduce the delay of cursor
feedback. However, some operating systems or browsers may have problems such as flickering or inability to
display the cursor, so it's turned off by default. In addition, the current cursor size adjustment of the
hardware cursor is only fixed to 3 levels, the smallest value is displayed below 0.65, and the largest value
is displayed above 0.95.
The game is freezing/very choppy what do I do?
You can uncheck "Use system resolution" in the settings and set the resolution to a value lower than 100%.
It is recommended to avoid high CPU usage, close other tabs of the browser or close other applications.
Please make sure you are using a mainstream modern browser (such as Firefox, Chrome).
Why is the site blank?
It may be that the API that provides the beatmaps is broken/offline. You can check if that's the case by
looking here:
Sayobot, if so wait and come back later.
To prevent this add beatmaps to your favorites and they will not be affected by API errors.
Can I upload a beatmap from a local osz file?
Not yet.


No search
Found 0 matches in 0 Haplotypes. This is approx. 1 match in 0 Haplotypes (95% CI: 0 - 0)
Found no match in 0 Haplotypes
No search
(n + 1)/ (N +1). This is approx. 1 match in 0 Haplotypes (95% CI: 0 - 0)
Kappa This is approx. 1 match in 0 Haplotypes


Welcome to Salmon's cookie sales data Department
Home
A New Branch
Branch
Min Customer
Max Customer
Avarage Customer
Save
Salmon's cookie sales data Department


The theories behind why Bristol is called Bristol
It hasn't always had the same name
by Tristan CorkAh Bristol. It’s a city, a county and a state of mind.
It’s given its name to a car, a way of tidying and making secure, a way of categorising poo and a rhyming slang for breasts.
As a place, it’s been replicated across the world, from Peru to Canada. Here in the original Bristol, the word Bristol is said so much it’s easy to forget what it means as a word.
So what does it mean? We know it so well, but where does the word Bristol come from?
Just as Bristol itself is a city of contrasts and diversity, the word itself has several different theories to its origin.
Firstly, it never used to be called Bristol. The very first ‘city’ was up in Leigh Woods, in a beautiful spot with the Avon Gorge on one side, Nightingale Valley on the other, and defended on a third side by a bank and ditch fort.
Back in those Celtic British and Roman days, the place was called Caer Odor, which is said to mean ‘the city of the gap’ - and it’s probable the gap in this case refers to Avon Gorge.
Back in those days, before the Saxons came, the people living around the river spoke an early form of Welsh, but a proposed etymology for Bristol comes from further afield. The Irish had a strong influence in Bristol’s history - it was closely linked through trade, and St Patrick himself was originally from these parts before being taken to Ireland as a slave.
One theory that has been proposed is that Bristol’s name is Irish - from the two words Braos and Tuile, which apparently mean a ‘stream through a chasm’.
But while this theory has bubbled up into a few online lists, it appears to have no basis in reality.
Etymologists and language experts tend to base their theories on tracing the changing ways names were spelled through time - and it is by doing this we can sort their origins.
Back in medieval times, Bristol had a variety of spellings, which often included a ‘C’ or a ‘G’ after the ‘Bri’.
Indeed, the word ‘Brygstow’ or ‘Brigstow’ is in use in the city today, albeit in a kind of renewal rather than survival.
This supports the theory Bristol evolved from the two early English words for Bridge and Stow (meaning meeting place).
So Bristol simply means ‘the meeting place at the bridge’. The spot across the River Avon roughly where Bristol Bridge stands now is likely to have had a bridge for millennia, and the early town - which boasted a huge population of around 10,000 back in the 13th century - would have grown up around that key crossing point.
But we're not quite done - how this became ‘Bristol’ is a matter of some debate.
The story goes that everyone else called it, and wrote it as Brigstow, or Bristow, but because Bristolians have a penchant for adding the letter ‘L’ to the end of vowel-ending words, that morphed over time into Bristol.
However, Brian Iles, who has spent decades researching the unique ‘Terminal L’ in the Bristol dialect, isn’t convinced.
He said there is no definitive evidence of the Terminal L being in use in Bristol before the 19th century, centuries after Bristow became Bristol.
So, we're all clear now, yes? Good.
For the latest news in and around Bristol, visit and bookmark Bristol Live's homepage.


Do you have a question or comment about our products?
We welcome feedback and would love to hear from you
If you prefer to contact us by mail, please send correspondence to:
Consumer Affairs Dept.Chattem, Inc.
P.O. Box 2219
Chattanooga, TN 37409-0219
Can't find our products?
Go here to discover where your favorite Rolaids products are available.


| Uraplast S 5561 LP General Information
-
| Molecular Weight: |
2750 (approx) |
| Chemical Category: |
Polymeric plasticizers |
| Moisture Content, wt. %: |
0.1 |
Usage and Performance Characteristics
-
| Manufacturer: |
DSM Resins bv |
| Outstanding Properties: |
Resistance to edible oils & fats, low migration |
| Used for Polymeric Materials: |
PVC |
| Used for Products: |
Foil, beverage hoses, protective clothing & coatings |
| Extraction, heptane 24 h at 23°C, %: |
0.2 (40 phr); 0.3 (60 phr); 0.4 (80 phr) |
| Extraction, peanut oil 24 h at 70°C, %: |
0.9 (40 phr); 1.9 (60 phr); 2.8 (80 phr) |
| Extraction, soapy water 7 days at 70°C, %: |
3 (40 phr); 7 (60 phr); 9.5 (80 phr) |
| Extraction, water 7 days at 70°C, %: |
3 (40 phr); 7.1 (60 phr); 10 (80 phr) |
| Low-temperature Flexibility, °C: |
4 (40 phr); -11 (60 phr); -22 (80 phr) |
| Migration to PE 10 days at 70°C, %: |
0.05 (40 phr); 0.07 (60 phr); 0.1 (80 phr) |
| Migration to PS 10 days at 70°C, %: |
0 (40 phr); 0.01 (60 phr); 0.1 (80 phr) |
| Volatility, wt. %: |
0.22 (24 h at 100°C, 40 phr); 0.28 (24 h at 100°C, 60 phr); 0.32 (24 h at 100°C, 80 phr) |
Physical Properties
-
| Aggregate State at 25°C: |
Liquid |
| Tensile Strength, MPa: |
32 (40 phr); 29 (50 phr); 27 (60 phr); 24 (70 phr); 22 (80 phr) |
| 100% Modulus, MPa: |
20 (40 phr); 18 (50 phr); 14 (60 phr); 12 (70 phr) |
| Density, kg/m3: |
1,120 (25°C) |
| Dynamic Viscosity, cP: |
6,500 (average) (25°C) |
| Shore A Hardness: |
86 (60 phr, 3 s) |
| Ultimate Elongation, %: |
325 (40 phr); 355 (50 phr); 380 (60 phr); 420 (70 phr) |
Chemical Properties
-
| Acid Number, mg KOH/g: |
<1 |
Optical Properties
-
| Refractive Index: |
1.469 (n25D) |
Hazard-Related Data
-
| Food Law Approvals: |
Approved for food contact |
Plasticizers Database (2nd Electronic Edition) Copyright © 2004 by ChemTec Publishing |


{{ with $featured }} {{ range $page := $featured }} {{ partial "featured-story.html" $page }} {{ end }} {{ end }} {{ with $pinned }} {{ range $page := . }} {{ partial "pinned-story-list.html" $page }} {{ end }} {{ end }}


Sanofi's strategy boss to leave as CEO readies revamp
PARIS: Sanofi's executive vice president in charge of strategy and business development, Muzammil Mansuri, a member of the French drugmaker's executive committee, will leave the firm by the end of the month, according to a memo seen by Reuters.
The decision marks the first important management change taken since Paul Hudson became chief executive of Sanofi on Sep 1, as he prepares to give pointers about his vision for the company next month.
Hudson and his teams are engaged in a strategic review and are expected to unveil the company's priorities for the coming years at an investor day in Cambridge, Massachusetts in December.
Mansuri, who joined Sanofi in 2016 from Gilead Sciences , will be retiring from the company, according to the document sent to staff on Wednesday.
Hudson said in the memo that Alban de la Sabliere, currently head of business development, and Laurent Van Lerberghe, head of strategy, would take on more responsibilities as of Dec 1 and report directly to him.
A spokesman for Sanofi could not provide any immediate comment.


Banner
This is a website that offers alpaca api users an alternative to the regular website
Stocks
We offer a variety of metric dashboards that allow you to gain a deeper insight into the stocks your algorithim is trading.
This is a website that offers alpaca api users an alternative to the regular website
We offer a variety of metric dashboards that allow you to gain a deeper insight into the stocks your algorithim is trading.


--- layout: page title: Page not found (404) main_image_path: main_nav: false sidebar: about-sidebar.html --- Sorry, we're lost! Use the menus to navigate your way around, or return to the home page.
Sorry, we're lost! Use the menus to navigate your way around, or return to the home page.


  The 10% FR funds development, we will never sell data to anybody about Hush users. I would rather delete the Hush git repo and stop working on it
[dscrd-hush] <Privatoshi> It's cool to say, we are Hush and we do this.
It's better to say, we are Hush and we do this, and these guys do this. And this is why we want you to use Hush
[dscrd-hush] <dukeleto> Loki, that is a real project, but I don't know how their messenger works. I think it requires their masternodes
[dscrd-hush] <dukeleto> Hush has always been against masternodes
[dscrd-hush] <Privatoshi> And if other projects do good things, good.
But we know what we do
[dscrd-hush] <dukeleto> Loki is built on Monero codebase, and that has no memo field. There is no way to do chat-based stuff directly on the blockchain, with standard XMR tools. Maybe they added stuff, but it makes me feel like the chat messages are just routed by masternodes, but not actually on the blockchain. I have no idea
[dscrd-hush] <Privatoshi> People know Duke Leto and know that he is trustworthy, and they know what he has done.
You have a proven record of working with privacy.
[dscrd-hush] <dukeleto> I read the Loki whitepaper over a year ago and I don't think it said much about chat then
[dscrd-hush] <Privatoshi> You think it's nothing to do with monero
[dscrd-hush] <Privatoshi> It is something separate, an add on
[dscrd-hush] <dukeleto> So, masternodes get paid to route your chat messages, that is what I think Loki is doing
[dscrd-hush] <dukeleto> Monero has no memo field, and so it has no way to send encrypted data to your recipient
[dscrd-hush] <dukeleto> Only Zcash protocol does that. Now, I am not a Monero expert, and maybe things have been extended or changed. But that is how I understand it
[dscrd-hush] <Privatoshi> I'll go ask. And download the white paper
[dscrd-hush] <dukeleto> There will be different implementations of chat than Hush will implement. All Hush operations are "on-chain"
[dscrd-hush] <dukeleto> File uploads, every chat message, every single one is stored on-chain forever
[dscrd-hush] <Privatoshi> What is the advantage/disadvantage to that?
[dscrd-hush] <dukeleto> in encrypted form
[dscrd-hush] <dukeleto> scalability is the concern
[dscrd-hush] <Privatoshi> I see
[dscrd-hush] <dukeleto> but, also, it opens up use cases
[dscrd-hush] <dukeleto> many use cases of HushList, absolutely need on-chain stuff. Otherwise, you can't prove that you knew something at a certain time, and you wouldn't get all the censorship-resistance
[dscrd-hush] <dukeleto> Every Hush full node is a backup of all data stored on Hush blockchain
[dscrd-hush] <Privatoshi> Really?
[dscrd-hush] <Privatoshi> All of it
[dscrd-hush] <dukeleto> Yes
[dscrd-hush] <dukeleto> memo fields are encrypted
[dscrd-hush] <dukeleto> only owners of the private key of the receiving address can decrypt it
[dscrd-hush] <dukeleto> but it's all there, encrypted, on every single Hush full node
[dscrd-hush] <dukeleto> So, protip: For sensitive data, encrypted data AGAIN, inside the memo field, is a good idea. Just plan for the worst
[dscrd-hush] <Privatoshi> I guess it's necessary to have all of the data
[dscrd-hush] <dukeleto> nodes can choose to delete some data, but all full nodes have access to the data. Some full nodes can "prune" their data to use less disk space
(edited)
[dscrd-hush] <Privatoshi> I just got a laptop
[dscrd-hush] <Privatoshi> I'm going to start download tonight
[dscrd-hush] <dukeleto> current Hush blockchain is about 600MB on disk
[dscrd-hush] <dukeleto> and you need to download 50MB of sapling files
[dscrd-hush] <Privatoshi> Np
[dscrd-hush] <Privatoshi> That's not too bad
[dscrd-hush] <Privatoshi> Verus Agama took forever to dl
[dscrd-hush] <dukeleto> if you are using hush binaries, they still might download more stuff. It's only the newest code that got rid of that and we haven't released binaries yet
[dscrd-hush] <Privatoshi> Had to download Zcashparams
[dscrd-hush] <dukeleto> yes, it will do all that stuff
[dscrd-hush] <dukeleto> in the future binaries, those downloads won't be necessary
[dscrd-hush] <Privatoshi> It's just a DL
[dscrd-hush] <Privatoshi> Thats a small thing lol
[dscrd-hush] <Privatoshi> I can't find it in me, to ever bitch about a DL or setup lol
[dscrd-hush] <Privatoshi> People work too hard for that
[dscrd-hush] <dukeleto> Well, I appreciate that. Many of us have access to good internet
[dscrd-hush] <dukeleto> Mostly I work on that stuff for all the people without good internet, and also for Tor users, where bandwidth is at a premium
[dscrd-hush] <dukeleto> and the #1 reason, was because it bothered me. None of those downloads were actually needed, but because of lots of technical debt, were required for no good reason. That just really bothered me
[dscrd-hush] <dukeleto> I had to modify freaking Rust code to prevent those files from being downloaded, and at first I gave up but then went back to it and figured it out
[dscrd-hush] <Privatoshi> Yeah we are lucky to have very good access to good internet, at good prices.
[dscrd-hush] <Privatoshi> And a lot of people still use dial-up
[dscrd-hush] <Privatoshi> I used dial up 20+ yrs ago
[dscrd-hush] <Privatoshi> 1/5th of a century ago
[dscrd-hush] <Privatoshi> That's perspective
[dscrd-hush] <Privatoshi> Internet isn't everything.
But it is something to be thankful, that we have this technology and it's easy to access and not expensive
[dscrd-hush] <Privatoshi> With that appreciation, then we can begin to understand the need for privacy


13. DataViews
13.1 Swing Applications
Those who have experience of Swing GUI development
knows how much time it takes to work out all the minutest details of
formatting, in-place input validation, handling the interactive data
modification, enforcing naming, order, and formatting consistensy, etc.
Whenever the domain or requirements change (e.g. new attributes
are added to an ObjEntity, formats or captions of data are modified,
or relationships change their meaning) developers are faced with the necessity
to go through the number of Swing data models, panels, various helpers fishing
out the bits of code to be corrected.
Another problem is the need for quick and easy prototyping of
data aware GUIs. Those who, at one time or another, worked with Borland
VCL for C++ or Delphi or DataExpress/dbSwing for Java and similar
frameworks can recall how painless it was to create a rough prototype of
the GUI working with the relational database and bind it to the actual
data. That was possible due to the layer of easily configured data aware
classes and components. And once the working prototype had been ready, refinining
it used to be a very simple task.
Cayenne DataViews solve these problems. Data Views act as a
bridge between the domain defined in terms of Cayenne DataObjects and a
presentation layer built with Swing. Potentially they can be used in the Web
environment as well, but Swing integration is the main direction.
Conceptually, Data Views are close to the application facades described, for instance,
by Martin Fowler.
The following figure shows the area where Data Views can be applied.
Validation Note
The validation rules mentioned in the Use Cases are meant to be
"lightweght", i.e. it is generally agreed the validation related
code to enforce the business rules should be located in the domain area
but, still, there are various checks one could prefer to perform right in
the presentation layer like inclusion in a predefined range of values,
correct input format, sometimes, even preliminary credit card number
validity check with the well known Luhn algorithm, the other kinds of
sanity checks. Presently the validation is on the list of the features to
be added.
|
|


Kia Ora, Welcome
I am a Rutherford Discovery Fellow and a Senior Lecturer of Software Engineering at the University of Auckland, New Zealand in the Department of Electrical, Computer, and Software Engineering. I lead the Human Aspects of Software Engineering Lab (HASEL), check it out at
https://hasel.auckland.ac.nz.
My research is mainly in the human and social aspects of software engineering. My current research topics include: software dependencies, software ecosystems, collaborative software development, software requirements engineering, and software developer diversity and inclusion. My research is currently funded by a Royal Society Te Apārangi's Rutherford Discovery Fellowship, the Royal Society Te Apārangi's Marsden Fund, the National Science Challenges Science for Technological Innovation's Veracity Spearhead, and Google.


Location
Longitude
W
E
°
'
"
Latitude
N
S
°
'
"
Time
Date
January
February
March
April
May
June
July
August
September
October
November
December
Time of day
:
:
UTC+12
UTC+11
UTC+10
UTC+09
UTC+08
UTC+07
UTC+06
UTC+05
UTC+04
UTC+03
UTC+02
UTC+01
UTC
UTC-01
UTC-02
UTC-03
UTC-04
UTC-05
UTC-06
UTC-07
UTC-08
UTC-09
UTC-10
UTC-11
UTC-12


{% extends "layout.html" %} {% block bar_heading %} Get an annual MOT reminder {% endblock %} {% block content %} {% include "includes/phase_banner_beta.html" %} Back What is your phone number? Phone numberYour reminder will be sent here What is your email address? Email addressYour reminder will be sent here {% endblock %}


|
||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
| Interface Summary | |
|---|---|
| Robot | An abstract description of what a robot is: a description of the hardware and an implementation of a controller. |
| Class Summary | |
|---|---|
| Description | Common superclass for descriptions. |
Building blocks for constructing simulation scenarios. Can describe module components in terms of their basic geometries, connector configurations etc. The simulation is described in terms of connections between modules and the setup of the enclosing world. Note that the module geometries must be translated into physics engine specific shapes by the corresponding module factory.
The building blocks are organized into the following subpackages:
ussr.description.geometry
Geometry shapes for describing entities in the simulationussr.description.robot
Robot building blocksussr.description.setup
Simulation world setupThe physics parameters of the simulation are set using PhysicsParameters
whereas module factories are manipulated using PhysicsFactory
.
PhysicsParameters
,
PhysicsFactory
|
||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |


ANTZ (1998)
Rating: 3 stars (out of 4.0) ******************************** Key to rating system: 2.0 stars - Debatable 2.5 stars - Some people may like it 3.0 stars - I liked it 3.5 stars - I am biased in favor of the movie 4.0 stars - I felt the movie's impact personally or it stood out *********************************
Directed by: Eric Darnell and Tim Johnson
Written by: Todd Alcot, Chris Weitz, Paul Weitz
Starring: Voices of Woody Allen, Sharon Stone, Gene Hackman
Ingredients: Animated ants, bored worker ant seeking more to life
Synopsis: In an animated underground ant colony consisting of millions of ants, all of the ants are workaholic conformists except two individualistic ants. One is General Mandible (voice of Gene Hackman), a military megalomaniac who secretly plots to destroy the ant colony and create a master race. He plans to take advantage of the conformist ants by getting them to unwittingly carry out his orders.
The other individual is the humble Z, a likable, scrawny, nerdy worker ant (voice of Woody Allen), who decides that there must be more to life than fulfilling a prescribed role. Z secretly wishes for free choice, and rails against conformism in his loquacious monologues.
A series of adventures ensues when Z falls in love with the Princess Bala (voice Sharon Stone), and the two find themselves outside the colony in search of a paradise called Insectopia. Later, Z and Bala must thwart General Mandible's plot to destroy the colony. The moral of the story is that unthinkingly accepting authority could turn you into somebody else's pawn, unless you learn to think for yourself.
Opinion: One of the fun things about watching animated movies is trying to guess the voice behind the character. ANTZ features the recognizable voices of Woody Allen (nerdy ant), Sharon Stone (princess ant), Sylvester Stallone (buffed middle class soldier ant), Gene Hackman (megalomaniac general ant), and Christopher Walken (flying ant). If you're good at this sort of thing, see if you can spot Dan Aykroyd or Jennifer Lopez.
The good news is that ANTZ is an animated movie that adults can watch. The computer effects are superb and there is no shortage of sardonic wit or cultural references. The bad news is that ANTZ is not a kids movie since the Woody Allen-style social commentary isn't intelligible for young children. If forced to sit through it, they get antsy.
Reviewed October 4, 1998
Copyright © 1998 by David Sunga This review and others like it can be found at THE CRITIC ZOO: http://www.criticzoo.com email<EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Add a new observer to the pool. The new observer needs to respond to ‘update’, otherwise it raises an ArgumentError exception.
# File lib/active_model/observing.rb, line 65 def add_observer(observer) unless observer.respond_to? :update raise ArgumentError, "observer needs to respond to `update'" end observer_instances << observer end
Total number of observers.
# File lib/active_model/observing.rb, line 78 def count_observers observer_instances.size end
Instantiate the global observers.
# File lib/active_model/observing.rb, line 58 def instantiate_observers observers.each { |o| instantiate_observer(o) } end
Notify list of observers of a change.
# File lib/active_model/observing.rb, line 73 def notify_observers(*arg) observer_instances.each { |observer| observer.update(*arg) } end
Gets the current observer instances.
# File lib/active_model/observing.rb, line 53 def observer_instances @observer_instances ||= [] end
Gets an array of observers observing this model. The array also provides enable and disable methods that allow you to selectively enable and disable observers. (see ActiveModel::ObserverArray.enable and ActiveModel::ObserverArray.disable for more on this)
# File lib/active_model/observing.rb, line 48 def observers @observers ||= ObserverArray.new(self) end
Activates the observers assigned. Examples:
class ORM include ActiveModel::Observing end # Calls PersonObserver.instance ORM.observers = :person_observer # Calls Cacher.instance and GarbageCollector.instance ORM.observers = :cacher, :garbage_collector # Same as above, just using explicit class references ORM.observers = Cacher, GarbageCollector
Note: Setting this does not instantiate the observers yet. instantiate_observers is called during startup, and before each development request.
# File lib/active_model/observing.rb, line 39 def observers=(*values) observers.replace(values.flatten) end
Generated with the Darkfish Rdoc Generator 2.


|
|
how to install event module |
0 |
1 year 13 weeks ago by sanjyou |
n/a |
|
|
Not able to upload data to emoncms, please help |
8 |
1 year 13 weeks ago by sanjyou |
1 year 13 weeks ago by sanjyou |
|
|
widget jgauge with 2 needles? |
34 |
1 year 13 weeks ago by Larsjo |
1 year 11 weeks ago by chaveiro |
|
|
Remote emoncms logging sampling rate |
0 |
1 year 13 weeks ago by Beire |
n/a |
|
|
generating a "so far today" value |
0 |
1 year 13 weeks ago by sroof |
n/a |
|
|
emonPi_Startup.ino calc_rms BUG |
4 |
1 year 13 weeks ago by CidiRome |
1 year 13 weeks ago by glyn.hudson |
|
|
Emonpi sketch compilation |
3 |
1 year 13 weeks ago by Beire |
1 year 13 weeks ago by Beire |
|
|
Update process from v8 to v9 |
5 |
1 year 13 weeks ago by Paul Reed |
1 year 13 weeks ago by Paul Reed |
|
|
Blank realtime visualisation [SOLVED] |
1 |
1 year 13 weeks ago by dahlma |
1 year 13 weeks ago by dahlma |
|
|
Compass/Windrose widget |
20 |
1 year 13 weeks ago by Paul Reed |
1 year 11 weeks ago by Paul Reed |
|
|
jguages have broken [SOLVED] |
1 |
1 year 13 weeks ago by dod |
1 year 13 weeks ago by dod |
|
|
Manually create Data capture files? |
3 |
1 year 13 weeks ago by llandry |
1 year 12 weeks ago by llandry |
|
|
Emonbase reading wh1081 weather station |
5 |
1 year 12 weeks ago by scubammx |
1 year 10 weeks ago by borpin123 |
|
|
Missing value from emonTH - SOLVED |
5 |
1 year 12 weeks ago by engeeaitch |
1 year 12 weeks ago by engeeaitch |
|
|
My jump to Emoncms V9 |
10 |
1 year 12 weeks ago by boelle |
1 year 11 weeks ago by boelle |
|
|
emonlib to measure power factor of inductive and capacitive reactances |
1 |
1 year 12 weeks ago by itauty |
1 year 12 weeks ago by Robert Wall |
|
|
Dashboard dial min value |
3 |
1 year 12 weeks ago by Beire |
1 year 12 weeks ago by Bill Thomson |
|
|
Someone has written a persistence binding for openHAB -> emonCMS |
0 |
1 year 12 weeks ago by sumnerboy |
n/a |
|
|
New minimal install issues |
12 |
1 year 12 weeks ago by borpin123 |
1 year 12 weeks ago by borpin123 |
|
|
Histogram feed in low-write mode. |
0 |
1 year 12 weeks ago by fcattaneo |
n/a |
|
|
Node Red post to local emoncms |
7 |
1 year 12 weeks ago by larsthiesson |
1 year 12 weeks ago by Paul Reed |
|
|
Download emoncms.org set up |
1 |
1 year 12 weeks ago by bruce_miranda |
1 year 12 weeks ago by pb66 |
|
|
Crontab with emoncms |
3 |
1 year 12 weeks ago by Priya |
1 year 12 weeks ago by Bill Thomson |
|
|
change graph colours |
0 |
1 year 12 weeks ago by smitt1979 |
n/a |
|
|
New virtual feed |
3 |
1 year 12 weeks ago by smitt1979 |
1 year 12 weeks ago by smitt1979 |
|
|
v9.1 update kwh/d |
6 |
1 year 12 weeks ago by Beire |
1 year 12 weeks ago by Beire |
|
|
v9 - Edit Daily visualization errors |
1 |
1 year 12 weeks ago by Paul Reed |
1 year 12 weeks ago by Beire |
|
|
Issues with node activation on local emoncms |
4 |
1 year 12 weeks ago by Patricio Duenas |
1 year 11 weeks ago by Patricio Duenas |
|
|
MySolar app broken? |
0 |
1 year 12 weeks ago by ajscheid |
n/a |
|
|
Input processing Help |
4 |
1 year 12 weeks ago by jideyf |
1 year 11 weeks ago by jideyf |
|
|
Low-write mode - your thoughts please |
42 |
1 year 12 weeks ago by Paul Reed |
1 year 8 weeks ago by glyn.hudson |
|
|
Emoncms.org account has partially frozen. Server error? |
5 |
1 year 12 weeks ago by nrgbod |
1 year 11 weeks ago by nrgbod |
|
|
http://openenergymonitor.org/emon/node/11541 Dead?? |
2 |
1 year 12 weeks ago by boelle |
1 year 11 weeks ago by boelle |
|
|
myApps - [SOLVED] |
4 |
1 year 12 weeks ago by Larsjo |
1 year 11 weeks ago by Larsjo |
|
|
EmonCMS 9.2 , Event Module problem.. |
1 |
1 year 11 weeks ago by fcattaneo |
1 year 11 weeks ago by pb66 |
|
|
Feed API Help |
2 |
1 year 11 weeks ago by rjsc2000 |
1 year 11 weeks ago by borpin123 |
|
|
Counting with Emoncms |
1 |
1 year 11 weeks ago by fversteegen |
1 year 11 weeks ago by chaveiro |
|
|
New Event Module - Features |
13 |
1 year 11 weeks ago by chaveiro |
1 year 4 weeks ago by jcgonzales |
|
|
Virtual Feed Behaving Oddly |
3 |
1 year 11 weeks ago by Esk Energy |
1 year 11 weeks ago by Esk Energy |
|
|
Neurio KW to watts |
0 |
1 year 11 weeks ago by cormad |
n/a |
|
|
Transmit variables from EmonCMS (Rasp or external) to EmonPi |
10 |
1 year 11 weeks ago by CidiRome |
1 year 10 weeks ago by CidiRome |
|
|
Minimal PHPFina data file viewer |
6 |
1 year 11 weeks ago by TrystanLea |
1 year 5 days ago by allmac |
|
|
Git command to up date installation |
3 |
1 year 11 weeks ago by borpin123 |
1 year 11 weeks ago by smitt1979 |
|
|
EmonCMS 9.2 migration data corruption |
18 |
1 year 11 weeks ago by arjen |
1 year 2 weeks ago by efidi13 |
|
|
Continuous Sampling EmonPi and EmonTx v3.4 examples |
58 |
1 year 11 weeks ago by TrystanLea |
41 weeks 4 days ago by Xino |
|
|
Dashboard with Gauge not displaying with Android |
8 |
1 year 11 weeks ago by Esk Energy |
1 year 11 weeks ago by smitt1979 |
|
|
Where should apps (modules) go? |
2 |
1 year 11 weeks ago by borpin123 |
1 year 11 weeks ago by borpin123 |
|
|
emoncms.org rawdata graphs stopped. |
2 |
1 year 11 weeks ago by dBC |
1 year 11 weeks ago by smitt1979 |
|
|
problems with My Electric |
2 |
1 year 11 weeks ago by borpin123 |
1 year 11 weeks ago by borpin123 |
|
|
Cannot get Wh Accumulator to work |
8 |
1 year 11 weeks ago by borpin123 |
1 year 11 weeks ago by Patrik Arlos |


Documentation for the code¶
- clide.clidesc_Obs(conn, table, channels, stations, from_date, to_date)[source]¶
returns the given observations table for the requested stations, date range and columns depends on an open clidDB connection clideDB
Parameters: conn : db connection
A database connection object as returned by clides_open()
table: string
- The table from which the observations are required, can be:
- ‘obs_daily’
- ‘obs_subdaily’
channels : string
The channel to retrieve, ex. ‘wind_speed’, ‘rain_24h’
stations : string
The station(s), if more than one ‘XXXXX, YYYYY’
from_date : string
The starting date in ‘YYYY-MM-DD’ format e.g. ‘2014-01-01’
to_date : string
The end date in ‘YYYY-MM-DD’ format e.g. ‘2014-01-01’
Returns: table : Pandas.DataFrame
A Pandas.DataFrame containing the data
- clide.clidesc_ObsDaily(conn, channels, stations, from_date, to_date)[source]¶
returns the daily observations table for the requested stations, channels and date range.
Parameters: conn : db connection
A database connection object as returned by clides_open()
channels : string
The variable channels in the table
stations : string
The station or stations list
from_date : string
The starting date in ‘YYYY-MM-DD’ format e.g. ‘2014-01-01’
to_date : string
The end date in ‘YYYY-MM-DD’ format e.g. ‘2014-01-01’
Returns: table : Pandas.DataFrame
A Pandas.DataFrame containing the data
- clide.clidesc_ObsSubDaily(conn, channels, stations, from_date, to_date)[source]¶
Read channels for stations (stations) from the obs_subdaily table
Parameters: conn : db connection
A database connection object as returned by clides_open()
channels : string
The variable channels in the table
stations : string
The station or stations list
from_date : string
The starting date in ‘YYYY-MM-DD’ format e.g. ‘2014-01-01’
to_date : string
The end date in ‘YYYY-MM-DD’ format e.g. ‘2014-01-01’
Returns: table : Pandas.DataFrame
A Pandas.DataFrame containing the data
usage:
table = clidesc_ObsSubDaily(clideDB, channels, stations, from_date, to_date )
- clide.clidesc_close(base_path, conn)[source]¶
closes a clide connection
Parameters: base_path : path
The base path
conn : db connection
A database connection object as returned by clides_open()
- clide.clidesc_getColumns(conn, table)[source]¶
Return the column names of a table
Parameters: conn : the postgresql connection
table : string
the table (e.g. ‘obs_daily’, ‘obs_subdaily’)
Returns: columns : Pandas.DataFrame
A Pandas.Series containing the column names
- clide.clidesc_getStationsByCountry(conn, country)[source]¶
Gets all the station details for all stations in a given country code (single or vector). It opens the connection, reads the stations table country must be a string, with country codes (if more than one) separated by ‘,’
Parameters: conn : db connection
A database connection object as returned by clides_open()
country : string
The two letters country identifier e.g. ‘WS’ for Samoa, ‘FJ’ for Fiji, ...
Returns: table : Pandas.DataFrame
A Pandas.DataFrame object containing the list of stations available for the country
- clide.clidesc_open(base_path, database='clideDB', user='XXX', password='XXX', dbhost='localhost')[source]¶
Open the ClideDB database and the progress file
Parameters: base_path : filesystem path
The base path where all the outputs etc are dumped
database : string
The name of the Database (ClideDB usually)
user : string
The username
password : string
The passowrd
dbhost : string
The host server name (‘localhost’ if clide is accessed locally)
Returns: conn : db connection
A database connection object as returned by psycopg2.connect()
- clide.clidesc_rain24h(conn, stations, from_date, to_date)[source]¶
Utility function to read the rain_24h channel from the obs_daily table
Parameters: conn : db connection
A database connection object as returned by clides_open()
stations : string
The station or stations list
from_date : string
The starting date in ‘YYYY-MM-DD’ format e.g. ‘2014-01-01’
to_date : string
The end date in ‘YYYY-MM-DD’ format e.g. ‘2014-01-01’
Returns: table : Pandas.DataFrame
A Pandas.DataFrame containing the data
- clide.clidesc_stations(conn, stations)[source]¶
Gets all the station details for a station number It opens the connection, reads the stations table station_no is a string, with stations separated by ‘,’
Parameters: conn : db connection
Database connection object as returned by clidesc_open()
stations : string
The station or station list if several station should be passed as string, not list e.g. ‘XXXXX, YYYYY, ZZZZZ’
Returns: table : Pandas.DataFrame
A Pandas.DataFrame object containing the station information