Git Product home page Git Product logo

graina2's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graina2's Issues

Improve Maven and Gradle integration coverage

This is a placeholder issue to allow users to suggest particular points to cover, tips & tricks, or anything else they feel has value in the book with regard to the Maven and Gradle coverage.

Chapter 7: refactor example test that uses mocks

One of the example test cases in chapter 7 looks like this:

def "Adding new post via mocked service layer honours functionality"() {

    given: "a mock post service"
    def mockPostService = Mock(PostService)    #1
    1 * mockPostService.createPost(_, _) >> new Post(content: "Mock Post") #2
    controller.postService = mockPostService   #3


    when:  "controller is invoked"
    def result = controller.addPost("joe_cool", "Posting up a storm") #4

    then: "redirected to timeline, flash message tells us all is well"
    flash.message ==~ /Added new post: Mock.*/    #5
    response.redirectedUrl == '/post/timeline/joe_cool'   #6

}

As the call to createPost() is a required interaction and should be verified, it makes sense to move it into the 'then:' block like so:

then: "..."
1 * mockPostService.createPost(_, _) >> new Post(content: "Mock Post")
flash.message ==~ /Added new post: Mock.*/
response.redirectedUrl == '/post/timeline/joe_cool'

To be honest, we should also be verifying the content parameter of the createPost() call! So perhaps the interaction line should be:

when:  "controller is invoked"
def postContent = "Posting up a storm"
def result = controller.addPost("joe_cool", postContent) #4

then: "redirected to timeline, flash message tells us all is well"
1 * mockPostService.createPost(_, postContent) >> new Post(content: postContent)

MEAP v9, chapter 5, code from github : profile for admin is invalid

Code for ch5 downloaded from github have this in grails-app/conf/BootStrap.groovy:

private createAdminUserIfRequired() {
    if (!User.findByLoginId("admin")) {
        println "Fresh Database. Creating ADMIN user."

        def profile = new Profile(email: "[email protected]")
        new User(loginId: "admin", password: "secret", profile: profile).save()
    }
    else {
        println "Existing admin user, skipping creation"
    }
}
  1. fullName is required in Profile class
  2. save() fails silently (because profile contains errors, fullName cannot be null)

The effect of this is that it fails later on in createSampleData() at the time of the first save() with flush:true.

