├── .gitignore
├── .idea
├── compiler.xml
├── gradle.xml
├── libraries
│ ├── Gradle__com_google_code_gson_gson_2_6_2.xml
│ ├── Gradle__com_h2database_h2_1_3_170.xml
│ ├── Gradle__junit_junit_4_12.xml
│ ├── Gradle__mysql_mysql_connector_java_5_1_39.xml
│ ├── Gradle__org_apache_commons_commons_math3_3_6_1.xml
│ ├── Gradle__org_codehaus_groovy_groovy_all_2_4_12.xml
│ ├── Gradle__org_hamcrest_hamcrest_core_1_3.xml
│ └── Gradle__org_spockframework_spock_core_1_0_groovy_2_4.xml
├── misc.xml
├── modules.xml
├── modules
│ ├── AdvancedGroovy_main.iml
│ └── AdvancedGroovy_test.iml
├── vcs.xml
└── workspace.xml
├── AdvancedGroovy.iml
├── README.md
├── api_key.txt
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
├── main
└── groovy
│ ├── ast
│ ├── builder
│ │ └── builder_demo.groovy
│ ├── delegate
│ │ └── phone_delegate.groovy
│ ├── immutable
│ │ └── Point.groovy
│ ├── singleton
│ │ └── SingletonPoint.groovy
│ ├── sortable
│ │ ├── Golfer.groovy
│ │ └── use_golfer.groovy
│ └── tostring
│ │ └── tostring_and_equals.groovy
│ ├── closures
│ └── return_from_closure.groovy
│ ├── coercedclosures
│ ├── GroovyUtilityMethods.groovy
│ ├── ListDirectories.java
│ ├── UtilityMethods.java
│ └── list_directories.groovy
│ ├── db
│ └── film_in_stock.groovy
│ ├── gjdk
│ ├── basic_auth.groovy
│ ├── groundhog.groovy
│ ├── perm_and_comb.groovy
│ ├── sort_strings.groovy
│ └── sum_numbers.groovy
│ ├── hr
│ ├── Department.groovy
│ ├── Employee.java
│ └── JavaDepartment.java
│ ├── icndb
│ ├── icndb_script_only.groovy
│ └── icndb_with_textarea_and_button.groovy
│ ├── io
│ ├── SumNumbers.java
│ ├── data.txt
│ ├── files.groovy
│ ├── sum_numbers.groovy
│ └── sum_numbers_loop.groovy
│ ├── metaprogramming
│ ├── CurrencyCategory.groovy
│ ├── CustomLevel.groovy
│ ├── complex_numbers.groovy
│ ├── expando_demo.groovy
│ ├── use_emc.groovy
│ ├── use_slang_category.groovy
│ └── without_custom_levels.groovy
│ ├── openweather
│ ├── Model.groovy
│ ├── OpenWeather.groovy
│ ├── api_key.txt
│ ├── parse_weather.groovy
│ └── use_open_weather.groovy
│ ├── pogo
│ ├── JavaTask.java
│ └── Task.java
│ ├── range
│ ├── Geocoder.groovy
│ ├── TrainStation.groovy
│ └── amtrak_ne_corridor.groovy
│ └── sorting
│ ├── Person.groovy
│ ├── SortStringsByLength.java
│ └── sort_list.groovy
└── test
└── groovy
├── ast
├── immutable
│ └── PointSpec.groovy
└── singleton
│ └── SingletonPointSpec.groovy
├── coercedclosures
├── CoercedClosureMapTest.groovy
├── GTCSubclassTest.groovy
├── GroovyJUnit4Test.groovy
└── ListDirectoriesTest.java
├── hr
├── DepartmentSpec.groovy
└── JavaDepartmentSpec.groovy
├── metaprogramming
├── ComplexSpec.groovy
├── CurrencyCategorySpec.groovy
└── LoggingTests.groovy
├── openweather
├── ModelSpec.groovy
└── OpenWeatherSpec.groovy
└── pogo
└── TaskTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | bin
3 | out
4 | .gradle
5 | .project
6 | .classpath
7 | .settings
8 | *~
9 | .idea
10 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_google_code_gson_gson_2_6_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__com_h2database_h2_1_3_170.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__junit_junit_4_12.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__mysql_mysql_connector_java_5_1_39.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_apache_commons_commons_math3_3_6_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_codehaus_groovy_groovy_all_2_4_12.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/libraries/Gradle__org_spockframework_spock_core_1_0_groovy_2_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/modules/AdvancedGroovy_main.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/modules/AdvancedGroovy_test.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
62 |
63 |
64 |
67 |
68 |
69 |
87 |
88 |
89 |
284 |
285 |
286 |
290 |
291 |
292 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 | true
411 | DEFINITION_ORDER
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 | 1511026923420
608 |
609 |
610 | 1511026923420
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 | No facets are configured
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 | 9.0
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 | AdvancedGroovy
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 | Gradle: com.google.code.gson:gson:2.6.2
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
--------------------------------------------------------------------------------
/AdvancedGroovy.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | AdvancedGroovy
2 | ==============
3 |
4 | Examples for my NFJS Advanced Groovy: Tips and Tricks talk
5 |
6 | Ken Kousen, ken.kousen@kousenit.com
7 |
8 | Author of "Making Java Groovy", http://manning.com/kousen
9 |
--------------------------------------------------------------------------------
/api_key.txt:
--------------------------------------------------------------------------------
1 | d82ee6ea026dd986ea1e975d14875060
2 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin:'groovy'
2 | apply plugin:'eclipse'
3 | apply plugin:'idea'
4 |
5 | repositories {
6 | jcenter()
7 | }
8 |
9 | dependencies {
10 | compile 'org.codehaus.groovy:groovy-all:2.4.12'
11 | compile 'org.apache.commons:commons-math3:3.6.1'
12 | compile group: 'com.google.code.gson', name: 'gson', version: '2.6.2'
13 | testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
14 | runtime 'com.h2database:h2:1.3.170'
15 | runtime 'mysql:mysql-connector-java:5.1.39'
16 | }
17 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kousen/AdvancedGroovy/1f54d272f30d8c271fb7a55d33272447abe747ed/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-all.zip
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/src/main/groovy/ast/builder/builder_demo.groovy:
--------------------------------------------------------------------------------
1 | package ast.builder
2 |
3 | import groovy.transform.Canonical
4 | import groovy.transform.Immutable
5 | import groovy.transform.builder.Builder
6 |
7 | import java.text.DateFormat
8 |
9 | @Builder
10 | @Canonical
11 | class Hero {
12 | String secretIdentity
13 | String name
14 | String company
15 | String job
16 | Date hireDate
17 | }
18 |
19 | Hero hero = Hero
20 | .builder()
21 | .secretIdentity('Robert Parr')
22 | .name('Mr. Incredible')
23 | .company('InsuraCare')
24 | .job('Adjuster')
25 | .hireDate(Date.parse('dd/MMM/yyyy', '29/Apr/2015'))
26 | .build()
27 |
28 | println hero
29 | assert hero.name == 'Mr. Incredible'
30 | assert hero.secretIdentity == 'Robert Parr'
31 | assert hero.company == 'InsuraCare'
32 | assert hero.job == 'Adjuster'
33 |
34 | hero = Hero
35 | .builder()
36 | .secretIdentity('Helen Parr')
37 | .name('ElastiGirl')
38 | .job('Domestic Goddess')
39 | .hireDate(Date.parse('dd/MMM/yyyy', '29/Apr/2015'))
40 | .build()
41 |
42 | println hero
43 | assert hero.name == 'ElastiGirl'
44 | assert hero.secretIdentity == 'Helen Parr'
45 |
--------------------------------------------------------------------------------
/src/main/groovy/ast/delegate/phone_delegate.groovy:
--------------------------------------------------------------------------------
1 | package ast.delegate
2 |
3 | class Phone {
4 | String dial(String number) { "dialing $number" }
5 | String getManufacturer() { "Samsung" }
6 | }
7 |
8 | class Camera {
9 | String takePicture() { "taking picture" }
10 | String getManufacturer() { "Nikon" }
11 | }
12 |
13 | class SmartPhone {
14 | @Delegate Phone phone = new Phone()
15 | @Delegate Camera camera = new Camera()
16 |
17 | String getManufacturer() {
18 | "${phone.manufacturer}, ${camera.manufacturer}" }
19 | }
20 |
21 | SmartPhone sp = new SmartPhone()
22 | assert sp.dial('555-1234') == 'dialing 555-1234'
23 | assert sp.takePicture() == 'taking picture'
24 | println sp.manufacturer
--------------------------------------------------------------------------------
/src/main/groovy/ast/immutable/Point.groovy:
--------------------------------------------------------------------------------
1 | package ast.immutable
2 |
3 | import groovy.transform.Immutable
4 |
5 | @Immutable
6 | class Point {
7 | double x
8 | double y
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/groovy/ast/singleton/SingletonPoint.groovy:
--------------------------------------------------------------------------------
1 | package ast.singleton
2 |
3 | @Singleton
4 | class SingletonPoint {
5 | BigDecimal x
6 | BigDecimal y
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/groovy/ast/sortable/Golfer.groovy:
--------------------------------------------------------------------------------
1 | package ast.sortable
2 |
3 | import groovy.transform.Sortable
4 |
5 | @Sortable(includes = ['height', 'score', 'last', 'first'])
6 | class Golfer {
7 | String first
8 | String last
9 | int score
10 | int height
11 |
12 | String toString() { "$score: $last, $first (${height})" }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/groovy/ast/sortable/use_golfer.groovy:
--------------------------------------------------------------------------------
1 | package ast.sortable
2 |
3 | //def golfers = [
4 | // new Golfer(score: 68, last: 'Nicklaus', first: 'Jack'),
5 | // new Golfer(score: 70, last: 'Woods', first: 'Tiger'),
6 | // new Golfer(score: 70, last: 'Watson', first: 'Tom'),
7 | // new Golfer(score: 68, last: 'Webb', first: 'Ty'),
8 | // new Golfer(score: 70, last: 'Watson', first: 'Bubba')]
9 | //
10 | //golfers.sort().each { println it }
11 |
12 | def golfers = [
13 | new Golfer(height: 70, score: 68, last: 'Nicklaus', first: 'Jack'),
14 | new Golfer(height: 73, score: 70, last: 'Woods', first: 'Tiger'),
15 | new Golfer(height: 69, score: 70, last: 'Watson', first: 'Tom'),
16 | new Golfer(height: 76, score: 68, last: 'Webb', first: 'Ty'),
17 | new Golfer(height: 75, score: 70, last: 'Watson', first: 'Bubba')]
18 |
19 | golfers.sort().reverse().each { println it }
--------------------------------------------------------------------------------
/src/main/groovy/ast/tostring/tostring_and_equals.groovy:
--------------------------------------------------------------------------------
1 | package ast.tostring
2 |
3 | import groovy.transform.Canonical;
4 | import groovy.transform.EqualsAndHashCode;
5 | import groovy.transform.ToString;
6 | import groovy.transform.TupleConstructor;
7 |
8 | @EqualsAndHashCode
9 | @ToString
10 | @TupleConstructor
11 | //@Canonical
12 | class Product {
13 | int id
14 | String name
15 | def price
16 | }
17 |
18 | Product p_orig = new Product(id:1,name:'name',price:9.99)
19 | Product p_copy = new Product(id:1,name:'name',price:9.99)
20 | Product p_diff = new Product(id:2,name:'other',price:5)
21 | Product p2 = new Product(3, 'abc', 10)
22 |
23 | assert p_orig == p_copy
24 | assert !p_orig.is(p_copy)
25 | assert p_orig != p_diff
26 | assert p_orig.toString() == 'ast.tostring.Product(1, name, 9.99)'
27 |
28 | Set products = [p_orig, p_copy, p_diff]
29 | assert products.size() == 2
--------------------------------------------------------------------------------
/src/main/groovy/closures/return_from_closure.groovy:
--------------------------------------------------------------------------------
1 | package closures
2 |
3 | boolean checkImplementation(Closure c) {
4 | (2..20).findAll { c(it) } == [2, 3, 5, 7, 11, 13, 17, 19]
5 | }
6 |
7 | // THIS DOESN'T WORK
8 | boolean isPrime1(int x) {
9 | if (x == 2) return true
10 | int limit = Math.sqrt(x) + 1
11 | (2..limit).each { n ->
12 | // nice try, but a return in a closure
13 | // returns only from the closure
14 | if (x % n == 0) return false
15 | }
16 | return true
17 | }
18 |
19 | assert !checkImplementation(this.&isPrime1) // See?
20 |
21 | // can set a variable, but can't break out of the loop
22 | boolean isPrime2(int x) {
23 | if (x == 2) return true
24 | boolean result = true
25 | int limit = Math.sqrt(x) + 1
26 | (2..limit).each { n ->
27 | if (x % n == 0) {
28 | result = false
29 | // don't you wish you could break here?
30 | }
31 | }
32 | return result
33 | }
34 |
35 | assert checkImplementation(this.&isPrime2)
36 |
37 | // use for-in loop instead, and it works
38 | boolean isPrime3(int x) {
39 | if (x == 2) return true
40 | boolean result = true
41 | int limit = Math.sqrt(x) + 1
42 | for (n in 2..limit) {
43 | if (x % n == 0) {
44 | result = false
45 | break
46 | }
47 | }
48 | return result
49 | }
50 |
51 | assert checkImplementation(this.&isPrime3)
52 |
53 | // of course, if you use for-in, you can use return
54 | boolean isPrime4(int x) {
55 | if (x == 2) return true
56 | int limit = Math.sqrt(x) + 1
57 | for (n in 2..limit) {
58 | if (x % n == 0) return false
59 | }
60 | return true
61 | }
62 |
63 | assert checkImplementation(this.&isPrime4)
64 |
65 | // don't forget about the find method, though
66 | // (Elegant implementation courtesy of Tim Yates, @tim_yates)
67 | boolean isPrime5(int x) {
68 | int limit = Math.sqrt(x) + 1
69 | x == 2 || !(2..limit).find { n -> x % n == 0 }
70 | }
71 |
72 | assert checkImplementation(this.&isPrime5)
73 |
74 | Number.metaClass.isPrime = { ->
75 | Integer x = delegate as Integer
76 | int limit = Math.sqrt(x) + 1
77 | x == 2 || !(2..limit).find { n -> x % n == 0 }
78 | }
79 |
80 | assert (2..20).findAll { it.isPrime() } == [2, 3, 5, 7, 11, 13, 17, 19]
81 |
--------------------------------------------------------------------------------
/src/main/groovy/coercedclosures/GroovyUtilityMethods.groovy:
--------------------------------------------------------------------------------
1 | package coercedclosures
2 |
3 | class GroovyUtilityMethods implements UtilityMethods {
4 |
5 | int[] getPositives(int... values) {
6 | values.findAll { it > 0 }
7 | }
8 |
9 | boolean isPalindrome(String s) {
10 | String str = s.toLowerCase().replaceAll(/\W/,'')
11 | str.reverse() == str
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/groovy/coercedclosures/ListDirectories.java:
--------------------------------------------------------------------------------
1 | package coercedclosures;
2 |
3 | import java.io.File;
4 | import java.io.FilenameFilter;
5 |
6 | public class ListDirectories {
7 | public String[] listDirectoryNames(String root) {
8 | return new File(root).list(new FilenameFilter() {
9 | @Override
10 | public boolean accept(File dir, String name) {
11 | return new File(name).isDirectory();
12 | }
13 | });
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/groovy/coercedclosures/UtilityMethods.java:
--------------------------------------------------------------------------------
1 | package coercedclosures;
2 |
3 | public interface UtilityMethods {
4 | int[] getPositives(int... values);
5 | boolean isPalindrome(String s);
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/groovy/coercedclosures/list_directories.groovy:
--------------------------------------------------------------------------------
1 | package coercedclosures
2 |
3 | new File('/').list(
4 | { File dir, String name -> new File(name).directory } )
5 | // as FilenameFilter)
6 | .each { fileName -> println fileName }
7 |
--------------------------------------------------------------------------------
/src/main/groovy/db/film_in_stock.groovy:
--------------------------------------------------------------------------------
1 | package db
2 |
3 | import groovy.sql.Sql
4 |
5 | int filmInStock(filmId, storeId) {
6 | Sql sql = Sql.newInstance(
7 | url:'jdbc:mysql://localhost:3306/sakila',
8 | driver:'com.mysql.jdbc.Driver',
9 | user:'root', password:'')
10 |
11 | int result
12 | sql.call('{call film_in_stock(?,?,?)}',
13 | [filmId, storeId, Sql.INTEGER]) { count ->
14 | result = count
15 | }
16 | result
17 | }
18 |
19 | int films = filmInStock(1,1)
20 | println "For store_id = 1 and film_id = 1, there are $films copies in stock"
--------------------------------------------------------------------------------
/src/main/groovy/gjdk/basic_auth.groovy:
--------------------------------------------------------------------------------
1 | package gjdk
2 |
3 | // trivial username, password
4 | def u = 'username'
5 | def p = 'password'
6 |
7 | // base 64 encoding
8 | def encoded = "$u:$p".getBytes().encodeBase64().toString()
9 | println "$u:$p -> $encoded"
10 | assert encoded == 'dXNlcm5hbWU6cGFzc3dvcmQ='
11 |
12 | // decoded with multiple returns
13 | def (user,pass) = new String(encoded.decodeBase64()).split(':')
14 | println "(user,pass) = ($user,$pass)"
15 | assert user == u
16 | assert pass == p
17 |
--------------------------------------------------------------------------------
/src/main/groovy/gjdk/groundhog.groovy:
--------------------------------------------------------------------------------
1 | package gjdk
2 |
3 | println 'Groundhog sees shadow --> 6 more weeks of Winter'
4 | def c = Calendar.instance
5 | c.set 2013, Calendar.FEBRUARY, 2
6 | def groundHogDay = c.time
7 | c.set 2013, Calendar.MARCH, 20
8 | def firstDayOfSpring = c.time
9 | def days = firstDayOfSpring - groundHogDay
10 | assert days == (firstDayOfSpring..groundHogDay).size() - 1
11 | println """
12 | There are ${(int)(days/7)} weeks and ${days % 7} days between GroundHog Day
13 | and the first day of Spring (March 20), so Spring
14 | comes early if the groundhog sees his shadow.
15 | """
--------------------------------------------------------------------------------
/src/main/groovy/gjdk/perm_and_comb.groovy:
--------------------------------------------------------------------------------
1 | package gjdk
2 |
3 | println( [[1, 2], ['a','b','c']].combinations() )
4 |
5 | ['A','U','S'].eachPermutation { println it }
6 |
--------------------------------------------------------------------------------
/src/main/groovy/gjdk/sort_strings.groovy:
--------------------------------------------------------------------------------
1 | package gjdk
2 |
3 | def strings = ['this', 'is', 'a', 'list', 'of', 'strings']
4 | println strings
5 |
6 | // Java sort
7 | //Collections.sort(strings)
8 |
9 | // Groovy sort
10 | //strings.sort()
11 | //println strings
12 |
13 | // Java sort by length
14 | //Collections.sort(strings, new Comparator() {
15 | // int compare(String s1, String s2) {
16 | // return s1.length() - s2.length()
17 | // }
18 | //})
19 |
20 | // Closure coercion
21 | Collections.sort(strings,
22 | { String s1, String s2 -> s1.size() <=> s2.size() } as Comparator)
23 |
24 | println strings
25 | assert strings*.size() == [1, 2, 2, 4, 4, 7]
26 |
27 | // Groovy Comparator reverse sort
28 | // (Note: issues with Java 8)
29 | //strings.sort( new Comparator() {
30 | // int compare(String s1, String s2) {
31 | // return s2.size() <=> s1.size()
32 | // }
33 | //})
34 | //println strings
35 |
36 | // Groovy closure sort
37 | strings.sort { it.size() }
38 | println strings
39 |
40 | // Groovy closure reverse sort
41 | strings.sort { -it.size() }
42 | println strings
43 |
44 | // sort by length, then by alphabet
45 | strings.sort { s1, s2 ->
46 | s1.size() <=> s2.size() ?: s1 <=> s2
47 | }
48 | println strings
--------------------------------------------------------------------------------
/src/main/groovy/gjdk/sum_numbers.groovy:
--------------------------------------------------------------------------------
1 | package gjdk
2 |
3 | def nums = [3, 1, 4, 1, 5, 9, 2, 6, 5]
4 |
5 | assert 36 == nums.sum()
6 |
7 | // sum with closure
8 | println nums.sum { it * 2 }
9 |
10 | // collect, then sum
11 | println nums.collect { it * 2 }.sum()
12 |
13 | // using spread-dot operator
14 | def doubles = nums*.multiply(2)
15 | println doubles.sum()
16 |
17 | // list has a multiply method, too
18 | def doubleList = nums * 2
19 | println doubleList.sum()
20 |
21 | // inject
22 | println nums.inject(0) { sum, val -> sum + 2 * val }
23 |
24 | // average
25 | println nums.sum() / nums.size()
--------------------------------------------------------------------------------
/src/main/groovy/hr/Department.groovy:
--------------------------------------------------------------------------------
1 | package hr;
2 |
3 | class Department {
4 | int id
5 | String name
6 | Map empMap = [:]
7 |
8 | void hire(Employee e) {
9 | empMap[e.id] = e
10 | }
11 |
12 | void layOff(Employee e) {
13 | empMap.remove(e.id)
14 | }
15 |
16 | Collection getEmployees() {
17 | empMap.values()
18 | }
19 |
20 | Department plus(Employee e) {
21 | hire(e)
22 | this
23 | }
24 |
25 | Department minus(Employee e) {
26 | layOff(e)
27 | this
28 | }
29 |
30 | Department leftShift(Employee e) {
31 | hire(e)
32 | this
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/groovy/hr/Employee.java:
--------------------------------------------------------------------------------
1 | package hr;
2 |
3 | public class Employee {
4 | private int id;
5 | private String name;
6 |
7 | public String getName() {
8 | return name;
9 | }
10 |
11 | public void setName(String name) {
12 | this.name = name;
13 | }
14 |
15 | public int getId() {
16 | return id;
17 | }
18 |
19 | public void setId(int id) {
20 | this.id = id;
21 | }
22 |
23 | @Override
24 | public String toString() {
25 | return "Employee [id=" + id + ", name=" + name + "]";
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/groovy/hr/JavaDepartment.java:
--------------------------------------------------------------------------------
1 | package hr;
2 |
3 | import java.util.Collection;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | public class JavaDepartment {
8 | private int id;
9 | private String name;
10 | private Map empMap = new HashMap<>();
11 |
12 | public int getId() {
13 | return id;
14 | }
15 | public void setId(int id) {
16 | this.id = id;
17 | }
18 | public String getName() {
19 | return name;
20 | }
21 | public void setName(String name) {
22 | this.name = name;
23 | }
24 |
25 | public void hire(Employee e) {
26 | empMap.put(e.getId(), e);
27 | }
28 |
29 | public void layOff(Employee e) {
30 | empMap.remove(e.getId());
31 | }
32 |
33 | public Collection getEmployees() {
34 | return empMap.values();
35 | }
36 |
37 | public JavaDepartment plus(Employee e) {
38 | hire(e);
39 | return this;
40 | }
41 |
42 | public JavaDepartment minus(Employee e) {
43 | layOff(e);
44 | return this;
45 | }
46 |
47 | public JavaDepartment leftShift(Employee e) {
48 | hire(e);
49 | return this;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/groovy/icndb/icndb_script_only.groovy:
--------------------------------------------------------------------------------
1 | package icndb
2 |
3 | import groovy.json.JsonSlurper
4 |
5 | String base = 'http://api.icndb.com/jokes/random?limitTo=[nerdy]'
6 | def json = new JsonSlurper().parseText(base.toURL().text)
7 | println json?.value?.joke
--------------------------------------------------------------------------------
/src/main/groovy/icndb/icndb_with_textarea_and_button.groovy:
--------------------------------------------------------------------------------
1 | package icndb
2 |
3 | import groovy.json.JsonSlurper
4 | import groovy.swing.SwingBuilder
5 |
6 | import java.awt.BorderLayout as BL
7 | import java.awt.Color
8 | import java.awt.Font
9 |
10 | import javax.swing.WindowConstants as WC
11 |
12 |
13 | String base = 'http://api.icndb.com/jokes/random?limitTo=[nerdy]'
14 | def slurper = new JsonSlurper()
15 |
16 | new SwingBuilder().edt {
17 | frame(title:'ICNDB', visible: true, pack: true,
18 | defaultCloseOperation:WC.EXIT_ON_CLOSE) {
19 | panel(layout:new BL(), preferredSize:[300, 250], background: Color.WHITE) {
20 | scrollPane {
21 | textArea('Welcome to ICNDB',
22 | constraints:BL.NORTH,
23 | font: new Font('Serif', Font.PLAIN, 24),
24 | lineWrap: true, wrapStyleWord: true, editable: false,
25 | id: 'textArea')
26 | }
27 | button('Get Joke', constraints:BL.SOUTH,
28 | actionPerformed: {
29 | doOutside {
30 | def json = slurper.parseText(base.toURL().text)
31 | doLater {
32 | textArea.text = json?.value?.joke
33 | }
34 | }
35 | }
36 | )
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/src/main/groovy/io/SumNumbers.java:
--------------------------------------------------------------------------------
1 | package io;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 |
7 | public class SumNumbers {
8 | public static void main(String[] args) {
9 | System.out.println("Please enter numbers to sum");
10 | BufferedReader br =
11 | new BufferedReader(new InputStreamReader(System.in));
12 | String line = "";
13 | try {
14 | line = br.readLine();
15 | } catch (IOException e) {
16 | e.printStackTrace();
17 | }
18 | String[] inputs = line.split(" ");
19 | double total = 0.0;
20 | for (String s : inputs) {
21 | total += Double.parseDouble(s);
22 | }
23 | System.out.println("The sum is " + total);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/groovy/io/data.txt:
--------------------------------------------------------------------------------
1 | 1,2,3
2 | a,b,c
3 |
--------------------------------------------------------------------------------
/src/main/groovy/io/files.groovy:
--------------------------------------------------------------------------------
1 | package io
2 |
3 | def files = []
4 | new File('.').eachFileRecurse { file ->
5 | if (file.name.endsWith('.groovy')) {
6 | files << file
7 | }
8 | }
9 | assert files
10 | println "There are ${files.size()} groovy files"
11 |
12 | def base = 'src/main/groovy/io'
13 |
14 | String data = new File(base + '/files.groovy').text
15 | assert data.contains('text')
16 |
17 | List lines = new File("$base/files.groovy").readLines()*.trim()
18 | assert lines[15] == "package io"
19 |
20 | lines.reverse().each { println it }
21 |
22 | List dataLines = []
23 | new File("$base/data.txt").splitEachLine(',') {
24 | dataLines << it
25 | }
26 | assert dataLines == [['1','2','3'],['a','b','c']]
27 |
28 |
29 | File f = new File("$base/output.dat")
30 | f.write('Hello, Groovy!')
31 |
32 | assert f.text == 'Hello, Groovy!'
33 | f.delete()
34 |
35 | File temp = new File("$base/temp.txt")
36 |
37 | // Don't really need parens here, so why use them?
38 | temp.write 'Groovy Kind of Love'
39 | assert temp.readLines().size() == 1
40 |
41 | // Need to start with a carriage return
42 | temp.append "\nGroovin', on a Sunday afternoon..."
43 |
44 | // Note use of overloaded << operator
45 | temp << "\nFeelin' Groovy"
46 | assert temp.readLines().size() == 3
47 | temp.delete()
--------------------------------------------------------------------------------
/src/main/groovy/io/sum_numbers.groovy:
--------------------------------------------------------------------------------
1 | package io
2 |
3 | println 'Please enter some numbers'
4 | System.in.withReader { br ->
5 | println br.readLine().tokenize()*.toBigDecimal().sum()
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/groovy/io/sum_numbers_loop.groovy:
--------------------------------------------------------------------------------
1 | package io
2 |
3 | println 'Sum numbers with looping'
4 | System.in.eachLine { line ->
5 | if (!line) System.exit(0)
6 | println line.split(' ')*.toBigDecimal().sum()
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/src/main/groovy/metaprogramming/CurrencyCategory.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming
2 |
3 | import java.text.NumberFormat
4 |
5 | @Category(Number)
6 | class CurrencyCategory {
7 | String asCurrency(Locale loc = Locale.default) {
8 | NumberFormat.getCurrencyInstance(loc).format(this)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/groovy/metaprogramming/CustomLevel.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming
2 |
3 | import groovy.transform.InheritConstructors;
4 |
5 | import java.util.logging.Level;
6 |
7 | @InheritConstructors
8 | class CustomLevel extends Level {
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/groovy/metaprogramming/complex_numbers.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming
2 |
3 | import static org.apache.commons.math3.complex.Complex.*
4 | import static java.lang.Math.*
5 |
6 | import org.apache.commons.math3.complex.*
7 |
8 | Complex lhs = new Complex(1.0, 3.0);
9 | Complex rhs = new Complex(2.0, 5.0);
10 |
11 | assert lhs.multiply(rhs) == lhs * rhs
12 | println lhs * rhs
13 | println "$lhs == ($lhs.real, $lhs.imaginary)"
14 |
15 | ComplexFormat fmt = new ComplexFormat()
16 | println fmt.format(lhs)
17 | println fmt.format(rhs)
18 |
19 | Complex.metaClass.plus = { Complex c -> delegate.add c }
20 | Complex.metaClass.minus = { Complex c -> delegate.subtract c }
21 | Complex.metaClass.div = { Complex c -> delegate.divide c }
22 | Complex.metaClass.power = { Complex c -> delegate.pow c }
23 | Complex.metaClass.negative = { delegate.negate() }
24 | assert new Complex(3.0, 8.0) == lhs + rhs
25 | assert new Complex(1.0, 2.0) == rhs - lhs
26 | assert new Complex(0.5862068965517241, 0.03448275862068969) == lhs / rhs
27 | assert new Complex(-0.007563724861696302, 0.01786136835085382) == lhs ** rhs
28 | assert new Complex(-1.0, -3.0) == -lhs
29 |
30 | Double.metaClass.power = { Complex c -> (new Complex(delegate,0)).pow(c) }
31 |
32 | println fmt.format( ( I * PI ).exp() )
33 | println fmt.format( new Complex(E, 0) ** (I * PI) )
34 | println fmt.format( E ** (I * PI) )
35 | assert (E ** (I * PI)).real == -1
36 | assert (E ** (I * PI)).imaginary < 1.0e-15
--------------------------------------------------------------------------------
/src/main/groovy/metaprogramming/expando_demo.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming
2 |
3 | Expando ex = new Expando()
4 | ex.name = 'Fido'
5 | ex.speak = { println "$name says Woof!" }
6 | ex.speak()
7 |
8 | class Cat {}
9 | Cat.metaClass.name = 'Garfield'
10 | Cat.metaClass.says = 'wants lasagna'
11 | Cat.metaClass.speak { println "$name $says" }
12 | Cat c = new Cat()
13 | c.speak()
14 |
15 | c.name = 'Fluffy'
16 | c.says = 'meow'
17 | c.speak()
--------------------------------------------------------------------------------
/src/main/groovy/metaprogramming/use_emc.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming
2 |
3 | import java.util.logging.*
4 |
5 | Logger.metaClass.methodMissing = { String name, args ->
6 | println "inside methodMissing with $name"
7 | int val = Level.WARNING.intValue() +
8 | (Level.SEVERE.intValue() - Level.WARNING.intValue()) * Math.random()
9 | def level = new CustomLevel(name.toUpperCase(),val)
10 | def impl = { Object... varArgs ->
11 | delegate.log(level,varArgs[0])
12 | }
13 | Logger.metaClass."$name" = impl
14 | impl(args)
15 | }
16 |
17 |
18 | Logger log = Logger.getLogger(this.class.name)
19 | log.hey 'what up?'
20 | log.whoa 'dude, seriously'
21 | log.rofl "you're kidding, right?"
22 | log.rofl 'rolling on the floor laughing'
23 | log.rofl 'rolling on the floor laughing'
24 | log.whatever 'heavy sigh'
25 | log.sup('sup, dude')
--------------------------------------------------------------------------------
/src/main/groovy/metaprogramming/use_slang_category.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming
2 |
3 | import java.util.logging.Level;
4 | import java.util.logging.Logger
5 |
6 | class SlangCategory {
7 | static String fyi(Logger self, String msg) {
8 | return self.log(new CustomLevel('FYI',Level.INFO.intValue()),msg)
9 | }
10 | static String lol(Logger self, String msg) {
11 | return self.log(new CustomLevel('LOL',Level.WARNING.intValue()),msg)
12 | }
13 | }
14 |
15 | Logger log = Logger.getLogger(this.class.name)
16 | use(SlangCategory) {
17 | log.fyi 'this seems okay'
18 | log.lol('snicker')
19 | }
--------------------------------------------------------------------------------
/src/main/groovy/metaprogramming/without_custom_levels.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming
2 |
3 | import java.util.logging.Logger;
4 |
5 | Logger.metaClass.fyi = { msg -> delegate.info msg }
6 | Logger.metaClass.omg = { msg -> delegate.severe msg }
7 |
8 | Logger log = Logger.getLogger(this.class.name)
9 | log.fyi 'for your information'
10 | log.omg 'oh my goodness'
11 |
--------------------------------------------------------------------------------
/src/main/groovy/openweather/Model.groovy:
--------------------------------------------------------------------------------
1 | package openweather
2 |
3 | class Model {
4 | Long dt
5 | Long id
6 | String name
7 | Integer cod
8 |
9 | Coordinates coord
10 | Main main
11 | System sys
12 | Wind wind
13 | Clouds clouds
14 | Weather[] weather
15 |
16 | def convertTemp(temp) {
17 | 9 * (temp - 273.15) / 5 + 32
18 | }
19 |
20 | def convertSpeed(mps) {
21 | // 1 m/sec * 60 sec/min * 60 min/hr * 100 cm/m * 1 in/2.54 cm * 1 ft/12 in * 1 mi/5280 ft
22 | mps * 60 * 60 * 100 / 2.54 / 12 / 5280
23 | }
24 |
25 | def convertTime(t) {
26 | new Date(t*1000) // Unix time in sec, Java time in ms
27 | }
28 |
29 | def getTime() { convertTime dt }
30 | def getTemperature() { convertTemp main.temp }
31 | def getLow() { Math.floor(convertTemp(main.temp_min)) }
32 | def getHigh() { Math.ceil(convertTemp(main.temp_max)) }
33 | def getSunrise() { convertTime sys.sunrise }
34 | def getSunset() { convertTime sys.sunset }
35 | def getSpeed() { convertSpeed wind.speed }
36 |
37 | String toString() {
38 | String result = """
39 | Name : $name
40 | Time : $time
41 | Location : $coord"""
42 |
43 | weather.each { w ->
44 | result += "\n Weather : ${w.main} (${w.description})"
45 | }
46 |
47 | result += """
48 | Icon : http://openweathermap.org/img/w/${weather[0].icon}.png
49 | Current Temp : $temperature F (high: $high F, low: $low F)
50 | Humidity : ${main.humidity}%
51 | Sunrise : $sunrise
52 | Sunset : $sunset
53 | Wind : $speed mph at ${wind.deg} deg
54 | Cloudiness : ${clouds.all}%
55 | """
56 | return result
57 | }
58 | }
59 |
60 | class Main {
61 | BigDecimal temp
62 | BigDecimal humidity
63 | BigDecimal pressure
64 | BigDecimal temp_min
65 | BigDecimal temp_max
66 | }
67 |
68 | class Coordinates {
69 | BigDecimal lat
70 | BigDecimal lon
71 |
72 | String toString() { "($lat, $lon)" }
73 | }
74 |
75 | class Weather {
76 | Integer id
77 | String main
78 | String description
79 | String icon
80 | }
81 |
82 | class System {
83 | String message
84 | String country
85 | Long sunrise
86 | Long sunset
87 | }
88 |
89 | class Wind {
90 | BigDecimal speed
91 | BigDecimal deg
92 | }
93 |
94 | class Clouds {
95 | BigDecimal all
96 | }
--------------------------------------------------------------------------------
/src/main/groovy/openweather/OpenWeather.groovy:
--------------------------------------------------------------------------------
1 | package openweather
2 |
3 | import com.google.gson.Gson
4 |
5 | class OpenWeather {
6 | String appid = new File('api_key.txt').text
7 | String base = "http://api.openweathermap.org/data/2.5/weather?"
8 | Gson gson = new Gson()
9 |
10 | String getWeather(city='Hartford', state='US') {
11 | String qs = [q: "$city,$state", APPID: appid ].collect { it }.join('&')
12 | String url = "$base$qs"
13 | String jsonTxt = url.toURL().text
14 | gson.fromJson(jsonTxt, Model).toString()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/groovy/openweather/api_key.txt:
--------------------------------------------------------------------------------
1 | d82ee6ea026dd986ea1e975d14875060
2 |
--------------------------------------------------------------------------------
/src/main/groovy/openweather/parse_weather.groovy:
--------------------------------------------------------------------------------
1 | package openweather
2 |
3 | import groovy.json.JsonOutput;
4 |
5 | import com.google.gson.Gson
6 |
7 | String appid = new File('api_key.txt').text
8 |
9 | def url = "http://api.openweathermap.org/data/2.5/weather?q=copenhagen,denmark&APPID=$appid"
10 | def jsonTxt = url.toURL().text
11 | println JsonOutput.prettyPrint(jsonTxt)
12 | //Gson gson = new Gson()
13 | //println gson.fromJson(jsonTxt, Model)
14 |
--------------------------------------------------------------------------------
/src/main/groovy/openweather/use_open_weather.groovy:
--------------------------------------------------------------------------------
1 | package openweather
2 |
3 | OpenWeather ow = new OpenWeather()
4 | println ow.weather // called Hartford
5 |
6 | // Home of Paul King, co-author of _Groovy in Action_ and my personal hero
7 | println ow.getWeather('Brisbane', 'Australia')
8 |
9 | // Home of Guillaume Laforge, head of the Groovy project
10 | // (also one of my heroes, along with Dierk Koenig, Graeme Rocher, Tom Brady, David Ortiz, ...)
11 | println ow.getWeather('Paris', 'France')
12 |
13 | // Have to check the weather in Java, right?
14 | println ow.getWeather('Jakarta','ID')
15 |
16 | // Is it always sunny in Philadelphia?
17 | println ow.getWeather('Philadelphia', 'US')
18 |
19 | // Any weather stations in Antarctica?
20 | println ow.getWeather('McMurdo Station', 'AQ')
21 |
22 | // Is it colder in Winnipeg than in Antarctica?
23 | //println ow.getWeather('Winnipeg', 'CA')
--------------------------------------------------------------------------------
/src/main/groovy/pogo/JavaTask.java:
--------------------------------------------------------------------------------
1 | package pogo;
2 |
3 | import java.util.Date;
4 |
5 | public class JavaTask {
6 | private String name;
7 | private int priority;
8 | private Date startDate;
9 | private Date endDate;
10 | private boolean completed;
11 |
12 | public JavaTask() {}
13 |
14 | public JavaTask(String name, int priority, Date startDate, Date endDate,
15 | boolean completed) {
16 | super();
17 | this.name = name;
18 | this.priority = priority;
19 | this.startDate = startDate;
20 | this.endDate = endDate;
21 | this.completed = completed;
22 | }
23 |
24 | public String getName() {
25 | return name;
26 | }
27 |
28 | public void setName(String name) {
29 | this.name = name;
30 | }
31 |
32 | public int getPriority() {
33 | return priority;
34 | }
35 |
36 | public void setPriority(int priority) {
37 | this.priority = priority;
38 | }
39 |
40 | public Date getStartDate() {
41 | return startDate;
42 | }
43 |
44 | public void setStartDate(Date startDate) {
45 | this.startDate = startDate;
46 | }
47 |
48 | public Date getEndDate() {
49 | return endDate;
50 | }
51 |
52 | public void setEndDate(Date endDate) {
53 | this.endDate = endDate;
54 | }
55 |
56 | public boolean isCompleted() {
57 | return completed;
58 | }
59 |
60 | public void setCompleted(boolean completed) {
61 | this.completed = completed;
62 | }
63 |
64 | @Override
65 | public int hashCode() {
66 | final int prime = 31;
67 | int result = 1;
68 | result = prime * result + (completed ? 1231 : 1237);
69 | result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
70 | result = prime * result + ((name == null) ? 0 : name.hashCode());
71 | result = prime * result + priority;
72 | result = prime * result
73 | + ((startDate == null) ? 0 : startDate.hashCode());
74 | return result;
75 | }
76 |
77 | @Override
78 | public boolean equals(Object obj) {
79 | if (this == obj)
80 | return true;
81 | if (obj == null)
82 | return false;
83 | if (getClass() != obj.getClass())
84 | return false;
85 | JavaTask other = (JavaTask) obj;
86 | if (completed != other.completed)
87 | return false;
88 | if (endDate == null) {
89 | if (other.endDate != null)
90 | return false;
91 | } else if (!endDate.equals(other.endDate))
92 | return false;
93 | if (name == null) {
94 | if (other.name != null)
95 | return false;
96 | } else if (!name.equals(other.name))
97 | return false;
98 | if (priority != other.priority)
99 | return false;
100 | if (startDate == null) {
101 | if (other.startDate != null)
102 | return false;
103 | } else if (!startDate.equals(other.startDate))
104 | return false;
105 | return true;
106 | }
107 |
108 | @Override
109 | public String toString() {
110 | return "Task [name=" + name + ", priority=" + priority + ", startDate="
111 | + startDate + ", endDate=" + endDate + ", completed="
112 | + completed + "]";
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/groovy/pogo/Task.java:
--------------------------------------------------------------------------------
1 | package pogo;
2 |
3 | import java.util.Date;
4 |
5 | public class Task {
6 | private String name;
7 | private int priority;
8 | private Date startDate;
9 | private Date endDate;
10 | private boolean completed;
11 |
12 | public Task() {}
13 |
14 | public Task(String name, int priority, Date startDate, Date endDate,
15 | boolean completed) {
16 | super();
17 | this.name = name;
18 | this.priority = priority;
19 | this.startDate = startDate;
20 | this.endDate = endDate;
21 | this.completed = completed;
22 | }
23 |
24 | public String getName() {
25 | return name;
26 | }
27 |
28 | public void setName(String name) {
29 | this.name = name;
30 | }
31 |
32 | public int getPriority() {
33 | return priority;
34 | }
35 |
36 | public void setPriority(int priority) {
37 | this.priority = priority;
38 | }
39 |
40 | public Date getStartDate() {
41 | return startDate;
42 | }
43 |
44 | public void setStartDate(Date startDate) {
45 | this.startDate = startDate;
46 | }
47 |
48 | public Date getEndDate() {
49 | return endDate;
50 | }
51 |
52 | public void setEndDate(Date endDate) {
53 | this.endDate = endDate;
54 | }
55 |
56 | public boolean isCompleted() {
57 | return completed;
58 | }
59 |
60 | public void setCompleted(boolean completed) {
61 | this.completed = completed;
62 | }
63 |
64 | @Override
65 | public int hashCode() {
66 | final int prime = 31;
67 | int result = 1;
68 | result = prime * result + (completed ? 1231 : 1237);
69 | result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
70 | result = prime * result + ((name == null) ? 0 : name.hashCode());
71 | result = prime * result + priority;
72 | result = prime * result
73 | + ((startDate == null) ? 0 : startDate.hashCode());
74 | return result;
75 | }
76 |
77 | @Override
78 | public boolean equals(Object obj) {
79 | if (this == obj)
80 | return true;
81 | if (obj == null)
82 | return false;
83 | if (getClass() != obj.getClass())
84 | return false;
85 | Task other = (Task) obj;
86 | if (completed != other.completed)
87 | return false;
88 | if (endDate == null) {
89 | if (other.endDate != null)
90 | return false;
91 | } else if (!endDate.equals(other.endDate))
92 | return false;
93 | if (name == null) {
94 | if (other.name != null)
95 | return false;
96 | } else if (!name.equals(other.name))
97 | return false;
98 | if (priority != other.priority)
99 | return false;
100 | if (startDate == null) {
101 | if (other.startDate != null)
102 | return false;
103 | } else if (!startDate.equals(other.startDate))
104 | return false;
105 | return true;
106 | }
107 |
108 | @Override
109 | public String toString() {
110 | return "Task [name=" + name + ", priority=" + priority + ", startDate="
111 | + startDate + ", endDate=" + endDate + ", completed="
112 | + completed + "]";
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/groovy/range/Geocoder.groovy:
--------------------------------------------------------------------------------
1 | package range
2 |
3 | class Geocoder {
4 | public static final String BASE =
5 | 'http://maps.google.com/maps/api/geocode/xml?'
6 |
7 | void fillInLatLng(TrainStation station) {
8 | String encoded =
9 | [station.city, station.state].collect {
10 | URLEncoder.encode(it,'UTF-8')
11 | }.join(',')
12 | String qs = [sensor:false, address: encoded].collect { it }.join('&')
13 | println "$BASE$qs"
14 | def response = new XmlSlurper().parse("$BASE$qs")
15 | station.latitude = response.result[0].geometry.location.lat.toBigDecimal()
16 | station.longitude = response.result[0].geometry.location.lng.toBigDecimal()
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/groovy/range/TrainStation.groovy:
--------------------------------------------------------------------------------
1 | package range
2 |
3 | import java.text.NumberFormat
4 |
5 | class TrainStation implements Comparable {
6 |
7 | // Links to next and previous stations
8 | TrainStation next
9 | TrainStation previous
10 |
11 | // location attributes
12 | String city
13 | String state
14 |
15 | // set by Geocoder service
16 | BigDecimal latitude
17 | BigDecimal longitude
18 |
19 | @Override
20 | int compareTo(TrainStation ts) {
21 | this.latitude <=> ts.latitude
22 | }
23 |
24 | TrainStation next() { next }
25 | TrainStation previous() { previous }
26 |
27 | String toString() {
28 | NumberFormat nf = NumberFormat.instance
29 | "$city, $state \t (${nf.format(latitude)}, ${nf.format(longitude)})"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/groovy/range/amtrak_ne_corridor.groovy:
--------------------------------------------------------------------------------
1 | package range
2 |
3 | TrainStation was = new TrainStation(city:'Washington', state:'DC')
4 | TrainStation bal = new TrainStation(city:'Baltimore', state:'MD')
5 | TrainStation wil = new TrainStation(city:'Wilmington', state:'DE')
6 | TrainStation phl = new TrainStation(city:'Philadelphia', state:'PA')
7 | TrainStation nwk = new TrainStation(city:'Newark', state:'NJ')
8 | TrainStation nyc = new TrainStation(city:'New York', state:'NY')
9 | TrainStation nhv = new TrainStation(city:'New Haven', state:'CT')
10 | TrainStation pvd = new TrainStation(city:'Providence', state:'RI')
11 | TrainStation bos = new TrainStation(city:'Boston', state:'MA')
12 |
13 | def ne_corridor = [was, bal, wil, phl, nwk, nyc, nhv, pvd, bos]
14 |
15 | was.next = bal; bal.previous = was
16 | bal.next = wil; wil.previous = bal
17 | wil.next = phl; phl.previous = wil
18 | phl.next = nwk; nwk.previous = phl
19 | nwk.next = nyc; nyc.previous = nwk
20 | nyc.next = nhv; nhv.previous = nyc
21 | nhv.next = pvd; pvd.previous = nhv
22 | pvd.next = bos; bos.previous = pvd
23 |
24 | Geocoder geo = new Geocoder()
25 | ne_corridor.each { station ->
26 | geo.fillInLatLng(station)
27 | }
28 |
29 | // heading north
30 | println '\nNorthbound from WAS to BOS'
31 | (was..bos).each { println it }
32 |
33 | // heading south
34 | println '\nSouthbound from BOS to WAS'
35 | (bos..was).each { println it }
36 |
37 | // nyc to bos
38 | println '\nNYC to BOS'
39 | (nyc..bos).each { println it.city }
--------------------------------------------------------------------------------
/src/main/groovy/sorting/Person.groovy:
--------------------------------------------------------------------------------
1 | package sorting
2 |
3 | import groovy.transform.EqualsAndHashCode;
4 | import groovy.transform.ToString;
5 |
6 | @EqualsAndHashCode
7 | @ToString(includeNames=true)
8 | class Person {
9 | String name
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/groovy/sorting/SortStringsByLength.java:
--------------------------------------------------------------------------------
1 | package sorting;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collections;
5 | import java.util.Comparator;
6 |
7 | import java.util.List;
8 |
9 | public class SortStringsByLength {
10 | public static void main(String[] args) {
11 | List strings = new ArrayList();
12 | strings.add("this");
13 | strings.add("is");
14 | strings.add("a");
15 | strings.add("list");
16 | strings.add("of");
17 | strings.add("strings");
18 | Collections.sort(strings, new Comparator() {
19 | public int compare(String s1, String s2) {
20 | return s1.length() - s2.length();
21 | }
22 | });
23 | System.out.println(strings);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/groovy/sorting/sort_list.groovy:
--------------------------------------------------------------------------------
1 | package sorting
2 |
3 | def strings = ['here','are','a','few','strings']
4 |
5 | // Sorting with a one-parameter closure
6 | def sorted = strings.sort { it.size() }
7 | assert sorted*.size() == [1, 3, 3, 4, 7]
8 |
9 | // Can't be sure of the order of equal length strings
10 | // assert sorted == ['a','are','few','here','strings']
11 |
12 | // Default (lexicographical) sort
13 | assert strings.sort() == ['a','are','few','here','strings']
14 |
15 | // Sort by length, then equal lengths alphabetically
16 | sorted = strings.sort { s1, s2 ->
17 | s1.size() <=> s2.size() ?: s1 <=> s2
18 | }
19 | assert sorted*.size() == [1, 3, 3, 4, 7]
20 |
21 | // Sort Person instances
22 | def peter = new Person(name:'Peter')
23 | def lois = new Person(name:'Lois')
24 | def chris = new Person(name:'Chris')
25 | def meg = new Person(name:'Meg')
26 | def stewie = new Person(name:'Stewie')
27 | def people = [peter, lois, chris, meg, stewie]
28 |
29 | assert people.sort { it.name } == [chris, lois, meg, peter, stewie]
30 | assert people.sort { it.name.size() } == [meg, lois, chris, peter, stewie]
31 |
--------------------------------------------------------------------------------
/src/test/groovy/ast/immutable/PointSpec.groovy:
--------------------------------------------------------------------------------
1 | package ast.immutable
2 |
3 | import spock.lang.Specification
4 |
5 | class PointSpec extends Specification {
6 | Point p
7 |
8 | def 'can use map-based constructor'() {
9 | when:
10 | p = new Point(x:3, y:4)
11 |
12 | then:
13 | p.x == 3
14 | p.y == 4
15 | }
16 |
17 | def 'can use tuple constructor'() {
18 | when:
19 | p = new Point(3, 4)
20 |
21 | then:
22 | p.x == 3
23 | p.y == 4
24 | }
25 |
26 | def 'equals method works'() {
27 | when:
28 | p = new Point(3, 4)
29 | Point p1 = new Point(3, 4)
30 | Point p2 = new Point(x:3, y:5)
31 |
32 | then:
33 | p == p1
34 | p1 != p2
35 | }
36 |
37 | def 'equals and hashcode work in a set'() {
38 | when:
39 | p = new Point(3, 4)
40 | Point p1 = new Point(3, 4)
41 | Point p2 = new Point(x:3, y:5)
42 | Set points = [p, p1, p2]
43 |
44 | then:
45 | points.size() == 2
46 | }
47 |
48 | def "can't change x"() {
49 | given:
50 | p = new Point(x:3, y:4)
51 |
52 | when:
53 | p.x = 5
54 |
55 | then:
56 | ReadOnlyPropertyException e = thrown()
57 | }
58 |
59 | def "can't change y"() {
60 | given:
61 | p = new Point(x:3, y:4)
62 |
63 | when:
64 | p.y = 5
65 |
66 | then:
67 | ReadOnlyPropertyException e = thrown()
68 | }
69 |
70 | def 'can you change x using direct ref?'() {
71 | given:
72 | p = new Point(x:3, y:4)
73 |
74 | when:
75 | p.@y = 5
76 |
77 | then:
78 | GroovyRuntimeException e = thrown()
79 | e.message == 'Cannot set the property \'y\' because the backing field is final.'
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/groovy/ast/singleton/SingletonPointSpec.groovy:
--------------------------------------------------------------------------------
1 | package ast.singleton
2 |
3 | import spock.lang.Specification;
4 |
5 | class SingletonPointSpec extends Specification {
6 | def "can't instantiate"() {
7 | when: new SingletonPoint(x:3,y:4)
8 | then: thrown(RuntimeException)
9 | }
10 |
11 | def "instance is not null"() {
12 | expect: SingletonPoint.instance
13 | }
14 |
15 | def "can change values"() {
16 | when:
17 | SingletonPoint.instance.x = 3
18 | SingletonPoint.instance.y = 4
19 |
20 | then:
21 | SingletonPoint.instance.x == 3
22 | SingletonPoint.instance.y == 4
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/groovy/coercedclosures/CoercedClosureMapTest.groovy:
--------------------------------------------------------------------------------
1 | package coercedclosures
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 |
6 | class CoercedClosureMapTest {
7 | UtilityMethods impl
8 |
9 | @Before
10 | void setUp() {
11 | // Implement interface using map of closures
12 | impl = [getPositives: {int... values ->
13 | values.findAll { it > 0 } as int[]},
14 |
15 | isPalindrome: {String s ->
16 | String str = s.toLowerCase().replaceAll(/\W/,'')
17 | str.reverse() == str
18 | }] as UtilityMethods
19 | }
20 |
21 | @Test
22 | void testGetPositives() {
23 | def correct = [1, 2, 3]
24 | def results = impl.getPositives(-3..3 as int[])
25 | assert results.every { it > 0 }
26 | }
27 |
28 | @Test
29 | void testIsPalindrome() {
30 | assert impl.isPalindrome('No cab, no tuna nut on bacon')
31 | assert impl.isPalindrome('Do geese see God?')
32 | assert impl.isPalindrome("Go hang a salami; I'm a lasagna hog!")
33 | assert impl.isPalindrome('A Santa pets rats, as Pat taps a star step at NASA.')
34 | assert impl.isPalindrome('Oy, Oy, a tonsil is not a yo-yo.')
35 | assert impl.isPalindrome('''
36 | A man, a plan, a caret, a ban, a myriad, a sum, a lac, a liar, a hoop, a pint,
37 | a catalpa, a gas, an oil, a bird, a yell, a vat, a caw, a pax, a wag, a tax,
38 | a nay, a ram, a cap, a yam, a gay, a tsar, a wall, a car, a luger, a ward, a bin,
39 | a woman, a vassal, a wolf, a tuna, a nit, a pall, a fret, a watt, a bay, a daub,
40 | a tan, a cab, a datum, a gall, a hat, a fag, a zap, a say, a jaw, a lay, a wet,
41 | a gallop, a tug, a trot, a trap, a tram, a torr, a caper, a top, a tonk, a toll,
42 | a ball, a fair, a sax, a minim, a tenor, a bass, a passer, a capital, a rut,
43 | an amen, a ted, a cabal, a tang, a sun, an ass, a maw, a sag, a jam, a dam, a sub,
44 | a salt, an axon, a sail, an ad, a wadi, a radian, a room, a rood, a rip, a tad,
45 | a pariah, a revel, a reel, a reed, a pool, a plug, a pin, a peek, a parabola,
46 | a dog, a pat, a cud, a nu, a fan, a pal, a rum, a nod, an eta, a lag, an eel,
47 | a batik, a mug, a mot, a nap, a maxim, a mood, a leek, a grub, a gob, a gel,
48 | a drab, a citadel, a total, a cedar, a tap, a gag, a rat, a manor, a bar, a gal,
49 | a cola, a pap, a yaw, a tab, a raj, a gab, a nag, a pagan, a bag, a jar, a bat,
50 | a way, a papa, a local, a gar, a baron, a mat, a rag, a gap, a tar, a decal, a tot,
51 | a led, a tic, a bard, a leg, a bog, a burg, a keel, a doom, a mix, a map, an atom,
52 | a gum, a kit, a baleen, a gala, a ten, a don, a mural, a pan, a faun, a ducat,
53 | a pagoda, a lob, a rap, a keep, a nip, a gulp, a loop, a deer, a leer, a lever,
54 | a hair, a pad, a tapir, a door, a moor, an aid, a raid, a wad, an alias, an ox,
55 | an atlas, a bus, a madam, a jag, a saw, a mass, an anus, a gnat, a lab, a cadet,
56 | an em, a natural, a tip, a caress, a pass, a baronet, a minimax, a sari, a fall,
57 | a ballot, a knot, a pot, a rep, a carrot, a mart, a part, a tort, a gut, a poll,
58 | a gateway, a law, a jay, a sap, a zag, a fat, a hall, a gamut, a dab, a can,
59 | a tabu, a day, a batt, a waterfall, a patina, a nut, a flow, a lass, a van, a mow,
60 | a nib, a draw, a regular, a call, a war, a stay, a gam, a yap, a cam, a ray, an ax,
61 | a tag, a wax, a paw, a cat, a valley, a drib, a lion, a saga, a plat, a catnip,
62 | a pooh, a rail, a calamus, a dairyman, a bater, a canal - Panama!
63 | ''')
64 | assert !impl.isPalindrome('This is not a palindrome')
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/test/groovy/coercedclosures/GTCSubclassTest.groovy:
--------------------------------------------------------------------------------
1 | package coercedclosures
2 |
3 | class GTCSubclassTest extends GroovyTestCase {
4 | UtilityMethods impl = new GroovyUtilityMethods()
5 |
6 | void testGetPositives() {
7 | log.info('inside testGetPositives')
8 | def correct = [1, 2, 3]
9 | def results = impl.getPositives(-3..3 as int[])
10 |
11 | // using special GTC methods
12 | assertLength(3, results)
13 | assertArrayEquals(correct as Integer[], results as Integer[])
14 | correct.each { assertContains(it, results) }
15 | }
16 |
17 | void testIsPalindrome() {
18 | assert impl.isPalindrome('No cab, no tuna nut on bacon')
19 | assert impl.isPalindrome('Do geese see God?')
20 | assert impl.isPalindrome("Go hang a salami; I'm a lasagna hog!")
21 | assert !impl.isPalindrome('This is not a palindrome')
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/test/groovy/coercedclosures/GroovyJUnit4Test.groovy:
--------------------------------------------------------------------------------
1 | package coercedclosures
2 |
3 | import org.junit.Test
4 |
5 | class GroovyJUnit4Test {
6 | UtilityMethods impl = new GroovyUtilityMethods()
7 |
8 | @Test
9 | void testGetPositives() {
10 | def results = impl.getPositives(-3..3 as int[])
11 | assert results.size() == 3
12 | assert results.every { it > 0 }
13 | }
14 |
15 | @Test
16 | void testIsPalindrome() {
17 | assert impl.isPalindrome('No cab, no tuna nut on bacon')
18 | assert impl.isPalindrome('Do geese see God?')
19 | assert impl.isPalindrome("Go hang a salami; I'm a lasagna hog!")
20 | assert !impl.isPalindrome('This is not a palindrome')
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/groovy/coercedclosures/ListDirectoriesTest.java:
--------------------------------------------------------------------------------
1 | package coercedclosures;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import java.io.File;
6 |
7 |
8 | import org.junit.Test;
9 |
10 | import coercedclosures.ListDirectories;
11 |
12 | public class ListDirectoriesTest {
13 | private ListDirectories ld = new ListDirectories();
14 |
15 | @Test
16 | public void testListDirectoryNames() {
17 | String[] dirs = ld.listDirectoryNames("/");
18 | for (String name : dirs) {
19 | System.out.println(name);
20 | assertTrue(new File(name).isDirectory());
21 | }
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/groovy/hr/DepartmentSpec.groovy:
--------------------------------------------------------------------------------
1 | package hr;
2 |
3 | import static org.junit.Assert.*
4 | import spock.lang.Specification
5 |
6 | class DepartmentSpec extends Specification {
7 | Department dept = new Department(name:'IT')
8 |
9 | def "add employee to dept should increase total by 1"() {
10 | given:
11 | Employee fred = new Employee(name:'Fred',id:1)
12 |
13 | when:
14 | dept = dept + fred
15 |
16 | then:
17 | dept.employees.size() == old(dept.employees.size()) + 1
18 | }
19 |
20 | def "add two employees via chained plus"() {
21 | given:
22 | Employee fred = new Employee(name:'Fred',id:1)
23 | Employee barney = new Employee(name:'Barney',id:2)
24 |
25 | when:
26 | dept = dept + fred + barney
27 |
28 | then:
29 | dept.employees.size() == 2
30 | }
31 |
32 | def "subtract emp from dept should decrease by 1"() {
33 | given:
34 | Employee fred = new Employee(name:'Fred',id:1)
35 | dept.hire fred
36 |
37 | when:
38 | dept = dept - fred
39 |
40 | then:
41 | dept.employees.size() == old(dept.employees.size()) - 1
42 | }
43 |
44 | def "remove two employees via chained minus"() {
45 | given:
46 | Employee fred = new Employee(name:'Fred',id:1)
47 | Employee barney = new Employee(name:'Barney',id:2)
48 | dept.hire fred
49 | dept.hire barney
50 |
51 | when:
52 | dept = dept - fred - barney
53 |
54 | then:
55 | dept.employees.size() == 0
56 | }
57 |
58 | def "add employee to dept via left shift should increase total by 1"() {
59 | given:
60 | Employee fred = new Employee(name:'Fred',id:1)
61 |
62 | when:
63 | dept = dept << fred
64 |
65 | then:
66 | dept.employees.size() == old(dept.employees.size()) + 1
67 | }
68 |
69 | def "add two employees via chained left shift"() {
70 | given:
71 | Employee fred = new Employee(name:'Fred',id:1)
72 | Employee barney = new Employee(name:'Barney',id:2)
73 |
74 | when:
75 | dept = dept << fred << barney
76 |
77 | then:
78 | dept.employees.size() == 2
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/groovy/hr/JavaDepartmentSpec.groovy:
--------------------------------------------------------------------------------
1 | package hr;
2 |
3 | import static org.junit.Assert.*
4 | import spock.lang.Specification
5 |
6 | class JavaDepartmentSpec extends Specification {
7 | JavaDepartment dept = new JavaDepartment(name:'IT');
8 |
9 | def "add employee to dept should increase total by 1"() {
10 | given:
11 | Employee fred = new Employee(name:'Fred',id:1)
12 |
13 | when:
14 | dept = dept + fred
15 |
16 | then:
17 | dept.employees.size() ==
18 | old(dept.employees.size()) + 1
19 | }
20 |
21 | def "add two employees via chained plus"() {
22 | given:
23 | Employee fred = new Employee(name:'Fred',id:1)
24 | Employee barney = new Employee(name:'Barney',id:2)
25 |
26 | when:
27 | dept = dept + fred + barney
28 |
29 | then:
30 | dept.employees.size() == 2
31 | }
32 |
33 | def "subtract emp from dept should decrease by 1"() {
34 | given:
35 | Employee fred = new Employee(name:'Fred',id:1)
36 | dept.hire fred
37 |
38 | when:
39 | dept = dept - fred
40 |
41 | then:
42 | dept.employees.size() == old(dept.employees.size()) - 1
43 | }
44 |
45 | def "remove two employees via chained minus"() {
46 | given:
47 | Employee fred = new Employee(name:'Fred',id:1)
48 | Employee barney = new Employee(name:'Barney',id:2)
49 | dept.hire fred
50 | dept.hire barney
51 |
52 | when:
53 | dept = dept - fred - barney
54 |
55 | then:
56 | dept.employees.size() == 0
57 | }
58 |
59 | def "add employee to dept via left shift should increase total by 1"() {
60 | given:
61 | Employee fred = new Employee(name:'Fred',id:1)
62 |
63 | when:
64 | dept = dept << fred
65 |
66 | then:
67 | dept.employees.size() == old(dept.employees.size()) + 1
68 | }
69 |
70 | def "add two employees via chained left shift"() {
71 | given:
72 | Employee fred = new Employee(name:'Fred',id:1)
73 | Employee barney = new Employee(name:'Barney',id:2)
74 |
75 | when:
76 | dept = dept << fred << barney
77 |
78 | then:
79 | dept.employees.size() == 2
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/src/test/groovy/metaprogramming/ComplexSpec.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming
2 |
3 | import static org.apache.commons.math3.complex.Complex.*
4 | import static java.lang.Math.*
5 |
6 | import org.apache.commons.math3.complex.*
7 | import spock.lang.Specification
8 |
9 | class ComplexSpec extends Specification {
10 |
11 | def setupSpec() {
12 | Complex.metaClass.plus = { Complex c -> delegate.add c }
13 | Complex.metaClass.minus = { Complex c -> delegate.subtract c }
14 | Complex.metaClass.div = { Complex c -> delegate.divide c }
15 | Complex.metaClass.power = { Complex c -> delegate.pow c }
16 | Complex.metaClass.negative = { delegate.negate() }
17 | Double.metaClass.power = { Complex c -> (new Complex(delegate,0)).pow(c) }
18 | }
19 |
20 | def "plus method aliased to add"() {
21 | given:
22 | Complex first = new Complex(1.0, 3.0)
23 | Complex second = new Complex(2.0, 5.0)
24 |
25 | expect:
26 | new Complex(3.0, 8.0) == first + second
27 | }
28 |
29 | def "minus method aliased to subtract"() {
30 | given:
31 | Complex first = new Complex(1.0, 3.0);
32 | Complex second = new Complex(2.0, 5.0);
33 |
34 | expect:
35 | new Complex(1.0, 2.0) == second - first
36 | }
37 |
38 | def "negative method negates complex"() {
39 | given:
40 | Complex minus1 = -ONE
41 |
42 | expect:
43 | minus1.real == -1
44 | minus1.imaginary.abs() == 0
45 | }
46 |
47 | def "Euler's formula still works"() {
48 | when:
49 | Complex result = E ** (I * PI)
50 |
51 | then:
52 | result.real == -1
53 | result.imaginary.abs() < 1e-15
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/test/groovy/metaprogramming/CurrencyCategorySpec.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming
2 |
3 | import spock.lang.Specification
4 |
5 | class CurrencyCategorySpec extends Specification {
6 |
7 | def "asCurrency with default locale use en-US"() {
8 | given:
9 | BigDecimal amount = 1234567.8901234
10 | String result = ''
11 |
12 | when:
13 | use(CurrencyCategory) {
14 | result = amount.asCurrency()
15 | }
16 |
17 | then:
18 | result == '$1,234,567.89'
19 | }
20 |
21 | def "asCurrency with given locale formats correctly"() {
22 | given:
23 | BigDecimal amount = 1234567.8901234
24 | String result = ''
25 |
26 | when:
27 | use(CurrencyCategory) {
28 | result = amount.asCurrency(Locale.FRANCE)
29 | }
30 |
31 | then:
32 | result == '1 234 567,89 €'
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/groovy/metaprogramming/LoggingTests.groovy:
--------------------------------------------------------------------------------
1 | package metaprogramming;
2 |
3 | import metaprogramming.without_custom_levels
4 | import metaprogramming.use_slang_category
5 | import metaprogramming.use_emc
6 |
7 | import java.util.logging.Level;
8 | import java.util.logging.Logger;
9 |
10 | class LoggingTests extends GroovyLogTestCase {
11 | String baseDir = 'src/main/groovy/metaprogramming'
12 |
13 | void testWithoutCustomLevel() {
14 | def result = stringLog(Level.INFO, without_custom_levels.class.name) {
15 | GroovyShell shell = new GroovyShell()
16 | shell.evaluate(new File("$baseDir/without_custom_levels.groovy"))
17 | }
18 | assert result.contains('INFO: for your information')
19 | assert result.contains('SEVERE: oh my goodness')
20 | }
21 |
22 | void testSlangCategory() {
23 | def result = stringLog(Level.INFO, use_slang_category.class.name) {
24 | GroovyShell shell = new GroovyShell()
25 | shell.evaluate(new File("$baseDir/use_slang_category.groovy"))
26 | }
27 | assert result.contains('FYI: this seems okay')
28 | assert result.contains('LOL: snicker')
29 | }
30 |
31 | void testEMC() {
32 | def result = stringLog(Level.INFO, use_emc.class.name) {
33 | GroovyShell shell = new GroovyShell()
34 | shell.evaluate(new File("$baseDir/use_emc.groovy"))
35 | }
36 | assert result.contains('WHOA: dude, seriously')
37 | assert result.contains("ROFL: you're kidding, right?")
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/groovy/openweather/ModelSpec.groovy:
--------------------------------------------------------------------------------
1 | package openweather
2 |
3 | import spock.lang.Specification
4 |
5 |
6 | class ModelSpec extends Specification {
7 | Model model = new Model()
8 |
9 | def 'convertTemp converts from Kelvin to F'() {
10 | expect:
11 | 32.0 == model.convertTemp(273.15)
12 | 212.0 == model.convertTemp(373.15)
13 | }
14 |
15 | def 'convertSpeed converts from meters/sec to miles/hour'() {
16 | expect:
17 | (2.23694 - model.convertSpeed(1)).abs() < 0.00001
18 | }
19 |
20 | def 'convertTime converts from Unix time to java.util.Date'() {
21 | given:
22 | Calendar cal = Calendar.instance
23 | cal.set(1992, Calendar.MAY, 5)
24 | Date d = cal.time
25 | long time = d.time / 1000 // Java time in ms, Unix time in sec
26 |
27 | when:
28 | Date date = model.convertTime(time)
29 |
30 | then:
31 | d - date < 1
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/test/groovy/openweather/OpenWeatherSpec.groovy:
--------------------------------------------------------------------------------
1 | package openweather
2 |
3 | import spock.lang.Specification
4 |
5 | class OpenWeatherSpec extends Specification {
6 | OpenWeather ow = new OpenWeather()
7 |
8 | def 'default city and state return weather string'() {
9 | when:
10 | String result = ow.weather
11 | println result
12 |
13 | then:
14 | result
15 | result.contains('41.76')
16 | result.contains('-72.69')
17 | }
18 |
19 | def 'Boston, US works'() {
20 | when:
21 | String result = ow.getWeather('Boston','US')
22 | println result
23 |
24 | then:
25 | result
26 | result.contains('42.36')
27 | result.contains('-71.06')
28 | }
29 |
30 | def "The weather is always great in Honolulu"() {
31 | when:
32 | String result = ow.getWeather('Honolulu', 'US')
33 | println result
34 |
35 | then:
36 | result
37 | result.contains('21.3')
38 | result.contains('-157.86')
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/groovy/pogo/TaskTest.java:
--------------------------------------------------------------------------------
1 | package pogo;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertFalse;
5 | import static org.junit.Assert.assertTrue;
6 |
7 | import java.util.Calendar;
8 | import java.util.Date;
9 |
10 | import org.junit.Test;
11 |
12 | public class TaskTest {
13 | private Date now = new Date();
14 | private Task t = new Task("name", 3, now, now, false);
15 |
16 | @Test
17 | public void testGetName() {
18 | assertEquals("name", t.getName());
19 | }
20 |
21 | @Test
22 | public void testSetName() {
23 | t.setName("other");
24 | assertEquals("other", t.getName());
25 | }
26 |
27 | @Test
28 | public void testGetPriority() {
29 | assertEquals(3, t.getPriority());
30 | }
31 |
32 | @Test
33 | public void testSetPriority() {
34 | t.setPriority(4);
35 | assertEquals(4, t.getPriority());
36 | }
37 |
38 | @Test
39 | public void testGetStartDate() {
40 | assertEquals(now, t.getStartDate());
41 | }
42 |
43 | @Test
44 | public void testSetStartDate() {
45 | Calendar cal = Calendar.getInstance();
46 | cal.set(2013, Calendar.MARCH, 21);
47 | Date spring = cal.getTime();
48 | t.setStartDate(spring);
49 | assertEquals(spring, t.getStartDate());
50 | }
51 |
52 | @Test
53 | public void testGetEndDate() {
54 | assertEquals(now, t.getEndDate());
55 | }
56 |
57 | @Test
58 | public void testSetEndDate() {
59 | Calendar cal = Calendar.getInstance();
60 | cal.set(2013, Calendar.MARCH, 21);
61 | Date spring = cal.getTime();
62 | t.setEndDate(spring);
63 | assertEquals(spring, t.getEndDate());
64 | }
65 |
66 | @Test
67 | public void testIsCompleted() {
68 | assertFalse(t.isCompleted());
69 | }
70 |
71 | @Test
72 | public void testSetCompleted() {
73 | t.setCompleted(true);
74 | assertTrue(t.isCompleted());
75 | }
76 | }
77 |
--------------------------------------------------------------------------------