| Error 2013-07-10 15:55:37,978 [localhost-startStop-1] ERROR hibernate.AssertionFailure  - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
Message: null id in com.grailsinaction.Profile entry (don't flush the Session after an exception occurs)

At that point, it is not very easy to see what went wrong as the line where the failure occurs is far from the line having the root cause.

Note that adding failOnError: true in the save() call on admin user won't trigger the exception; only when hibernate actually tries to commit the session to database will it throw the error.

Adding fullName: "Administrator" to creation of profile fixes the issue. I would suggest also using "[email protected]" for the email to be consistent with rest of data created in bootstrap and to add failOnError:true, flush:true to the save() call.

"Listing 5.6 Where queries in action" requires several changes to get it to work

This post is going to ramble a bit.

The QueryIntegrationSpec test class in this listing failed on the "Query against a range value" method. Looking at the sample data in Bootstrap.groovy, I concluded that the assertion needed to change

from: users*.loginId == ["phil", "peter", "glen", "frankie", "chuck_norris", "admin"]
  to: users*.loginId == ["phil", "jeff", "graeme", "frankie", "burt", "admin"]

I wasn't getting the admin user, so after adding some println's I found that the save for admin was failing silently. To get it to work, I changed the code

from:
def profile = new Profile(email: "[email protected]")
new User(loginId: "admin", password: "secret", profile: profile).save()

to:
def profile = new Profile(fullName: "Administrator", email: "[email protected]")
def user = new User(loginId: "admin", password: "secret", profile: profile, dateCreated: new Date())
user.save(failOnError: true, flush: true)
println "Created user " + user + " dateCreated=" + user.dateCreated

I also added a println to the createSampleData() method and discovered that the createAdminUserIfRequired() method is called before the createSampleData() method in the Bootstrap.groovy code:

    def init = { servletContext ->
        environments {
            development {
                if (!Post.count()) createSampleData()
            }
            test {
                if (!Post.count()) createSampleData()
            }
        }

        // Admin user is required for all environments
        createAdminUserIfRequired()
    }

So it appears that the environments {} block is a configuration instruction that will get executed after any method calls that come after that block. It would be helpful if you added a comment that tips us off to the execution order of what happens inside the init block.

Thanks!

MEAP v8 ch.3 - 3.4.3 (p82) : wrong references

Current :

In listing 3.15, we’re able to call User.addToTags() because Tag belongsTo
User. We’re also able to call Post.addToTags() because Tag belongsTo Post.
But Post doesn’t belongTo Tag, so we can’t call Tag.addToPosts().

The only part where "User.addToTags()" is called is in listing 3.19, it's the same for Post.addToTags(). Maybe it's in the wrong place ?

Little suggestion :

But as shown in listing 3.16, Post doesn’t belongTo Tag, so we can’t call Tag.addToPosts().

Explanation :

The important part is changing the place of the paragraph, but I think it won't hurt to reference 3.16 in order to explain the last sentence.

From : http://www.manning-sandbox.com/thread.jspa?messageID=141570&#141570

MEAP v11, chapter 5, suggestion for advSearch : "%${value}%"

The dynamic search (after figure 5.9) as written does exact match, but that may not be obvious to the reader. I think using ilike field, "%${value}%" would make things easier to understand. At least, it would support the natural tendency to enter a part of a name, like 'rocher', to search for 'Graeme Rocher'.

Error in code in 6.1.2, Listing 6.x (MEAP v7)

package com.grailsinaction
import grails.test.mixin.TestFor
import spock.lang.Specification
import grails.test.mixin.Mock
@TestFor(PostController)
@Mock(User)
class PostControllerSpec extends Specification {
    def "Get a users timeline given their id"() {
        given: "A user with posts in the db"
            User chuck = new User(userId: "chuck_norris", password:
                                "password").save(failOnError: true)
            chuck.addToPosts(new Post(content: "A first post"))
            chuck.addToPosts(new Post(content: "A second post"))

        and: "A userid parameter"
            params.id = chuck.userId

        when: "the timeline is invoked"
            def model = controller.timeline()

        then: "the user is in the returned model"
            model.user.userId == "chuck_norris"
            model.user.posts.size() == 2
    }
}

This code will produce an error when we launch grails test-app:. The error is:
"No signature of method com.grailsinaction.User.addToPosts() is applicable for argument types : (com.grailsinaction.Post) values: [com.grailsinaction.Post : (unsaved)]"

To correct it, I had to modify the @mock statement as follows :
@Mock([User, Post])

MEAP v10 page 12, references to listing 1.7 out of sync

We read:

"Finally, we get to the body of the page. We output our common masthead div to get our Web 2.0 gradient and cute icons, and then we call <g:layoutBody> to render the BODY section of the target page #4."

That should be #5; #4 is layoutResources, which is not explained

`register2` action does not work

It seems that the UserController.register2() action returns a model on two of its code paths. Unfortunately, there is no register2 view, so those code paths result in 404s.

The action should either render the register view or redirect to it. Alternatively, we add a register2 action, but that's my least preferred option.

Grails_in_Action_Se_v11_MEAP link downloads v10

Hi everyone,
while I'm trying to download last Grails in Action Second Edition v11 it is version 10 the version I'm downloading. That's why the new chapter, chapter 9, is not included.

I think that maybe the link was not well uploaded to manning website.

meap_v11

Thank you

Error after creating domain class:-Javassist Enhancement failed: qotd.Quote

I am new to Grails. Just followed graina2 step by step....

After creating domain class Quote.groovy and running:--

import qotd.*
def quote = Quote.findByAuthor("Chuck Norris Facts")
println quote.content

In Groovy Console, I get error as_-
No property found for name [author] for class [class qotd.Quote]

cmd window shows:--
Javassist Enhancement failed: qotd.Quote
groovy.lang.MissingPropertyException: No such property: hasProperty for class: groovy.lang.MetaClassImpl
at grails.ui.console.GrailsSwingConsole.runInstance(GrailsSwingConsole.g
roovy:61)

I am not sure, Am I missing something?

5.2.2 No ClassCastException

The book says that when the following code is run as a script in the console:

Post.where { user.loginId == 12 }.list()

we should see a ClassCastException because loginId is a String property and 12 is not a String.

Actually, the integer is automatically converted to a String so no ClassCastException is thrown. I verified this by adding the following code to Bootstrap.groovy:

        def twelve = new User(loginId: "121212",
                password: "aaaaaa",
                profile: new Profile(fullName: "Twelfth man", email: "[email protected]"),
                dateCreated: now - 2).save(failOnError: true)

        twelve.addToPosts(content: "Very first post")
        twelve.addToPosts(content: "Second post")
        twelve.save(failOnError: true)

and changing the console script to:

import com.grailsinaction.*
println Post.list().user.loginId
println Post.where { user.loginId == 121212 }.list()
println "There are ${Post.count()} posts in the database"

The script results were:

groovy> import com.grailsinaction.* 
groovy> println Post.list().user.loginId 
groovy> println Post.where { user.loginId == 121212 }.list() 
groovy> println "There are ${Post.count()} posts in the database" 

[121212, 121212, dillon, sara, phil, sara, phil, sara, phil, phil, sara, sara, sara, phil, phil]
[com.grailsinaction.Post : 8, com.grailsinaction.Post : 9]
There are 15 posts in the database

MEAP v9, chapter 5, listing 5.6 : user names needs update

Test "Query against a range value" expects a list of user names (loginId) that are not part of what is created in BootStrap.

Assertion should read

users*.loginId == ["phil", "jeff", "graeme", "frankie", "burt", "admin"]

instead.

Meap V12:-- JVM bind error with ctrl-c

As per page 10, If I close the application with ctrl-c and again run the application, I get the error:-
java.net.BindException: Address already in use: JVM_Bind:8080

I need to manually kill the earlier process and restart again. Is this a problem with closing the applicaion with ctrl-c

Too many white spaces between text in PDF

Hi Peter,

Please look into the first line on page 7 in PDF and you will see there is too many spaces in between the words. You might not see this issue in LATEX if you are using it to write the book.

whitespaces

Please look the attached image.

Regards,
Rasheed

Listing 5.1 Initial attempt at generating sample data

Could you emphasize that the Bootstrap.groovy file in the GitHub repository must be downloaded for the tests in this chapter to work?

I had copied this listing to create my own Bootstrap.groovy file and practiced creating my own sample data.

My approach in working through the book is to copy code from the book's listings and use the command line to ensure I am understanding every step it takes for all files to appear in the project. I'm not just copying all project files from the repository and then reading the chapter. So reminders about which repository files are required or assumed to be downloaded would be helpful. Thanks!

/grails-app/conf/BuildConfig.groovy is created by default

Hi Peter,

On page 6 I think there is typo mistake. It states:

"...you can create a custom /grails-app/conf/BuildConfig.groovy file with an entry for..."

Since BuildConfig.groovy is created by default; it shouldn't be mentioned that one should create it.

Thanks,
Rasheed

MEAP ch1 v12, Section 1.5.1

I am new to Groovy and Grails, and following the Grails In Acton 2nd Edition step-by-step to learn from scratch. Have a question on Section 1.5.1 Scaffolding: add rocket fuel

Question:

After following step-by-step, and browsing to http://localhost:8080/qotd/quote/list gives the following error (have also attached a figure)

HTTP Status 404 - /qotd/quote/list
type Status report
message /qotd/quote/list
description The requested resource is not available.
Apache Tomcat/7.0.42
qotd_quote_list

However, browsing to http://localhost:8080/qotd/quote/create works fine (matches with Figure 1.12 in the book), and I am able to create a new quote. At this url, if I hover/click on the "Quote List" button it shows/takes me to http://localhost:8080/qotd/quote/index (and NOT to the list of quotes). Please see that attached figure.
qotd_quote_create

The versions I am using are:
App version: 0.1
Grails version: 2.3.1
Groovy version: 2.1.8
JVM version: 1.7.0_45

Is this a bug in Grails or I am missing something?

Thank you and any help would be highly appreciated.

MEAP V10 - Still a lot of code snippets in the book with userId instead of loginId

The code on GitHub is consequently using User.loginId but there are still a lot of code snippets using User.userId

No big deal and I assume this is something that you already planned to clean up but just so you don't miss it I put a ticket for it now.

Some of the references, there are more and easily found by search in the pdf document:
Listing 3.3
Listing 3.11
Listing 6.1 (findByUserId, GitHub code is findByLoginId)

Clarify use of grails.project.groupId in chapter 1 example

The "A Word on Package Naming" sidebar doesn't make it clear whether the example QOTD application is using the grails.project.groupId setting or not. For example, figure 1.8 shows the qotd package being used rather than com.grailsinaction.qotd.

Is the latter just an example suggestion? If so, then the sidebar should make this clear and point out that the default qotd is used throughout the chapter and the GitHub source code. Otherwise, the examples need updating to use com.grailsinaction.qotd.

MEAP v10 page 4: Grails is now shipped with Tomcat

We read:

"Grails ships with a copy of Jetty (an embeddable Java web server—there is talk that a future version will switch to Tomcat)"

Grails 2.2.3 apparently runs Tomcat by default. From the qotd welcome page:

Application Status

App version: 0.1
Grails version: 2.2.3
Groovy version: 2.0.8
JVM version: 1.7.0_25
Reloading active: true
Controllers: 2
Domains: 1
Services: 3
Tag Libraries: 13

Installed Plugins

i18n - 2.2.3
logging - 2.2.3
core - 2.2.3
urlMappings - 2.2.3
resources - 1.1.6
jquery - 1.8.3
databaseMigration - 1.3.2
webxml - 1.4.1
tomcat - 2.2.3 <---
controllers - 2.2.3
codecs - 2.2.3
domainClass - 2.2.3
converters - 2.2.3
dataSource - 2.2.3
filters - 2.2.3
groovyPages - 2.2.3
servlets - 2.2.3
mimeTypes - 2.2.3
hibernate - 2.2.3
validation - 2.2.3
scaffolding - 2.2.3
services - 2.2.3
cache - 1.0.1

Downloading code for each chapter

Please consider adding instructions for downloading the GitHub code at the beginning of each chapter. Once you fix the Profile.groovy belonging to User problem, it works flawlessly if I replace my hubbub directory with the hubbub subdirectory for that chapter.

The big gotcha, of course, is that the code is specifically for v2.2.1. At the beginning of the book, it says to download the latest grails version. That leads to all kinds of problems. Using v.2.2.1 avoids the hassle of upgrades, googling config changes needed for jar incompatibilities, etc.

I think you should consider suggesting how to download and organize multiple versions of grails, and then swap them in and out with environment variables. Maybe not many people need that kind of advice, but the ones that do will probably really appreciate it.

Listing 3.14: clarify annotations

From this post on the Manning forums, current:

List<String> sortedPostContent = foundUser.posts.collect { it.content }.sort() #2
[...]
sortedPostContent == ['First', 'Second', 'Third'] #3
[...]

#2 Iterates through User’s posts
#3 Sorts posts alphabetically
[...]

for our test case we sort them alphabetically to make the comparison meaningful #3

Suggestion :

#2 Iterates through User’s posts and sort them alphabetically
#3 Compare retrieved values to known values

[...]

for our test case we sort them alphabetically to make the comparison meaningful #2

MEAP v9, p76, "Refactoring homepage and breaking tests" refers to unexisting User() constructor.

The "Refactoring homepage and breaking tests" on page 76 tells us to update User() constructors to change user.homepage with user.profile.homepage, but there is no constructor in User class (at that point) and what needs to be done to fix tests is more than just updating the references, as we have to stop trying to assert on homepage as it is now validated with Profile, not User (as per the comments in UserIntegrationSpec).

I think mentionning the effect of extracting homepage into another instance, with respect to validate() and thus asserts in spec tests, would be a good addition here.

MEAP v13, chapter 3, section 3.4.3 Many-to-many relationships

The discussion related to "Listing 3.15 The Tag object models relationships to both Post and User" doesn't explain why the Tag class has a back reference to the User class. Given that back reference, it also doesn't explain why the belongsTo in Tag must use that particular form in order to support the user back reference. Consequently, while the discussion about the Post-Tag relationship is fine, the discussion of the User-Tag relationship is quite weak.

MEAP ch1 v12, Issues with *Spec.groovy vs. *Tests.groovy

When I run grails create-*, instead of generating *Tests.groovy (as mentioned in the book), it generates *Spec.groovy. Below are the examples.

Example 1: Pg. 10
grails create-controller quote creates
| Created file test/unit/qotd/QuoteControllerSpec.groovy
instead of (as mentioned in the book)
| Created file test/unit/qotd/QuoteControllerTests.groovy

Example 2: Pg. 17
grails create-domain-class quote creates
| Created file test/unit/qotd/QuoteSpec.groovy
instead of (as mentioned in the book)
| Created file test/unit/qotd/QuoteTests.groovy

Example 3: Pg. 25
grails create-service quote creates
| Created file test/unit/qotd/QuoteServiceSpec.groovy
instead of
| Created file test/unit/qotd/QuoteServiceTests.groovy

Anyways, I added a method called testStaticQuoteReturnsQuicheQuote in my QuoteServiceSpec.groovy class as follows, and then ran grails test-app QuoteServiceSpec and it did NOT run any tests (in the command prompt I got | Completed 0 unit test, 0 failed in 0m 1s).

Here is my QuoteServiceSpec.groovy class.

package qotd

import grails.test.mixin.TestFor
import spock.lang.Specification

/**
 * See the API for {@link grails.test.mixin.services.ServiceUnitTestMixin} for usage instructions
 */
@TestFor(QuoteService)
class QuoteServiceSpec extends Specification {

    def setup() {
    }

    def cleanup() {
    }

    void "test something"() {
    }
    
    void testStaticQuoteReturnsQuicheQuote(){
        Quote staticQuote = service.getStaticQuote()
        assertEquals("Anonymous", staticQuote.author)
        assertEquals("Real Programmers Don't eat quiche", 
        staticQuote.content)
    }
}

My questions:

  1. Is the *Spec.groovy vs. *Tests.groovy issue that I am seeing because of the version I am using (Grails version: 2.3.1, Groovy version: 2.1.8, JVM version: 1.7.0_45), compared to the version the chapter was written for?
  2. How to run the test for the quote service successfully in Grails version 2.3.1?

Thank you in advance for any suggestions.

Chapter 5.1.1 - Error when creating admin user in BootStrap.groovy

When launching the app with the bootstrap file from github, I get an exception during the create admin portion.

Fresh Database. Creating ADMIN user.
| Error 2013-06-06 10:11:52,448 [localhost-startStop-1] ERROR hibernate.AssertionFailure  - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
Message: null id in com.grailsinaction.Profile entry (don't flush the Session after an exception occurs)

This is the code I have copied from the git repo:

private createAdminUserIfRequired() {
    if (!User.findByLoginId("admin")) {
        println "Fresh Database. Creating ADMIN user."

        def profile = new Profile(email: "[email protected]")
        new User(loginId: "admin", password: "secret", profile: profile).save()
    }
    else {
        println "Existing admin user, skipping creation"
    }
}

MEAP v9, chapter 3, section 3.4.2 : sorting gotchas

I think that sorting should be introduced in more details at end of section 3.4.2 or it should not be touched until later in the book.

Rationale

If one feels the urge to add spock tests verifying sort behavior of Post and user.posts, as I did after reading section 3.4.2, they're in for a bumpy ride. Here is what observed:

  • User.posts is backed by a HashSet which means that calling order of user.addToPosts() has nothing to do with the order the collection is processed by hibernate when actually inserting records to the database;
  • sorting is applied to the collection when it is fetched from the database; if you write your test so the same hibernate session is used to save and read, the sort will not be applied to user.posts collection;
  • dateCreated is under the control of hibernate (or GORM ?) and is not the instant in time the actual Post instance was instanciated (in the JVM), but really the instant in time when it got inserted into the database;

Because of that, tirival code to check for sorting behavior does not work and writing tests that work is not easy for the intended audience (from my point of view).

If you think it is worth it to address the subject of sorting at that point, I would suggest adding the following tests to PostIntegrationSpec with a pargraph or two discussing the details :

    def "Ensure posts linked to a user are sorted by date descending, earliest first"() {

        given: "A user with several posts"
        User user = new User(loginId:'joe', password: 'secret')
        user.addToPosts(new Post(content:'First post')).save(failOnError: true, flush: true)
        user.addToPosts(new Post(content:'Second post')).save(failOnError: true, flush: true)
        user.addToPosts(new Post(content:'Third post')).save(failOnError: true, flush: true)

        when: "The user is saved"
        user.save(failOnError: true)

        then: "The posts appear sorted by date created, descending"
        User.withNewSession { session ->
            User.get(user.id).posts.collect { it.content } == [ 'Third post', 'Second post', 'First post' ]
        }
    }

    def "Ensure listing post collection is using sort order"() {
        given: "A user with several posts"
        User user = new User(loginId: "joe", password: 'secret')
        user.addToPosts(new Post(content: "B")).save(failOnError: true, flush: true)
        user.addToPosts(new Post(content: "C")).save(failOnError: true, flush: true)
        user.addToPosts(new Post(content: "A")).save(failOnError: true, flush: true)
        user.save(failOnError: true, flush: true)

        when: "the list of all posts is retrieved"
        List<Post> posts = Post.list()

        then: "The posts for user created are in date created order"
        posts.collect { it.content } == Post.list().sort { it.dateCreated }.reverse().collect { it.content }
    }

This is with

   static mapping = {
       posts sort: 'dateCreated', order: 'desc'
    }

specified in class User, and

    static mapping = {
        sort dateCreated: 'desc'
    }

specified in class Post.

MEAP v11, chapter 5, usefulness of `parseDate()` ?

At end of section 5.2.1, code snippets are using a parseDate() method that is not defined in the text. I know there is a paragraph stating not to worry and that its actual implementation is irrelevant, but, if others are like me, they will end up running most (if not all) code snippets in a grails console and the snippets with parseDate() will fail. Changing them is not terribly difficult, but I fail to see the benefit of having this hypothetic parseDate() method in there.

I would suggest to use new Date() (and variants) as it is done in some other snippets in this chapter. I prefer to have code that I can copy/paste in my grails console to experiment as I learn rather than have code that looks like production code (if that was the intent?).

Same thing for sub-section "5.3.2 Introducing Criteria queries" where the first fragment use a parseDate(params.fromDate) while a ge "dateCreated", new Date() -1 would do the job, like what is done in the second fragment in that sub-section 5.3.2.

Chapter 3 listing 3.3 Saving and retrieving a domain object for the database

Listing is as follows:
Listing 3.3 Saving and retrieving a domain object from the database
package com.grailsinaction
import spock.lang.*
import grails.plugin.spock.*
class UserIntegrationSpec extends IntegrationSpec { #1
def "Saving our first user to the database"() {
given: "A brand new user"
def joe = new User(loginId: 'joe', password: 'secret',
homepage: 'http://www.grailsinaction.com')
when: "the user is saved" joe.save() #2
then: "it saved successfully and can be found in the database"
joe.errors.errorCount == 0 #3
joe.id != null #4
User.get(joe.id).userId == joe.userId #5
}
}

Last line should be:
User.get(joe.id).loginId == joe.loginId #5


test-app output before and after the above correction:

| Compiling 1 source files....
| Compiling 1 source files.....
| Running 1 spock test... 1 of 1
| Failure: Saving our first user to the database(com.grailsinaction.UserIntegrationSpec)
| groovy.lang.MissingPropertyException: No such property: userId for class: com.grailsinaction.User
at com.grailsinaction.UserIntegrationSpec.Saving our first user to the database(UserIntegrationSpec.groovy:19)
| Completed 1 spock test, 1 failed in 602ms
| Tests FAILED - view reports in C:\netscripts\smcccd\hubbub\target\test-reports

| Compiling 1 source files.....
| Compiling 1 source files.....
| Completed 1 spock test, 0 failed in 378ms
| Tests PASSED - view reports in C:\netscripts\smcccd\hubbub\target\test-reports

Grails by default comes with Tomcat now not Jetty!

Hi Peter,

If I am not wrong then now Grails (2.2.1) by default comes with tomcat and not Jetty.

In section 1.2 and page 4 it states:

"Grails ships with a copy of Jetty (an embeddable Java web server—there is talk that a future version will switch to Tomcat), which Grails uses to host your application during the
development and testing lifecycle."

Please correct it if you agree.

Regards,
Rasheed

MEAP v11, chapter 5, section 5.3.1 : fetch parameter oddities

When using def users = User.list(sort: 'loginId', order: 'asc', max: 5, fetch: [posts: 'eager']) the result list has 3 items whereas def users = User.list(sort: 'loginId', order: 'asc', max: 5) has 5.

I wonder if this is a bug in grails (version 2.2.3) ?

Here is a spec that should pass but where the tests using the fetch parameter are failing:

package com.grailsinaction

import grails.plugin.spock.IntegrationSpec

/**
 * Integration tests that should pass, but the one specifying fetch parameter to list() fails.
 */
class UserIntegrationCh531Spec extends IntegrationSpec {

    def setup() {
    }

    def cleanup() {
    }

    def "Static User list with sorting order"() {
        given: "User domain static list() method is used with parameters sort and order"
        def users = User.list(sort: 'id', order: 'asc')

        when: "a copy of the list is sorted by id"
        def copy = users.collect().sort { it.id }

        then: "both are equals"
        users == copy
    }

    def "Static User list with sorting order and eager fetch"() {
        given: "User domain static list() method is used with parameters sort, order and fetch"
        def users = User.list(sort: 'id', order: 'asc', fetch: [posts: 'eager'])

        when: "a copy of the list is sorted by id"
        def copy = users.collect().sort { it.id }

        then: "both are equals"
        users == copy
    }

    def "Static User list with max"() {
        given: "User domain static list() method used with a max parameter"
        def max = 4
        def users = User.list(max: max)

        when: "We count the results"
        def count = users.size()

        then: "it equals the max given"
        count == max
    }

    def "Static User list with max and eager fetch"() {
        given: "User domain static list() method used with a max parameter and fetch"
        def max = 5
        def users = User.list(max: max, fetch: [posts: 'eager'])

        when: "We count the results"
        def count = users.size()

        then: "it equals the max given"
        count == max
    }

}

MEAP v9, listing 3.2, assertion is false

The assertion (#5) is false as the sum of 3 and 7 is 10. If this is intentional, there should be a paragraph talking about seeing the test become red when run and how to fix it.

However, I think the first Spock test introduced should pass, unless you want to go into a discussion on the merit of writing tests that fails first, then make them run; but then, the test should fail not because of a error in the test but because of the code under test.

MEAP v10 Chap 5 Search Form

Are you assuming the readers of your book will know how to create the search form all on their own? What to name it, where to save it, and what the content of said file should be? All based on Figure 5.9?

If so, you should say so. And I think you maybe giving some of us more credit then we are due.

At the very least, you should point the reader to the Chapter 5 download files and AdvSearch.gsp (for those of us who expected a little more instruction on how to "generate a basic search form for Hubbub profiles". I am assuming this is what I am supposed to do.

And then where are we supposed to put the "advResults()" code that follow figure 5.9? I am still searching the download files for that code.

Did someone else write this section? It does not seem to be on par with the first 4 chapters.

Well I found the "AdvResults" code in UserController.groovy file. I still think this section needs some more work to be user friendly and instructional.

addPostAjax throws NPE if no user logged in

LameSecurityFilters only redirects to the login form on addPost and deletePost actions (I'm not sure the latter one even exists). So if the user isn't logged in, addPostAjax just throws an NPE.

Also problematic is the lack of a login form 😉

A potential solution for addPostAjax is for it to return a 401 if there is no 'user' object in the session. In fact, we should probably display a login link and hide the post submission form until there is a user in the session.

What controls the number of lines kept in the grails console?

After making all the Hibernate logging changes in section 5.2.2, I noticed that only the last 600 lines that Hibernate logged showed up in the console output. I cannot see what Hibernate logged in the first few hundred lines. How can I configure the console to retain all/more lines so I can spot problems earlier in scripts? Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.