pax_global_header00006660000000000000000000000064120202252330014501gustar00rootroot0000000000000052 comment=2310f1830ff8342356fac6635a8bcf92d50177df spock-0.6-groovy-1.8/000077500000000000000000000000001202022523300143145ustar00rootroot00000000000000spock-0.6-groovy-1.8/.gitignore000066400000000000000000000005241202022523300163050ustar00rootroot00000000000000# entries starting with and ending in / will be excluded from root IDEA module, # and entries ending in / from all IDEA modules (see ide.gradle) # Gradle .gradle/ build/ # Maven target/ # IDEA .idea/ *.iml *.ipr *.iws out/ # Eclipse .project .classpath .settings/ bin/ # Grails stacktrace.log # Sphinx /docs/_build/ # Other .DS_Storespock-0.6-groovy-1.8/LICENSE000066400000000000000000000261351202022523300153300ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.spock-0.6-groovy-1.8/NOTICE000066400000000000000000000013261202022523300152220ustar00rootroot00000000000000========================================================================= == NOTICE file corresponding to the section 4 d of == == the Apache License, Version 2.0, == == in this case for the Spock distribution. == ========================================================================= This product includes software developed by The Apache Software Foundation (http://www.apache.org/). It includes the following other software: gentyref (http://code.google.com/p/gentyref/) For licenses see the LICENSE file. If any software distributed with Spock does not have an Apache 2 License, its license is explicitly listed in the LICENSE file.spock-0.6-groovy-1.8/README000066400000000000000000000043721202022523300152020ustar00rootroot00000000000000Spock Framework README ====================== Spock is a developer testing and specification framework for Java and Groovy applications. To learn more about Spock, visit http://spockframework.org. To run your first spec right away, visit http://meet.spockframework.org. Current release versions: 0.6-groovy-1.7, 0.6-groovy-1.8 (released 2012-03-02) Current development versions: 0.7-groovy-1.8-SNAPSHOT, 0.7-groovy-2.0-SNAPSHOT Modules ------- spock-core: Core framework. spock-specs: Specifications for spock-core, written with Spock. Not required for using the framework. spock-maven: Extended Maven support (optional). spock-example: Self-contained example project with Ant, Gradle, and Maven build. See spock-example/README for more information. spock-spring: Integration with the Spring TestContext Framework. spock-tapestry: Integration with the Tapestry 5 IoC container. spock-guice: Integration with Guice 2. spock-unitils: Integration with Unitils (http://www.unitils.org/). spock-grails: The Grails plugin is now its own project hosted at https://github.com/spockframework/spock-grails. Building Spock yourself ----------------------- Prerequisites: JDK 5 or higher Type: ./gradlew clean build If not already present, build dependencies (including Gradle itself) will be downloaded automatically. Further Resources ----------------- Spock homepage http://spockframework.org Spock web console http://webconsole.spockframework.org Main documentation http://wiki.spockframework.org/SpockBasics User discussion group http://forum.spockframework.org Dev discussion group http://dev.forum.spockframework.org Issue tracker http://issues.spockframework.org Build server http://builds.spockframework.org Maven repository http://m2repo.spockframework.org (releases are also available from Maven Central) Spock blog http://blog.spockframework.org Spock on Twitter http://twitter.com/pniederw Ant homepage http://ant.apache.org Gradle homepage http://www.gradle.org Groovy homepage http://groovy.codehaus.org Maven homepage http://maven.apache.org If you have any comments or questions, please direct them to the Spock discussion group. All feedback is appreciated! Happy spec'ing! Peter Niederwieser Creator, Spock Frameworkspock-0.6-groovy-1.8/build.gradle000077500000000000000000000044651202022523300166070ustar00rootroot00000000000000description = "Spock Framework" libs = [ ant: "org.apache.ant:ant:1.8.2", // use same version as Groovy 1.8 asm: "asm:asm:3.2", // use same version as Groovy 1.8 cglib: "cglib:cglib-nodep:2.2", easymock: "org.easymock:easymock:3.0", groovy: "org.codehaus.groovy:groovy-all:1.8.5", h2database: "com.h2database:h2:1.3.164", hamcrest_core: "org.hamcrest:hamcrest-core:1.2", jmock: "org.jmock:jmock:2.5.1", jmock_junit4: "org.jmock:jmock-junit4:2.5.1", junit: "junit:junit-dep:4.9", log4j: "log4j:log4j:1.2.16", mockito: "org.mockito:mockito-all:1.9.0", objenesis: "org.objenesis:objenesis:1.2" ] allprojects { group = "org.spockframework" version = "0.6-groovy-1.8" apply from: script("common") } apply from: script("ide") subprojects { apply plugin: "groovy" apply plugin: "signing" sourceCompatibility = 1.5 repositories { mavenCentral() } configurations { all*.exclude module: "junit" // we use junit-dep instead } dependencies { groovy libs.groovy } signing { sign configurations.archives required { !isSnapshotVersion && gradle.taskGraph.hasTask(uploadArchives) } } tasks.withType(Compile) { task -> options.useAnt = false } configureJavadoc(javadoc) task sourcesJar(type: Jar) { classifier "sources" from sourceSets.main.allSource } task javadocJar(type: Jar) { classifier "javadoc" from javadoc } artifacts { archives sourcesJar, javadocJar } } task javadoc(type: Javadoc) { title "Spock Framework API Documentation ($version)" destinationDir file("build/javadoc") source subprojects.javadoc.source classpath = files(subprojects.javadoc.classpath) } configureJavadoc(javadoc) task publishJavadoc(type: Sync) { from javadoc into "file:///var/www/spock/javadoc/$version/" } task wrapper(type: Wrapper) { gradleVersion = "1.0-milestone-8a" } File script(String name) { project.file("gradle/${name}.gradle") } def configureJavadoc(task) { configure(task) { include "spock/**" configure(options) { links "http://download.oracle.com/javase/1.5.0/docs/api/" links "http://groovy.codehaus.org/gapi" links "http://kentbeck.github.com/junit/javadoc/4.9" links "http://www.jarvana.com/jarvana/inspect/org/hamcrest/hamcrest-core/1.2/hamcrest-core-1.2-javadoc.jar" } } } spock-0.6-groovy-1.8/config/000077500000000000000000000000001202022523300155615ustar00rootroot00000000000000spock-0.6-groovy-1.8/config/ant-junit/000077500000000000000000000000001202022523300174725ustar00rootroot00000000000000spock-0.6-groovy-1.8/config/ant-junit/junit-frames.xsl000066400000000000000000001015231202022523300226300ustar00rootroot00000000000000 Unit Test Results. . <xsl:value-of select="$TITLE"/> <h2>Frame Alert</h2> <p> This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. </p> body { font:normal 68% verdana,arial,helvetica; color:#000000; } table tr td, table tr th { font-size: 68%; } table.details tr th{ font-weight: bold; text-align:left; background:#a6caf0; } table.details tr td{ background:#eeeee0; } p { line-height:1.5em; margin-top:0.5em; margin-bottom:1.0em; } h1 { margin: 0px 0px 5px; font: 165% verdana,arial,helvetica } h2 { margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica } h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica } h4 { margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica } h5 { margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica } h6 { margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica } .Error { font-weight:bold; color:red; } .Failure { font-weight:bold; color:purple; } .Properties { text-align:right; } All Failures All Errors All Tests Unit Test Results: <xsl:value-of select="$title"/> open('allclasses-frame.html','classListFrame')

. Unit Test Results: <xsl:value-of select="$class.name"/>

Class

Failures

Errors

Tests

cur = TestCases['.'] = new Array(); cur[''] = ''; Unit Test Classes: <xsl:value-of select="$name"/>

<none>

Classes

All Unit Test Classes

Classes

/ _.html All Unit Test Packages

Home

Packages

<none> Unit Test Results: Summary open('allclasses-frame.html','classListFrame')

Summary

Error Failure Pass
Tests Failures Errors Success rate Time
Note: failures are anticipated and checked for with assertions while errors are unanticipated.

Packages

Error Failure Pass
<none>
open('package-frame.html','classListFrame')

Package

Classes

../ ../ stylesheet.css

Designed for use with JUnit and Ant.

Name Tests Errors Failures Time(s) Time Stamp Host Class Name Status Type Time(s) Error Failure Pass Error Failure TableRowColor Failure Error Success N/A
spock-0.6-groovy-1.8/config/ant-junit/junit-noframes.xsl000066400000000000000000000426131202022523300231710ustar00rootroot00000000000000 Unit Test Results. <xsl:value-of select="$TITLE"/>


Packages

Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers. Failure Error

Package

Back to top

TestCase

Back to top

Summary

Failure Error
Tests Failures Errors Success rate Time
Note: failures are anticipated and checked for with assertions while errors are unanticipated.
cur = TestCases['.'] = new Array(); cur[''] = '';

Designed for use with JUnit and Ant.

Name Tests Errors Failures Time(s) Name Tests Errors Failures Time(s) Time Stamp Host Name Status Type Time(s) Failure Error Error Failure Error Success N/A
spock-0.6-groovy-1.8/config/ideaCodeStyle.xml000066400000000000000000000024511202022523300210230ustar00rootroot00000000000000 spock-0.6-groovy-1.8/docs/000077500000000000000000000000001202022523300152445ustar00rootroot00000000000000spock-0.6-groovy-1.8/docs/Makefile000066400000000000000000000110161202022523300167030ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SpockFramework.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SpockFramework.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/SpockFramework" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SpockFramework" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." make -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." spock-0.6-groovy-1.8/docs/conf.py000066400000000000000000000160271202022523300165510ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Spock Framework documentation build configuration file, created by # sphinx-quickstart on Sat Jul 16 14:17:19 2011. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Spock Framework' copyright = u'2011, Peter Niederwieser, Luke Daley' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '0.6' # The full version, including alpha/beta/rc tags. release = '0.6' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'SpockFrameworkdoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'SpockFramework.tex', u'Spock Framework Documentation', u'Peter Niederwieser, Luke Daley', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'spockframework', u'Spock Framework Documentation', [u'Peter Niederwieser, Luke Daley'], 1) ] # -- Options added by us ------------------------------------------------------- highlight_language = 'java' spock-0.6-groovy-1.8/docs/getting_started.rst000066400000000000000000000022171202022523300211670ustar00rootroot00000000000000Getting Started =============== It's really easy to get started with Spock. This section shows you how. Spock Web Console ----------------- `Spock Web Console`_ is a website that allows you to instantly view, edit, run, and even publish Spock specifications. It is the perfect place to toy around with Spock without making any commitments. So why not run `Hello, Spock!`_ right now? Spock Example Project --------------------- To try Spock on your own computer, download and unzip the Example Project (`download link`_). It comes with fully working Ant, Gradle, and Maven builds that require no further setup. The Gradle build even bootstraps Gradle itself and gets you up and running in Eclipse or IDEA with a single command. See the README for detailed instructions. Next Steps ---------- The following sections provide further information on how to use Spock in a number of different environments: * Ant * Gradle * Maven * Groovy Console * Eclipse * IDEA .. _Spock Web Console: http://meet.spockframework.org .. _Hello, Spock!: http://meet.spockframework.org/?id=9001 .. _download link: http://files.spockframework.org/spock-example-0.5-groovy-1.7.zip spock-0.6-groovy-1.8/docs/index.rst000066400000000000000000000017411202022523300171100ustar00rootroot00000000000000.. Spock Framework documentation master file, created by sphinx-quickstart on Sat Jul 16 14:17:19 2011. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Spock Framework 0.6 Documentation ================================= Spock is a testing and specification framework for Java and Groovy applications. What makes it stand out from the crowd is its beautiful and highly expressive specification language. Thanks to its JUnit runner, Spock is compatible with most IDEs, build tools, and continuous integration servers. Spock is inspired from JUnit, jMock, RSpec, Groovy, Scala, Vulcans, and other fascinating life forms. Contents: .. toctree:: :maxdepth: 2 getting_started anatomy_of_a_specification state_based_testing data_driven_testing interaction_based_testing new_and_noteworthy migration_guide Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` spock-0.6-groovy-1.8/docs/make.bat000066400000000000000000000106571202022523300166620ustar00rootroot00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\SpockFramework.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\SpockFramework.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) :end spock-0.6-groovy-1.8/docs/migration_guide.rst000066400000000000000000000061071202022523300211500ustar00rootroot00000000000000Migration Guide =============== This page explains incompatible changes between successive versions and provides suggestions on how to deal with them. 0.6 --- Class initialization order ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. note:: This only affects cases where one specification class inherits from another one. Given these specifications:: class Base extends Specification { def base1 = "base1" def base2 def setup() { base2 = "base2" } } class Derived extends Base { def derived1 = "derived1" def derived2 def setup() { derived2 = "derived2" } } In 0.5, above assignments happened in the order ``base1``, ``base2``, ``derived1``, ``derived2``. In other words, field initializers were executed right before the setup method in the same class. In 0.6, assignments happen in the order ``base1``, ``derived1``, ``base2``, ``derived2``. This is a more conventional order that solves a few problems that users faced with the previous behavior, and also allows us to support JUnit's new ``TestRule``. As a result of this change, the following will no longer work:: class Base extends Specification { def base def setup() { base = "base" } } class Derived extends Base { def derived = base + "derived" // base is not yet set } To overcome this problem, you can either use a field initializer for ``base``, or move the assignment of ``derived`` into a setup method. ``@Unroll`` naming pattern syntax ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. note:: This is not a change from 0.5, but a change compared to 0.6-SNAPSHOT. .. note:: This only affects the Groovy 1.8 and 2.0 variants. In 0.5, the naming pattern was string based:: @Unroll("maximum of #a and #b is #c") def "maximum of two numbers"() { expect: Math.max(a, b) == c where: a | b | c 1 | 2 | 2 } In 0.6-SNAPSHOT, this was changed to a closure returning a ``GString``:: @Unroll({"maximum of $a and $b is $c"}) def "maximum of two numbers"() { ... } For various reasons, the new syntax didn't work out as we had hoped, and eventually we decided to go back to the string based syntax. See :ref:`improved-unroll-0.6` for recent improvements to that syntax. Hamcrest matcher syntax ~~~~~~~~~~~~~~~~~~~~~~~ .. note:: This only affects users moving from the Groovy 1.7 to the 1.8 or 2.0 variant. Spock offers a very neat syntax for using `Hamcrest `_ matchers:: import static spock.util.matcher.HamcrestMatchers.closeTo ... expect: answer closeTo(42, 0.001) Due to changes made between Groovy 1.7 and 1.8, this syntax no longer works in as many cases as it did before. For example, the following will no longer work:: expect: object.getAnswer() closeTo(42, 0.001) To avoid such problems, use ``HamcrestSupport.that``:: import static spock.util.matcher.HamcrestSupport.that ... expect: that answer, closeTo(42, 0.001) A future version of Spock will likely remove the former syntax and strengthen the latter one. spock-0.6-groovy-1.8/docs/new_and_noteworthy.rst000066400000000000000000000146711202022523300217240ustar00rootroot00000000000000New and Noteworthy ================== 0.6 ~~~ Mocking improvements -------------------- The mocking framework now provides better diagnostic messages in some cases. Multiple result declarations can be chained. The following causes method bar to throw an ``IOException`` when first called, return the numbers one, two, and three on the next calls, and throw a ``RuntimeException`` for all subsequent calls:: foo.bar() >> { throw new IOException() } >>> [1, 2, 3] >> { throw new RuntimeException() } It's now possible to match any argument list (including the empty list) with ``foo.bar(*_)``. Method arguments can now be constrained with `Hamcrest `_ matchers:: import static spock.util.matcher.HamcrestMatchers.closeTo ... 1 * foo.bar(closeTo(42, 0.001)) Extended JUnit rules support ---------------------------- In addition to rules implementing ``org.junit.rules.MethodRule`` (which has been deprecated in JUnit 4.9), Spock now also supports rules implementing the new ``org.junit.rules.TestRule`` interface. Also supported is the new ``@ClassRule`` annotation. Rule declarations are now verified and can leave off the initialization part. I that case Spock will automatically initialize the rule by calling the default constructor. The ``@TestName`` rule, and rules in general, now honor the ``@Unroll`` annotation and any defined naming pattern. See `Issue 240 `_ for a known limitation with Spock's TestRule support. Condition rendering improvements -------------------------------- When two objects are compared with the ``==`` operator, they are unequal, but their string representations are the same, Spock will now print the objects' types:: enteredNumber == 42 | | | false 42 (java.lang.String) JUnit fixture annotations ------------------------- Fixture methods can now be declared with JUnit's ``@Before``, ``@After``, ``@BeforeClass``, and ``@AfterClass`` annotations, as an addition or alternative to Spock's own fixture methods. This was particularly needed for Grails 2.0 support. Tapestry 5.3 support -------------------- Thanks to a contribution from `Howard Lewis Ship `_, the Tapestry module is now compatible with Tapestry 5.3. Older 5.x versions are still supported. IBM JDK support --------------- Spock now runs fine on IBM JDKs, working around a bug in the IBM JDK's verifier. Improved JUnit compatibility ---------------------------- ``org.junit.internal.AssumptionViolatedException`` is now recognized and handled as known from JUnit. ``@Unrolled`` methods no longer cause "yellow" nodes in IDEs. .. _improved-unroll-0.6: Improved ``@Unroll`` -------------------- The ``@Unroll`` naming pattern can now be provided in the method name, instead of as an argument to the annotation:: @Unroll def "maximum of #a and #b is #c"() { expect: Math.max(a, b) == c where: a | b | c 1 | 2 | 2 } The naming pattern now supports property access and zero-arg method calls:: @Unroll def "#person.name.toUpperCase() is #person.age years old"() { ... } The ``@Unroll`` annotation can now be applied to a spec class. In this case, all data-driven feature methods in the class will be unrolled. Improved ``@Timeout`` --------------------- The ``@Timeout`` annotation can now be applied to a spec class. In this case, the timeout applies to all feature methods (individually) that aren't already annotated with ``@Timeout``. Timed methods are now executed on the regular test framework thread. This can be important for tests that rely on thread-local state (like Grails integration tests). Also the interruption behavior has been improved, to increase the chance that a timeout can be enforced. The failure exception that is thrown when a timeout occurs now contains the stacktrace of test execution, allowing you to see where the test was “stuck†or how far it got in the allocated time. Improved data table syntax -------------------------- Table cells can now be separated with double pipes. This can be used to visually set apart expected outputs from provided inputs:: ... where: a | b || sum 1 | 2 || 3 3 | 1 || 4 Groovy 1.8/2.0 support ---------------------- Spock 0.6 ships in three variants for Groovy 1.7, 1.8, and 2.0. Make sure to pick the right version - for example, for Groovy 1.8 you need to use spock-core-0.6-groovy-1.8 (likewise for all other modules). The Groovy 2.0 variant is based on Groovy 2.0-beta-3-SNAPSHOT and only available from http://m2repo.spockframework.org. The Groovy 1.7 and 1.8 variants are also available from Maven Central. The next version of Spock will no longer support Groovy 1.7. Grails 2.0 support ------------------ Spock's Grails plugin was split off into a separate project and now lives at http://github.spockframework.org/spock-grails. The plugin supports both Grails 1.3 and 2.0. The Spock Grails plugin supports all of the new Grails 2.0 test mixins, effectively deprecating the existing unit testing classes (e.g. UnitSpec). For integration testing, IntegrationSpec must still be used. IntelliJ IDEA integration ------------------------- The folks from `JetBrains `_ have added a few handy features around data tables. Data tables will now be layed out automatically when reformatting code. Data variables are no longer shown as "unknown" and have their types inferred from the values in the table (!). GitHub repository ----------------- All source code has moved to http://github.spockframework.org/. The `Grails Spock plugin `_, `Spock Example `_ project, and `Spock Web Console `_ now have their own GitHub projects. Also available are slides and code for various Spock presentations (like `this one `_). Gradle build ------------ Spock is now exclusively built with Gradle. Building Spock yourself is as easy as cloning the `GitHub repo `_ and executing ``gradlew build``. No build tool installation is required; the only prerequisite for building Spock is a JDK installation (1.5 or higher). Fixed Issues ------------ See the `issue tracker `_ for a list of fixed issues. spock-0.6-groovy-1.8/gradle/000077500000000000000000000000001202022523300155525ustar00rootroot00000000000000spock-0.6-groovy-1.8/gradle/common.gradle000066400000000000000000000001511202022523300202170ustar00rootroot00000000000000isSnapshotVersion = project.version.endsWith("-SNAPSHOT") isRootProject = project == project.rootProject spock-0.6-groovy-1.8/gradle/ide.gradle000066400000000000000000000014321202022523300174730ustar00rootroot00000000000000allprojects { apply plugin: "idea" apply plugin: "eclipse" } def gitIgnore = file(".gitignore").readLines() def gitIgnoreDirs = gitIgnore*.trim().findAll { !it.startsWith("#") && it.endsWith("/") } def (topLevelDirs, allLevelDirs) = gitIgnoreDirs.split { it.startsWith("/") } topLevelDirs = topLevelDirs.collect { it.substring(1) } idea { project { jdkName "1.6" languageLevel "1.5" configure(modules) { module -> def prj = module.project excludeDirs = prj.files(allLevelDirs) as Set if (prj == prj.rootProject) excludeDirs += (prj.files(topLevelDirs) as Set) } ipr { withXml { provider -> def node = provider.asNode() node.component.find { it.'@name' == 'VcsDirectoryMappings' }?.mapping[0].'@vcs' = 'Git' } } } }spock-0.6-groovy-1.8/gradle/publishMaven.gradle000066400000000000000000000042651202022523300213760ustar00rootroot00000000000000apply plugin: "maven" basePom = { project { name project.displayName description project.description url "http://spockframework.org" licenses { license { name "The Apache Software License, Version 2.0" url "http://www.apache.org/licenses/LICENSE-2.0.txt" distribution "repo" } } scm { connection "scm:git:git://github.com/spockframework/spock.git" developerConnection "scm:git:ssh://git@github.com/spockframework/spock.git" url "http://github.spockframework.org/spock" } developers { developer { id "pniederw" name "Peter Niederwieser" email "pniederw@gmail.com" } developer { id "ldaley" name "Luke Daley" email "ld@ldaley.com" } } } } project.deployers = [] project.afterEvaluate { configure(project.deployers) { pom basePom } } install { project.deployers << repositories.mavenInstaller } uploadArchives { task -> project.deployers << repositories.mavenDeployer { if (isSnapshotVersion) { snapshotRepository(url: "file:///var/www/m2repo/snapshots") } else { repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { if (project.hasProperty("sonatypeOssUsername")) { authentication(userName: sonatypeOssUsername, password: sonatypeOssPassword) } } } } } project.poms = project.deployers*.pom modifyPom = { Closure modification -> project.poms.each { it.whenConfigured(modification) } } def optionalDeps = [] optional = { optionalDeps << it; it } def providedDeps = [] provided = { providedDeps << it; it } def internalDeps = [] internal = { internalDeps << it; it } modifyPom { pom -> optionalDeps.each { dep -> pom.dependencies.find { it.artifactId == dep.name }.optional = true } providedDeps.each { dep -> pom.dependencies.find { it.artifactId == dep.name }.scope = "provided" } internalDeps.each { dep -> pom.dependencies.removeAll { it.artifactId == dep.name } } // no need to publish test dependencies pom.dependencies.removeAll { it.scope == "test" } } deployers*.beforeDeployment { signing.signPom(it) } spock-0.6-groovy-1.8/gradle/wrapper/000077500000000000000000000000001202022523300172325ustar00rootroot00000000000000spock-0.6-groovy-1.8/gradle/wrapper/gradle-wrapper.jar000066400000000000000000001206231202022523300226500ustar00rootroot00000000000000PK Fo%@ META-INF/PK Fo%@²îMETA-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àåâåPK Do%@org/PK Do%@ org/gradle/PK Do%@org/gradle/wrapper/PK Do%@jr×TŒ -org/gradle/wrapper/BootstrapMainStarter.classV[WWþŽ NGƒxI°Qi5¼@š¦¶Qkc¬Æ š(jJL/aÌ0c‡Á˜Þžú'úÚ—¾6/˜UWÓ÷þ‹ü‘¶û HWq1sξ~ßÞgüëïß_x?*ஂ!,ʸ'cIAŸ)XÆŠî+XÅšx¬û±!$ ?6elɈ(èÂlcGFÒ]á¼'ûâñÈϤðXÆOÄò !|)ã+ß¼nê΃'Ýg–¬,g¸’ÐM¾U*¤¹½«¥ ’VF3ö5[ûªPròz‘!š°ì\b¸ú†Ò1¨Ò22*²àÂÿPFNEºŠ#<%.trb•FÅŒ*ÉØ}w/Ò«0P À¢ÚĤ©`*LX ñƒô_ƱŠoPSeNgÜÐÓy:(©8Á3¢RI?]K?›xB|m§*žã[êïE‚’éè^ïÃò’U2²aÓrÂuÚáa'Ïà áZÌðúâNX7kâ¬NÖÓ%!<~£8Sñ¾Ð~`ÿŸÓDcq¬‘×±öv¨·H´ñ„¯Í]nÎZÕ2Ñb™ Ë`m>k"1 •ÞÍÛ\£³ß•)Ù67Ú¾¯ªÁŠÂõ¹³Ôf#ÍSPA‘®Ó uuoDZo€h›ÁìÌq§6—wÛø´øDÿkz¯½IG7§nžXOéTÝiLS9—ÒTEÑVÃhÓ,·!邌ЋÛ(mh™Hoiâ¼\þúMh–‘OAsèhRÄþv¥}L-›Œš¶©c‚õÌmƒïãú© @|<`â^¡g˜vqz3z{'ÎÀ^ТƒLŸ+Ä»ôT+Žédà=²ίÉN¦÷öÄÔ:¶ÎáII@Jy¦Ëð–áKžAž•^Â’Êè IA¥Œ·f½!oP%»®”§ÝÉ2®ÌúB>F’@Ê3IûžG/\œȰ›à:%¢¿aJ>‚%_$íC‚'®V@TŠÕ8".èmD1A`}ØÀ$­<ã6¦0 ‰¢ŒÒ7NÄ©27éŸnUéVtî6I$’|HQè"®Vx‘5°qŽ`j2Ø{†¾2ú7§^-xf¤~ièŒLõK·Õ2‚W˸ö3|!ïo?Iì×^Ÿ#” Ö¿ÄÛg¸þg½ö”D4Luž&*7i=CàÕJ&¸ÓÞ‹n¢y³ä×C6s˜'‚}d÷ ­$¯^’ ·¢Õ nžOÿPK Do%@„¥³š!org/gradle/wrapper/Download.class}U]sU~NšÍ&Û¥´”¦Ä‚@I(%J%EÀ–µ­ -–¢¸MNÃB²7ZüºpFoÆgg.œQ.êE˜Gï¸ðG©ÏÙ~m1cfröœ÷ãyŸ÷cÏþõ÷oxŸHá‚71¢–Qµ\4°cÆqIÇeyq\1 ãª ¼e`S¦ñ¶†à7y â¸f`s®ã8æÕᆲ[P’7u¼«ã=Žé™©K3c…­Ñ˳“WD^`ǨëÔ}Ëñç¬JC¶)Xö‘Ùññ±™[…ü1ŠŽt ÄÎÚŽíŸhKg梣nI 윰9Ù¨.JïšµX¡dׄ[´*s–g«óº0êß¶ëû&\¯œ-{V©"³ËžU«I/{Ñ]v*®Uˆ—Ö÷ûÓw¬{VÖ‘~vv&?¼v²Ýì¸]‘Ên•Jž¬¶c»)é—dÝ·Ë·]gS½á+`Œ­eM)ë:n tn„Í;¾ô«Â$^å9à zÆKKÒˆ,ŒÓ¨ÎHÅvgÍsˊ̨ÛP,킸 _ ¹~ªá×~Á÷¤U%X´è:¤·g[vÑEÅ›úžMÿ¼v7 nÃ+J•»¸QÅãÊØÄAôëxß„…EE”LHµ;ŒŽ%eÜØ»;$%Ka~ä®ZX¥ÐmµÜÑq×DUŽ 5˜ðÀªú&^Gƒe8®ãž‰e¬è¸oâC|$cÅÄ'èèûŸ‰`gË)g§ï°.dÝÂ!¿åѽå±Ùe3œ Û(Wìº_fù‹W–þ´åIÇ_Sw¦3ÏL¬z·d{õ ¤õQÐ|—M ¹lÍJWú¿3›J·¥ #±Ã­Igk^x.ĶII¶Ö†¹…æF 7”Üöên!æ”zÁ„ké…‘L~[G ÷뾬†tÚ³x!1jêD¯õR¬Aù–ƒ2ìnU º-{¶ÏÞèä‘ÏïTaŽZ±âÖ%roU þû°—û}¼'#x‘çý¡ó´qÏw„ë!J²|r.¡}±˜¼Ä5ûpjf¼Œ#| ¤‘¡•r–ã‰ÞcMD¾Et•϶&¢×{m . uqà…~7û!t8IÀÃ4€X‡W»£Böâ‰pœû(%YîOl‰iRóXLŠœ6ÐD,{ }þ)âóŒžxc2k¢=ME›0sZבÎßã9=1”Hi)½‰ó§ã‘p2™è‰n %’‰Ýè¨&¾þÝ¿¢sWW»‘J ¦ô¶žxÝþy¦t»›èIiÏOiM$Ÿ!3ØDï#ôçÚ[ªu¥Nµÿ¹Jòjx@âðUð\+ш ¹Z ¢i÷1Ý~~338ÉÝ«8…×øµ<<†p·ÌMœA ÃÄ;‡œçµrŸa_`”Èçð eßQö²)û…_ØÃA,ƒø’È'Ùé´8Etoö²E§¸?Í( UàÍÖ<ÞlÍãõÖDð3yœa ûñ%rä%ûŸp–þZ¨q‚lT¦çÿPK Do%@'nƒ°ß,org/gradle/wrapper/GradleWrapperMain$1.classRËn1=ÎkÊdPK ¥< U°`è‚UyE!%´R ±r&ÖÔÅcl‡¨›V*ÀG!®“HT°h-ùÚ÷øÜ§ï¯ß§?lã~ŒÖ#܈QÁz7#ÜŠp;ÂCã™ÔÒ¿`¨¶;û µ® †å¾Ôâݤ ûž!­¾É¸ÚçV}Öüt `HÞj-lWqç!í¾±yš[>V"Z^–¦ofêǹ6àRomïP™Ü“³­vç¬U¦dÚ5EÁõ8$³Ç­–øñÐLl&z2$°öŸÏLJü+§^ëL'u>þÀŒ#ÜIp› –p‰aó¼@ î¡Åðàbe0¬„°©â:OwG‡"ó Ï‹Ñã™7öˆ*¿H†2˜ œÅž5„{)\Ïšâ•Í]hàçþß4†ÞRõ;94ñR¥^RW¹RfúAÑfªwK/vx‚:M CD#S¡M]"-¦[J'}1êNÀ¾Ïž›$3ð9’Éœ€ËXA†+h-ŒŸ;¼5 òéÕcÔ¾ýãâåÍ…‹*Vg¬«¸Fg k¸ŽeºÅĪ#¬¥?PK Do%@ß̧T z*org/gradle/wrapper/GradleWrapperMain.classWXÇþW”=V+ *¨Ÿd•$β$GͲO€â„$'du¬àä»]¼·'DšSíôö¥:‰ÓãôHrr\Dl9ÍIœ8½÷êT§÷âäŸÝån9›/ß³3o^›÷þ÷fîþ‡/ß`§T¥`/ÆlÇy1LˆáI žŒ§ˆÙS< ·ˆÙÓx† ?SÁ³ðìžSÃÅ­ nÃse5; ŽuÍ¡¾º2ÛOó1Í’°ØåHš‘#É”ÎÝÅc–ÉM;©gE‚l™¦Ýš$omf"cëéž=pųv2)Ò…-5®MdZÍq#ejä“T—ØgŒi‰›èHÛù„>f'™4ŸdôÇ4+£ÇKŒ±ÌtÔ9Îæ²Çõyp\£éš„iœ£¬N—÷ø#šH%#¥Ú[ÌtZ3†EšZ¦Å„ŽxrÄÐì¬Å›‡Ùƒ³9fSQq6<\êž™‘Ãõ¥´ÒL-õòèWTžÅ&ñë\¢¡Û‘¾ÞŽø„akç Á'O EPŠy«È¤½¾Œnµ›i* d ]¬+q3k%t(+f!µY¨RÑ…nƒ0T¤‘Rq#R2îSñ)|ZÅ0tŸQq?>«â,ˆŠõ^ ôF{XzC%5¬âsx@ÆçU|_”°¶<·Û*T| _–ñ_Å×$¬.S]¢a¤RÖ”Ù,¢7Tf·G³G£™Œžf [*2â€]¸I _—°­ŒÄaVRÆæB'nkl*¾oJØõà” c>ýbóN `ñu†nµ¤4ºœQñ-|[ÆwT|ßSñ}ü€Ýs¢)àáæÚi.öqÒÊø‘Šã'*~*ð3<¨âçx ñF¦ßÚ,a¡ODÆ/Tü¿¢¿fEÏÇ¿Qñ~+ãw*~?Èø£Š?áÏ2þ¢â¯øs÷èfÚ‹…Ø›5ìdZ/l 7þ.ã*þ)\®<Óªøþ-áP‹f¦Öé4ÃJˆÐ1é¡3¦òÜ ±‹†Î°E…lø§µŒÚ¶%³­™¥X4Û}ú¬ž°Uü ‹ÿU™š«õ"šei5²¶TI¤—Þ2*:Ñ.aeiG9œM¦†j|*H¬ÑH³«\•*…©º¢¨/2>]¼#ºío(õᆹZü²rtæ},kGEEÃ%­Ytµjê×s„nxΦ:óºZZ¤±~RºFÇUç¦(,——ÓÅû¦ÂÌÚÜ-tÄîØÜ×µ4o*>vmçõDÖ6Ùzæz ´Ïºq¬¤Aû|ˆ’ßw;ÏôèfèL[øäÉrœÓ=è@¹Ý-ȉ¯¬;:éÞ©r×VYn ,»W®c9vÖdtÛדzD>¬#Z‚§™°=\zïÎÅë(«-â$jY|!'Z&–Ì0{[fí¤·¯`ceïÖ—ö£¡ƒ{y˜¥EÂUs§Ð÷šj,˜ÒþÜÎÃ¥D)Öà³/ø å/sß«Å)<ÍÒ ÛEWMaÍJ —­ ™,]š¸’kKwY"–>–ÒÄÝl‰0î-S"ó,Àmóe –©Î=ãFƒq°nvœVÓ}·nš>O†Xµ’öD¤”‡f×?2‡1ñÊvß | ÌÒZÜ¥¾ú¹öxCQS¬ð*¼¡Ü %v`ú*ôÖªl“Í,NñZª÷ëĨeŽ»è럩¤ÃMp<1ª‹üUë7gµT¦¤“Mƒ¬šm(­1ûÊ$cȲm²ßÅ‘è$n <ØNˆtÚ˜„óêÕÞm$ž“¶é’ø;o;ìUü±yí|†tpµ*×Ç|ë®yÇq¾ 1ý:®ûÖדSJŽ=¤Dø•„þÆIH–Çr¬vˆÑËQuÇ ~kЇ~r ᇠ@æ7‘Ç‚XSÇ9TvåQµ¿rUecÕ9È;òkòPòXxmUPõfÕÛ/aQ‹§°dpyÕòê)ÔNb邃yÔMbÙ$–Oai+s¨/ºÖH£@*9«AcêÐŒµ¸!þBnÄ.ìÆœÆ>Çýv×E àqüVbˆ/铞º;˜K¨cu؞ΚsˆäpuçX›Â5ƒM“Øu…6v÷äpíí¨Äàc*ïÆÞÁŠÆxû&±ÿŠçÌI¼àتe"vzž¬wðÒOÚ ©XÆ”¬£' ü!¢c:]ˈ c”¯Å~Ü Ëñ5SðÕd¬…îÁëò8ÔÙxTÇ®0¼žU0Øé'‰É%Üà¸4”Õ >=…°«#ìÖx[‰é@U³2Ná`Êz—&`Í¢Äâá` }È¡5ØÆ!‡#wá ÉûÍÉ:¦ÏáÎYøHq”þPK Do%@çìXsªÛ"org/gradle/wrapper/IDownload.classEÁ Â0 †ÿÌéæ¼ ^õbñ¼« APô^·26J;êt>›À‡;•É—üùó|Ýè{èz~¢+%5O“é&çWΔ(Ùa…_Ê4[gR„³#!XÝbQ”™Vg=Ë{}1±¨÷„A´üYÍëCÂX›”¥†'R°Êð¢†5Âðc/¹JÙö”‹¸$Œþ£æS‡@pP¹„\ËmKuíØôlïÀPK Do%@‡ôp’ è org/gradle/wrapper/Install.classXg`S×þ®%ë=ËJ QƳ!Œ`€ScƒTЖÊÖ3(‘ôÔ§§éH÷Þ銻ÓAG:BANâ&éLgº÷nÓ½Ût/ú÷4±HÒþð}çÞ{î9ç~gÜ#ú?wÞ àrµ?ˆœjÀãðNËpF†¼ŽY·IÞĘ b>(Ô]BÝ­áù~HǃXˆS2ùˆPÕñ1ù~\Vî•á ø$>¥ãÓ²ü™ >‹ûñ9|^ö¾ ã‹òý’(ú²Ž¯èøª_ÓðußÐðÍ :ð­ .Å·eý;2|WÇ÷4|_ÃtüPÇDÀýA´ãÇ2ü$ˆŸâg:~®á~)³_±¿b~£á·Al{7àw:~/“?Èðq  b;Ðð§ vàÖñ Òü¿5àïø‡ØòOÿ’ï¿Eë4œ bHAÕ¨ê”O¿¦êƒØ'xíT¨€0hšÒ5ÕÄ9°_yÕ(;FP-PMAµP-ÊÊÐÔb…pÿÀÎCã‡ûÇÆG{'ÆG†ïÝ1¾[!4t]ì ±îd,}¤{̱é#[ôYé¬K;ûcÉœ© Ç­c餋+\4dÙGºØ±xÒì>fÇ2Óîì/ìólS,y,v"Û_:¡*ÞâD:›ºžò31çèŽlÖLM&M[au-¡{+y(8pU"p¶) ´<øàV<´¸uûü}Vœ—[8”H›Ã¹Ô¤iǸ)˜XS±äþ˜yaÑïMdVÖÔ,h%“428e›1ÇìOdbÕê›6î‰ÑÁ­ë¼iÂêÞ™Hšä^'Ÿ˜Ì9 +=a'‰^õ 8>efd?«©Âô92ç»ïÿ[™g[ÐIe&22+™UÞÕÅòÞXÖ,‚®‚vC"ã- å­=¬v[).IA¶$Ö=Úo V+²¦3pÜœÊ9÷^ÓN%²Y¹µÂâÖjíâ»:ñÅŠÒzonzÚ´Íø¨‹{Á’uâVŽr›="œìÞiÙ©˜ã¸ þ$½N9™I… *àØk[Sf6Û›K$=I*£°d>ƒì˜%ñ4ap¤ä)îE*N ¦©ÒÎe3^ɲÀ¦ÏJ¥biæ‰A&ËÞCÙ±#”ÜÈH¤™x¼¨¯u“(`e‡c‚bCÜLšdv pȨesSb#MLðo@Oå}l3Í»ª•ñ¾¸«Ï¥é7…‹Ï:ÿz3íØ'J.páåÑnºv@vD¤+ÊwÝ« ¤IË+N ¤s)ÓŽ‘˜ñâbù|©ÅŒ™²2'Ó™œCÓÍXJ¡«lkÅzÙ䑜S^õB']å·ŠC4Ú šeµOÓ“n QÈ¡^2'Ðà˜•³§LÏr£P ºD€ëÕÓ8bਠq˜¸NaÑ®ÑýC‡'ÆFïÙ3Àx(VIЬÇ5µÔÀªÙPËp“¡– µ7QM¥C V´sÝZˆaC]¨Vj•ºˆnëÊÄlÇPs…ÆE u nÒÔjïV—Rl±‚òtDެÑT‹¡.Sk5ÕJóÕ:CµáU ¢~‰@ábܘSŽeŸ »H}¥ì'$2ÂÀˆ8VÄÀëñ¦ZÙÈÑ\ÚI¤ÌRJ(ìÚåfD¤²*FÖ¶d×Fâ–™¤-'2e¥X"1g¨ÖŒGl‹«e#„»‹ð–ÕŒL^Ç=Cu¨N¹òZOÇ3 ¼\` N&Ò…ZÎP>_¨çAK$§Ž¦,f­oóƆêòðì6Ô#ÔåšZo¨+ÔV1Ó¡©ÅªÉ”ËZdÚ²{βÚ%Œvõö µQmu›e¸’Þ¨Qâ µE­$ö-Ù–´\¾§ÈV]ª µUØ.zðj¥ÐÖgå’q×Ù‡¼Ó–½I“¯½‘G3Âú–cNœˆ$¦#'¬\ä; ‰‰yœ£f¤àö‰AzN³²]iV9C]¥®ÖÔ6CmW×j‡b¾iǼ‚h¨>Õo¨µ“‰\³Rqò[Ô.Mí6Ô dϵê‘E¸ç•+C ËFµ‡/ü¹©¬Å0)¤^å–8cØÀI¼ÃP#j‰¦öjŸÕÔ˜¡ÆÕcÿüCÑ9®*`gágÅŠäv|WýOÌ냴²Ô£5J>Øç0a.{X½µ®h÷—†ô¡c¥ßb’”Ž5d3í>·¯.ê¨ä©©Cc©4LŸ'Ý8빬fGn­„ ºSk®¹ÁH<Ëî±ls i¦X$è䯴yÜ)LÏ- ¤®©ëù‚“»»òvUíäù"!\v÷¼F¯~*i fKjåõ%$ÈÔz¨WÐXZK ·Ù )!Ù×íÇ%xZÔ#Œ&¡0ÅY4„¤½#’†Ïý-|Ùññ«“÷z$9¦8{*ÏÔó{AÛ,TÛ…gP×¶ò |mgào ûÏ þ6WnZxàØ?.CÖ¢ ­X‚u´  w6x’Áã— ”K‰ u.%Öù\JìñsßF–{bM/5WS[{(Òä/ýý% ®´NWÛ2³¤­ rÜi‘zÌ•|Ü“¬þMdøíl;úŽÎö<z¤ëfÐÌoMá@Á›Þ/La¸žl=šÇÖ¦-Æ ÍaATè¦9,ŒÎb‘Ћó…–pÈcé,š{ô°žÇ²§°¼ÀZÁMŠ “!O´OÃßÖïÀ…>„u‘°ò@AÿÚŠC«xH–/ò$ËÁp`»¼M=zkDX55t‰Lôêsš,¬v•Ì 2‡K£¡5õw¡%êk‹úe}ñØí¸lkïq•´‡ð£X*ÿcƒõX+9n¢Ã6Ó±Wâ-x6zØÎnÅ ®Æ-؆{°÷bî#×_ч³èWÔ ²{¿Öuâ4‚<Nà&ÝSt')ÏB=‘^çRO"ås©'“ò»ÔSHÕC~BÜH)JûÃú:ü>&ÉÓ\Éå ¨“¾Û ~õMr3(p?ƒÝÍðß&®mqÖ¼G Ï¡=¸ Q_¨“…ºÆ¢õytÍâ=þ°?Ë{êÃõy¬ŸÁê O\AÐ;*±?‰sØÃƨ°ošÅæY\Ù˜ÃèéÑü­Ñý^,k¡«ü®WÂúXW8yöÇâÖmÃ'±ÌÓz ÉFìî¼·*`úÎÕͽP?¿·ñâÍx+ÛÂíî÷ã¹ö±XÎq˜p¨}ÌèQrŒÆ :t?w€&JàGãùx ހÔaRZ ï$üï#}Šè4³ûN:õn:õ[Ìù1ÃÅÍ4ò|ž‰gò>ÏÆs¨ñ9X…çò¼NmÇó(ÛO×áx!]úNò¾/æÚi—z‰8÷—2þ~×á,¬ø^JJnø9¼Ì ‘:ùeU¨q9skOhàvì<…]yìj æqmÝ[Qï¿Õwk)ÐC®Ž=Í cau•«M±¶¬6¯p«nüÐ,èy­” ¸¹ÝMä.~¹Ç·mUÇÝ·à’67¶:V­gp1ƒ7ù›ý3¨÷ÝúLŸ:yöûd]V6bµä£_#hcv)ËX s¤—ìà|=ã»Xp[ÈõjÂí§IkðÜÌË,Ð3x­kòæ\›ñ:.%? ÷æŸukCÑöYìñâjx¸óŒ( #±WáCØçÅúèÍl ¢2a&4ç1Îýr›”Ë<&æ°Ÿ~ ZÅ3‹GÍ"šÇÁ“gß%â•ß”.FAzý¦ç×ÐçôöÕôê5ôâ41Nå4/*×ÞF“×0.߈7¹x[¥+Zx³{E¡nq#b#õ-ŒU5˜ôÐÛ T±lç& x×DZËb?>¨·wæñèè&ÿkÑÔÑék¦Õ9yö7ôÓc™_‡Ï}g8¾‹‰ëJš¡ò5T[~[J&¶0¬ßåšØ‚wãVJ àb¼雷MLÅ÷ôj½*|ÛPK Do%@Ý1¡ &org/gradle/wrapper/PathAssembler.class•UiWg~Æ1Š Õ6â²Vì¦Q)$l6,M€¥â$y £ÉLœ™(jÕîµýíé ç´‰§žÖïýQ=½ïÌd!„.æ]ï½Ïs·wþüë·?\Àwa¦Øq]¢ù) =˜áÜóüpo%tãC¾M{‘‘°„e>¬Hø‹Xõↈ›Öð‰„ƒ¸ÅÏ×%܆Âϲ|Èy‘ç3óbË‚„M¨Üê-/îxqWDQÀÑéôx25¹¾œ™L¯Ï,ÌM®g–Ò³óÓ|©;Ê}%VT´B,cªVˆ ØŸÐ5ÓR4kE)V˜€þÅôÂõÉÄRC«¿`(ù"[6™1£—¸„cFÕcSj‘‘‰Þ+ª¦Z×tFVxzžÄ¤TÍWJYf,)Ù"ãøzN)®(†Ê÷î¡ÇÚTMÃ)Ý(ĨØC)—™[T¬ÍqÓd%’4è``'4G“‡ÚD`·‹{hÌŠ-§gã#íîxóªiM(&s—œ…‘/—bÃÿº¾{uC-Óê‘Zv4ùÊQÜW`V’†ÃŽè;sâÑ.+–+·É Ç©Š¥c+°­ØœsoÚŸ·u3L’ðozÉϳk¨Ù ×ñ/§SþógÍóQMÓ Ù;,g‰x(ãs‡>•ñOE<“ñwñs|!ãK<%µöþ”ñ¾¦l»GUW¡^‹æUCÄ72¾Åsj1žÄË~ʶ_5ýí®¦? üÿÖ4¤ÉOµ¼€ÈÞÙß&Þ–î 8èX¦§ÛÚ±ƒý•z%´”.¤p{1§—Êvý·ÝŠ„|±U>±©v¯Â´ë Õì”]Læêýåvši?a7v¤¶ƒÞ Ý )^¢»¹ÞLµ×BçÆìä'Ũ§`è•2¿Ÿí¨'·¾D—ºÚ}\ŠŠiÍjy¶µ°±‡y’ï3+Y³îEJ)šmÂuÒm¾?4-Vrž˜EC§ê² 8÷Ÿ )ŽSô§;DÉnÇiœ€³´ëÂíϵìOÐGï­E:£g…Æí.Ò,ÐܬAøÙ Ó(Ñ øá!€­dGQÄhæÞt L‘$—•¸`èWt5­ô--é#"ÜÒGÚµÄWœ'q£®Í2zI¼D÷j0Tƒç%zVkè W!ú¼4#5ôÑ\…Tþíb¯Í3`# ¤9{ƽ‹V]öêm¼C,¼û?Ñå=ÑÃ{ ¿×@¿Ô†ÞÅŸiý{J×åÈòœoÿ ôðùH?âØK\õù<¿ãÐjw(ó‡k|ñTq¤Éãe ”¡^Šéùu”<R“×hƒ×¨ÍJ–$®Ø¼¨¤®âšÍk¬ÁË =× Uqt.ÌãpìÚÉŸÐÞŸôÜ®âx;þeãT9WÈâUøÈV¨?äâ÷`ïÛø2ÕÍ8&l|ú͹øÏIÇ,ò UñÚðA×vÈwÂÞ ðdùN¾Àë5¼±Íƒä&Íç§D…xæNÕ36øªi‚ª3I¨“©)â0ÓR©ÉÓ$ÝŸ±+uÊÖŸþPK Do%@!¦¬æ 0org/gradle/wrapper/SystemPropertiesHandler.classVësUÿm›dÓíò*”’ŠPŠ@úŒ€lJUJ+•¾$P,‚ºMo“…d7l6´ŸøFý ŽÃ×~r¦c vF¾ûG©¿» m^ ÍôÜ{Ïëžó;çžÙ¿ÿùó/‡ñ³†vŒ¨xCCF4œÆ¨Š75ø%óŒcò0.w*&UL©xKÃ&ŒqV®1IÎIr^ƒŽé .hx3Òìb#ÞÁ¥F\Æ»’¼'/;/¥ïk00+I\ÄTžoDI¦Š+ ¦eºƒ êÃÓ |CöœP°eÌ´ÄD.=+œsÆlŠœ¦1;n¤¦ Ç”ç"Óç&ͬ‚î1ÛIDŽ1—‘ÇÈd„‰-e]‘žrl\SdOÅNTÁö„p+¥ ö†Ç®׈iGFÌ”ˆvŽ9×LEÆ í‚¦sa¤„ÊtG­LÎ-ˆ¨¦0°æuùèäðb\d\Ó¶(«¿*–d.ž4eX‰ÍL+A‘š6ÜxR8ëν›‘‹¼ßÉ '‘K Ë-÷29{EÄ]ÊëÌì(q0ê Çpmi»9³ž®ŒšŒòŒ45–˜°,B%Z¦°%â e&Ãå­V­L¦ ¢¨4/+èRæqQûʯ¨«š3H‡ 13anΡá§ó™}j1;çÄE®ÝOh©^iªc?ý¶{NÙ$ïRqUG lšµðRÐò„V’-62:®IßÛkô”‚ÖÀÏæ,×L‹aKeV'sfjN6ÙþaDZ¶…¤°ÚR¶1GYÛFuÛæË ²’¸:r¸.ZP°5»Ã¥Þpog‡ŠEKø@Ç |¨â#㦊Ot| fñ>×q_¨øRÇ-Éù _«øFÇ·øNÇ÷øAÅm?â'ÏþHeÿ+ÐK±äp1‹Îár‘Å©ì 9pdò vmˆJ_³ÔðÇSvV:“áXÔí W7KG«ˆt´B¿øRŸ¦tí‹-®V¤FgJ8ç’Ž½ “ËÞ jÜNg<|ž’RÍÇà‹ WBZªF…›Êrng}™zÉljªæ2¾¤‘‹tá³¼¥Žõ¡w´4ú¡¤áÄĵœ°â¢F£´ —ñÇØ7oÊ:ûŽãlÖ¬ÂÖJqI +á&½†%MÈüþOý×ó(ÎÀõlDÇk˜?“Cìã¯ò¯ŠœO¤xŠpU¸ú;W¡ü<æ"Õ £ƒk:ÑE-+÷áC¼?ÖP7³Šú±Î<|¿Àßµ²?ñ5¨3ôœèîÉ£ÿÚ2ô~ŸÜ„|–Ñ6±}f ›¨½¹iK[éb[M=«Øþ¨iÇ4Otç±ó!ZôûB¾‡Ø¥à.NÉ]ˆ,OÈŸGkÏõBèZA=9„^&Ћ½5„cèG#%„i4“îcŠíØB̶1é-Ú Ä!‚Ð…nZuÑ&B«DyºÀ¬Ëq7p”î%ÜFîàeÜ£Ö µîSK‚:ùaÔL=¼-ŠÝ´pw­Œå0?½nè#ô ¯>zêc ’8C_Ç;AÇq¼Â5ˆßè7Ê"…ð+p‚ŹÌï­A¼J¯ XÐz»“^‘‡¸;åí†ÿPK Do%@ø|ž!J (org/gradle/wrapper/WrapperExecutor.class•Xù{×=cd$˃ òB¼AY¶HBBÂ’ÄÅ©·X6®¡-Kƒ-"k”ш%M›Òtß—¤é¾Ð6]  6‰›Ð¦mhé’îûúOôÇ~=w4„ äãó›wß»ïÞs×÷Äåÿ¾ð€›ño?ñãÑ ¢ ûñDÕ8„‚wQS5œ–á2<)\ï’ÝwËðY{¯ïóãý|Àñ!|8ˆuøˆì4ˆv|LÎ|\fŸÙ'xJt<íǧ„çiÙyFfŸöã3AlÄ©>+ßÏðù¾ÀøR_à+²|Ư¶¯É÷ë2œ©Å³ø†Hù¦ß âV|[”œ â¾ãÇwx.ˆ=çX `)€ <Ä Xâ{x1€—ø3 š†â“C}S“Cc£‡§&†OŒNLÎ( ÕŽi±´–™‹Å-3•™Û­`M¿‘ÉYZÆ: ¥óº‚–}½ñA„õ‡ÆÇ'Ç&ËwJ÷Nî¯|¬l'˜5¬nZ)=§ ©€/o¥Ò±qwÕd*G¼³Ü12 ê |ÝŠMM q¿®(e_*­»)#&´Xy\334x,oeó–«ÊvEo6«g’Ú¬ÍXÄ0©û¨ž°R&GÃ<©àÞÎR•Oo6̹؜©%Óz츩qÇŒM¾ƒ'ôDžÂ¨Â×o$‰qíp*£æfusRŽK|Œ„–> ™)¡EñƒFÁDç/3yõžT&eÝ¥`oE¬åN½Š(ÖèÙ<‘гâxnͧ¨Í×ghSÖÔ³š©x¢7e¦Üй­<„«sFÞLˆ½®¾œ9S×’¶cÊL3ÑJè:š¥'§5Æ©†þYÐ,K7]lÃ÷­,SSM²(¬.mhÉqO v\—óÄMT†5¤k ®&žÊ0» Ë»ýø>ƒ<§[%Éë×mÑÒC‡®,ÈJž’M§+îõ†EñZvD@š)F >ŸfÎÑ ú :"U© íZ 4ÌV¯ b¦W„€Øö ´¹–þpÉpmí¼ܶJxU§ÀOŽj"¥úX¡W52¿ ÓIårä+Ê Æíd*FCYböˆ|›þ S¯7t–ñÈn‡ì)v!3øUWÊÙ{Y†ƒ*îÅTŒbLÅ8îSñCüHE GUÆý*†1ÂV¨DVAqu"Ÿ±R ºg3ÚoäÓÉpư’ßa_¸ˆ/|Ä4Â[r=¬Æ¢¬±Yi5~üXÅ+¸$ ¢")X~ŠË*~†Ÿ«ø…Ì~‰û™ÜÉ’ÂN«8“+NsJ[d¼ªBþõå‘í˧ÒIÉ'ÞLO0}Tü ¿f Š•Wx!ìJ7Ýá]> ›9Ûâ&ïjZc>I‰`_ÏC©¬ŠßàòŠ'KûoÔ-¹pÂÈXÌÙ\8é¶“°ž¡@=·+Üá`눆;Ê1•¯9€:ÂZ&YºSÅMS÷jÞã©t:<«‡M}Á8ƵœadzÂãi]Ëéá<ÿ$Va©Zv¿ž-‰Ïoýø8ì÷*¿¯÷&«§Iþ âø“Vñ¼¬ ÝË;jXûŒ|&éM¡é 9CÖޤARÒK?A{Td$¼%ë#ð²¥qÍšgv0 q—^àpIÙõã¯*þ†¿ûñÿÄ¿ôŽa»Øé!k>ü€~²€ —ÕâÍ$}R1¿W°2¿[½ù?ÉPŸðXZïöî1ÏêMW¿ðWú{ìªNWÛ^ÈÙäÁ’r*°’£p-)¸³BÃó6èBýUî‘ g=+“ó¦qܽÄkØgã‰y]ʦ¡³¢¼5ÒŠ™Š«ÐÜÜK¹øjjt¥Ä þNðͨ¶ º’û•ú·xD³Ÿ º¯«Á;m€ –±â³=¯ÉUWÜò •Þ7 ¶{¥öÏkf\0¯gz ¬’ẲT°/Wé«|ŽuV¼ù…£¾Â—H’õ-W¿ty{%ÈlÙ¯&G:K_J×Ì×°rE¬;®óF§9Ë΂Íß/e¾â:ƒ¿×jÐŒ~ $U…VÒû<ônÒ¯÷Ð{Iï÷Ð{Hyè»’ë“ó\”ö—7©ýåeÊo-uN Γ¤F±š§€–e(3˨š‰„V-Á·Œê™%¬îZ‚ÿ¬-wŠãjž:p€cSá¦mÙ2é¬0¼Ñ•=ÈŸkµNdG®!²Ë#rWf‘G#òUø)Š,!‰žGM¤ë<‚‘îó¨íZ„ú¢]Ñ Xá~Ýy¬=ƒ»h̺™PÈ÷"êgVuÅ/ ¡Ù·„Æ‹… ç(¸…6Epƒé¨{àCŒÖlGS×sµ;°·‘÷rßÎ_¨;¹]ŒÆþ‹b=áM¨Â)ÌÛåYôFPÞ²Ž7¡/$|í˸u†Þ1ÒE¼·ñïö3ŽÊ·ûâ92×Ðádld\Ý ´Ð™âèB¬#Œ4òÛF¥0l»ºÝ-©v;ÿ¤JðÒ”²k|®8eãWBYM®-¯ÖŒ'ÖÕŽ d›žuk”‡/¡u;gBwøV” \£ â®Hh7C í±Ç½öx—ä»wùº»š™í÷œs4Ù‚M*È1Íòèåo?ñR¥U÷ 9 U—ƒåT]žaZÅs§O|®ý~>Óû“Ï5J:±ìÚF¢—¤Õ0uÎFËKïQºó1¬ÁãòŸk·7ºPñ5ôÚ[9«â¿‡]eã4GÀµÙ}ª·ÚéS3¾¢³ú.–ÅàIO‰·¹zÚ= ]"üoÿPK Do%@]”wfPN#gradle-wrapper-classpath.propertiesSÎÍO)ÍIUHIMËÌË,ÉÌÏãRÉ(UðJÌS00U04¶2µ°2°Pp÷ Q0204â*(ÊÏJM.)¶M/JLÉIÕMÎÉä**Í+ÉÌMµåPK =o%@org/gradle/cli/PK =o%@H‡k˜“‚3org/gradle/cli/AbstractCommandLineConverter$1.class•RÛJÃ@=kjScµõVïÚjÁVÑè³"Hµ Ô (·éR#é®l¢à_éƒ ~€%Ά ^@I 3;³œsfgæíýùÀ–ÐYiÌÙ˜w`¿`cÑF‘!]úay“a½¡tÇíhÞ„ë¾»× #ͽ¨¦º].Û _Šš’·BGBopÇ—~´Ë°YI„¬6R5Õ 9ss|Óm }Î[eFÊãA“k߼dʔȆ졔B׆‚2náò]øÎwý©‘ˆjÃP¥=-xDÐr¥úütÊu÷Ë9S7ÚußÈ•þ¤¿â·œºs ½@…¾ì‰èRµm”²È` K Åÿ4i¤‰ÚÃ7ÂnÀeÇ=i] /bXùO¥N|Jß1¬%c°*Õ&Š´˜i« –Ï›§Ñ¾öÑï`Ð ›NuŠãÌêÚ#Øêú(²0DÖ q “ÍÆg9Œ’û–‡Y zœûÄhî2/°.žºÿÁXøÂ˜ùŘé1Z˜Œ«Â4ùfÈŽÄŠŒ^PK =o%@L qr{‘ 1org/gradle/cli/AbstractCommandLineConverter.class•UkSÓ@=Û†FBTTD)>xJ›¶T| Å ŠVDa˜ñckSRf|ŒŸ¢3ZGñø£ïnb-´B Cöfs÷œsOîn~ýþþÀ– ˜¸¢ãªnt£7{0ƒ¢’[˜•Ñmy¹#/s:îê(ë¸ÇpxË> ¶ÔÅ;†l¥.ªÅª°7j¼èÔÜb¹¾¹i{×ãË­©3 ©’ë¹Á,C2“]cÐÊõ ÎpT¦.mo®s±j¯×hæx¥îص5[¸ò>šÔ‚—®ÏPØÍ7·î‚(ZxËuï5ÄÙ¿ëÝÖ_¼K*­®ÎÌڠσÿÈÏÄ6CÖ¯;!YÅ€h¶¨’ }ÃáÛaÙW ewb-µÌ­Âõªªpcþ­Ã··îù:æºWܪgÛ‚œ,ÄÆÉ’ ×ÚlRŠ6Z$v®½­¨öu qЕŽéŽ®·wÔ’ èEð@6k‡§IEp1¶1”jêñø›EÏlÏ!gû2¹»2aò³ÒêtûóÙö©=š¡­Å•ú¶pø‚+7Éð^›bRò˜èÅ1êl¦±)0˜‹žÇE¹fû>÷%Ì‚‰#8ªã¾‰X4ñtTL<Æ’‰A\01‰¢Œž0äÀÇлۆі´Ó´d͉êö&÷‚æÆPïû ‡“<&bÔpŽàv@ïd,³ÿ™Kï±›N—nUíÐñý&¥fh¿,ê=uÂ0ÜøÏ‘c‡>ˆ±CcíBm˜>N&µÒaúOÈæ¡Ï[ŠbjIº§»§Ð(ŽY_Á¬H<§ ùÚ'šLâ]åG”¬¡~P€´'ÑOã©3§!;wé~™ÖÊÕ)+×s]8£0ûìSFR,kAO5ÑiMR¡¿§1Iã€õÚ7t1<¶ò "ËçÐ8ô±IxD%ž'â!V¤Cáâ&éÎâ”qžž&}(m ¢³†)k„béÝ(Æ(J`\I»I[¦Q®3¬œÕ@wÆ?-)UÐxKáFSƒAè; 7"æÝ|Å—ø>ШјnZ±d¤iE~èE–-ª4§tXáꦎtä…Œ,ÊIPv¯r%©´…Þ¥›®¤#WÂü<åïÖ[Ð4y>ÑLx‘Âh —Ôx×U½LyBPK =o%@—›ÈËFK1org/gradle/cli/CommandLineArgumentException.class•‘ÍJ1…Oú3£µ¶ZmÅ‚bwÚªƒëJADA\ØÒ}: ÓÈL"™õµ\\ø>”˜¤¥ŠÁ,nrOîýî yÿx}p† Ø2aÛEÝEƒÀ9ç‚§=‚ú¡O©QzýTqv†…K9fUŸ v›Å#¦ti¥æË€FCª¸Éçb!ð„àÄ—*ôBEÇó‚ˆ{—2Ž©È… ³˜‰ôê9`)—¢KàÆ,Ihh©¿\´—xû¦ &J>™ùÖp1 Y¢Iõ¥¥¾ÌTÀ®¹ñÛúËØ©”Q„cB… óW4¿æße"å1[\¢…¼þ³r f‚Ž®Îz:ÏéÝiw¦ /ö~EÇ’Uwue«úÔ˜Ui}ÍR”±®†U™³nôŒ¼ÞÝvçxŠÜOØžnÚ·°ƒYÙæÎaæTņµ¸i»kŸPK =o%@$¸Rü<Y)org/gradle/cli/CommandLineConverter.class’]KÃ0†Of·ºù5¿ñZÄVÑêëÈP -Þgm m*Y:üm^øüQb–B).ƒö¦Éyó¾O'?¿_ßp Ç6ØpˆÀŽs>'B"pœ`ŠçØK1§Þ³$OR⻵âËdJbé#è=|ÆäC²œÏl8BÐ åX‚ ¸2Å kµP Æ©?òÝ(RY#v™j¼ÈMc˜b•¼;'Èõ¨ÀIJ¼8eÞ+3’Œó,Ã< _Ñôy£F<58Ù°Á‹QUk]5ËwFõΖŒ5‹Î¾û¦¦>ŒËà‘qêa^ˆ˜<²TåŸÔâÆå"âzáBpºš\EÐÿ@p¹Úx/h‘.«—×A€ ‹¯m!XKíÚjg©zlµjÁºVº¥§• ƒ²©•-ƒ²­”èëuYÙ…=ýßÿPK =o%@6êg WF &org/gradle/cli/CommandLineOption.classTkSU~6 Ù\–Rj+–[5„BhÕR ‚@éÅrÓDÖªK²†ÅM6³Ùxù)þí©Ž´ƒqú­3þ ˆúœÍ’ëfäCÞ=ç=ÏyÞ罜üõϸ†rÃX—q'ÖÃHân÷p_¬>Œâ6¢ØÄ–0Û2v¢øËÈŠãœ0Ÿ³+c/‚8Ö…ù4„ýŠå#ŸÉx,A6+¶n–«6ŽÔoÔLÍÖLV³$„³z±¬Ú5K“0Ñ~ºXßj¹˜ÉÚ–^..,ñ†¢ZÅZI+Û¹ï+¼4Ø‚Z3Ôj•¡NßbZÜŒ´jÞÒ1Ýô"ÕÚAÞ,•Ôrˆ‚V±´¼*ð{ªU&DBpQ/ëö’„áT Á}[³ÔC[˜Ú•X3 šHV/k[µÒfåÄ™iæUcWµt±wAÓäÓ'Ò8¤¶iQWÀ>ÔY¿ñ Ó*fŠ–Z0´LÞÐ3ku­"Ò¶CÓ‘}C—„d{pÏà•GÚOŸ+ê)jööiëSS]Í¿Òéë6z¨VWÜ®K˜ä­3”Ai¹Äøý“miîÐiìöˆ—ÔJ5g¶"o¤ºgR 7(b ~»uøb׿H±bæ·­šý©©‡.6Ž6k†­W ­9QaÎ;aºg6’5kV^»£‹v'»¤ÎŠôLàs¶©Ù{jõ=Qp¯ÉøBÁ—Qð:Fd}€¼Œ‚ Ë ¾£Ä;«$ãPŽ#¦ÛdÝЫ¤è‚qa.c”o©óêjM7 š¥àk|I£šiŽÎð‚ïñ¬‚nJý¿F´ Û>8Òò¶SÙÝSYÎÁ®©³€ÜþÎ:›Ñ=äBºûY¶¹my¦‰n/Ç€½ÞÒ¾cÔ@Ùù´^]/÷·=jT ¢§©n¬˜Š Z©hb¶f<dzGA&d›u›äß?Ї„è18jÜùp‰?¶¹±ƒ?¶ÉY¹ßqç«3Iî¯p÷ üð»œ~)ý¾ýçð#þ }ÇNŸ@–°yõ! ?àa /ÙJÿŽÀÌ ¢>ì=ù÷ï_IáÇ›´¤!é0(1I)s”²Doñ$Í“9D‘¢?qc˜¢Ï'$`Wgu3”9ëÊ­{2俏º†ën Â/0}BÒS „礴NÒ稓¼Mß;x—VÌÓ#0áô9D˜xºIqÔ¥ Si“,ì’ñ¿Æ“Dñ"™!ɬ'ÉðæaWêÁóÀ“gÅ;¹XWrÛLn§Grãnr«ž#둜爬9¨ÛÿPK =o%@2_e¦è(org/gradle/cli/CommandLineParser$1.class…ŒA Â0EÿhµZ v庈kCÏPEÁÄv¨-iIõp.<€‡S\ºp>ó?fÞëýxȇCD„èln¶àm­˜°ÈMÛJ]îkÍ'iÛu#ï’0ßèBWëêÀÝÕ”!f„¥±•¨¬,‹BÕâçy•@ˆwZ³Í•tŽ!é‘BI]‰ã¥á¢#¤ÿHIê9|gèߌ|{Ÿúü õ-™|PK =o%@©Ö¡È<Ê ;org/gradle/cli/CommandLineParser$AfterFirstSubCommand.classÅVëNQþζ°°-P* Þ+¡Øäf)()S%ÁKYëBÙ%ÛE|À÷ÀDƒJbügâ£øÆ9»Š¥l%$þ93gfÎwffgfÏÏß_¿Hà™„fÈ´Ä%´@–H6àà ˆ1Ì5£DŒ‰x(b\‚“$<1%"ÅPo½ÖŠ¡8CwÚ0órÞT6 ªœ+hòŒ±½­èiMWW³¨šI²×tÍšd˜ëu7ÿÛÂo”Ù%ë ÞcCehá‚åÝíuÕ|®¬HL9¥°ª˜ß—„^î.C[ê•¥š³šY´²»ë%Hÿ‚®«æLA)U²qõ1tÅéËXž‘šÊHš =k)¦•Ù±4C1ÃÐêðÎU¤´ëeozSy£ÈEÏËYËÔô|²Rv÷¼›|ð(fž'®¾œaÛ“Se¡eJ²ó¾½c“ñ˜ [—òáÝÃKØÅ!¼ó%Á—†P-礬±kæÔYWLG…M?OA\ñ#€VOü˜Åœˆy?ð”¡Ë- c®Ž¼Ð·tcO?£:«©ü¸›Ü±%ª]× «ÀwTSôÕXSNÍP7•o¹[Ë|É0 ]¨­j‰É¹1µ§˜ê阪)þ½O¨ÜÝ«èÜ"pŒ¨Î”\N-C£qªÒÁ#ìt殥ä%e‡OSêà¼j1ô”‰Ìú¦š³ŽÎ–‹D¬Ð¨:Ú»³ÆË%´cùœ©µykuµ¢ýºÀà9¿ÂÏ3/M½ÿ•ºØ¿ ¢‹þò-ô`hÄy ðùFóºvó´÷õG¢Ÿ D¢±x>Ð^@;­Í\džQÇFàc£è YéÈWq°9šL$c¸E·9¨ïÑ/ÑTä#„ÏðÆ¾ NÀwÔ/÷ý@ðâZ”4 v€ÆýCHkÜî¾µhŒDþ¾#eÓþ±+AÈÆÑÊ&ÐÎ&bS¶;ç¢cwR¸‹nrƒs÷ˆ(è8B¸O€£ô–\ÌPhü¤hÇÌNb®ç‡ÙP¸x ."LpÌæ"vÔœ‹"fgµÏÆèÇ5¢Ó”fzqu’ä6Ñ;^ =Dh  Œ€?µH’ÞGtü‘–À´WÀ"Ñ´WúPK =o%@¬€Ú„£)3org/gradle/cli/CommandLineParser$AfterOptions.class­•OÓ@Ç¿×utƒ Äß ‚@ ”¡¢ˆ1P$hD§òß±ÕYí®¦+Š/Á÷â’¨$šø|QÆçº:*)Ó¤÷<Ï=÷yžçî¹öç¯o?± AŸ†4&ºIÒULjHbZƒ‰E³ ™Š[¯sQ-ÙÂb.¹^ͬy¼êXfű͇ÜkXÕ¥}Ÿ†Ô-[Øþm†Ññx÷‰2CrÉ­<' ëÛõ-Ë{Ì·²ô—Ü wÊܳ¥“þK»Á½ó·¼o|ÛR]Âò–ÞhX¤š#GbIx#Ñõ”u¾ÎßoY>÷ü¦‘a`¼ôŠ¿å¦ÃEÍÜð=[Ô&6Ü«ÉäÚ&z\A¨¸ÂÐ×”›QiÒ§6;;ÄŠ/¢-÷ß óϸbݪÉü•Áb§ÚâãE#©¸Ê†Õ#s<¹´‚²3#_E†‘£,aÐ6Üm¯bݳek ¶ùLË"³È +_ײ膦bŽa>–þD¼î;Ñáô†›’1®«¸‘Åò–ÉGÆOéÆØî —#¦Zœ.Û&¥Œ]VŽÑI:“ }äušÆ3Iù4pÆȧéh` ÚoPK =o%@“¤ùé| <org/gradle/cli/CommandLineParser$BeforeFirstSubCommand.classÅVërÓFþÖV²AVÀqqJÚœàøÇBSJ®‰i iz“á l‰‘åÂ+ôút¦@3ÐþëLÿô=úLÏJÆq°9 3ý³—³ßžóí§³Gû÷«ß_ÈᾌãX8BÍ¢Œ(8ò2$\”±„OB¸„O9.‹É2ÇŠ€]‘!ã*ǵ!\ç¸!ã&>“1Œ5Ž‚ŒÖ9Š·ŒF|Ža²`ÙÕlÕV·jzV«ÙU«^WÍ­‚aê·U»¡ÛyB_4LùÄp}Æþ&Â5ouàò‰ iÕÚÒŽ Ãz³^Ñí;j¥F–HÁÒÔÚ†jbÞ2J‚.CtE¿oÙú5Ãn8¥f¥å“A¹išº½ZS ` ¾$ã=ÑICÚ.´‡8Ýga¶Ì’£ÚNñ‘cX&Ç #ÞØ‹E‹ùÚœ)dž̡d›ï*ØÀ—_)(c“!æ'¡‚{øšaÑ7Ò]ó¡i=6{$ã‰ý–L`R°úŽ!µ€e»Ú¬ë¦sõ‰¦·>ýDËe¬•™áb^ÎŦ§Ó³ áÝü,VèšÃñ½Qc¸à{¤µ}4Ú{Aø¥úpþíêA?„¼ËU[ßKh¿…ùÃ_pºWþéz`âx †µ¾ŠP¿—JV5Mo4â st¹ÎöqŸ^¬¦cÔ²·ÔG¢xî1P!«êÙNš^¦¼ÞÛiÚe°(LõÃ`“ƒô íQ÷§^ª¼ƒÒÓY£ûÕ4ü&ªà”šu•dYìÁóÞÁJµ«u´Ç^ïß·(Ã>¿ÿÀÿ%nú0^£U”Þa,åFADµ§¿×4»Aó õJ2õÉTzÁ_hÀ‡Ôklì4B,ŽÈ6Jk„Ç8ù†;¢jK6†Ó8Óòú†0@½¾©œJ³m ¬'EàÓÏÁøCKÒ˜ôržùÈψì@.§hJ^yºƒárä¨ôÇÊÁLéÂÛùc‘²Ø‘“^#ß{Ú¦{œèÎÕÆY“,…4K#Ïf齘séŸóˆµéë˜Æ Ñ£aI¤éèã$O³Â Ér­ÃiE¢ž»j±]µ…6á†IzvŽyRŸ¹£³®^bt»ßã¼ëãNQ¿BÚ§çðI²Ä©Ÿ’Äsy )zg©Gxâ¹¼ ñ^Â-ÂE©ÿ\ àê¿•äÿPK =o%@·Ø(kPForg/gradle/cli/CommandLineParser$CaseInsensitiveStringComparator.class¥S]oA=³|l‹‹EÚâg+Z¾ì–ê‹•Ä„”¨ MßÖi–Ýfwiü+þ^|©‰ÆgŠQã/0ÞY6˜ &†0÷ÎsÏ{îì—_?¨áq :¤°¢–vÔRÔQR᲎ªŽ‡:v’ éÈ É+–Žâ-w Ö:Ò/Ç£žðyϦH¶ãö¹}Ä=©öQ0¼‘>Ã÷EÛñ…ãË@žŠnàIÇj¹£îñÀõŒ¶ã¯esß”ð¼ãz–iy|` ³oK“°#î TÕ×Üó…WXBYgÐûᎮ±SìóSnÚܱÌ)²>)µ)Ç= ¤ëÔT?s€Ùñ>u6Ã!k_`Õ;ý >QìÚÛ½óÄÑ™:©é0Ò-m¾VW³(ü aµ+-‡c¥DãoWÒ6ÿÈטï¾IT©®;öúâ…TÃÍÍ•ÛUIR¸d`5û %3© ¬cCÇ#†§ÿ;æsìÓ†6uݽ\-†õèѺmËq=¡ê3l.x@j «34C~=I¢ÓçFYôÆ¡)hgÐÎ$KÃG¢üÚ{r4¤iMª ûŠËäSÖ…z&$a”<$tœl¶R=C¬¹õ‰­‰òã“SV!Ø7$Ùw¤ØìgÈZžfF¬ÊÛD.¬”ÅUò4ºƒk¸ŽXæÕ¼Õ<@Œ~@º\ùŒD•þgHN^ûóç»/<¨ß73»Ùd7Ý„G_Î|çœïv¾ûî;ÿ¹ø&€.ü-Œ8VM˽aô %a2Œ >1yIóò^,^lÆw$dB8.a*Œp" 'º/„ÏÖàsø<#}!ŒûñEÞ> áKalÁWBx0Œ]x(Œ‡ñß<ÆcxœŸáI>ùj ¾†¯óò”„§ùú_?#át5¦ñ0vàY 3a´Àá9þ~“—çCø_`Œ™æÛa|/IøŽ„ï ÈfÚÑMcرtc\Â÷èd¨à„¶†¡Yý)Õ¶5[ 7­ñظ¥&SZ,‘Òcýæä¤j$㺡R-[³ é÷Ty®¿©GCØ5‰¥Ã$®ˆd!‘TÚŽêhε§Â0t”×µŸU=®¦2üÊÚø1õ¸Ë8z*×m‡îª‡õqCu21n\q½×Û§Tc<æ¿»—Ù9ºÝØyå—{0ö^ÝÐ^ËÍåÑ×é…ò–/oèõ³åˆ@°ßL’µ®b”ÁÌä˜fVÇRt‰› 5uDµtÞû‡A¶–@ý­†9exZ-óæîò ”&%Û†M£ÏÏLj†#°¯¹Ø]-ë •šç)f'°‘m¯ZΠvÂ!ÑÍë–±q\s¨ö’æÍ-wº!ÊtJc«Tº!+Ð6Ä倣YªcrdÉi×™C~…W‘¯ý˜ðŠþõÿ屻ܠ œè䥋—n^vòÒÃËœùk`C.63VB»EçÀ®/Âé`7É8€·àc }_`Ó’óú,K=É•…¯~ cúe܈Ý2>„=2öâÃ2zÑ'ãFZW×);ûO$4ßý;ýëöÝ+^qVš¶ÛMJÒÔlÅ0ÅQïÕÕPr1ÞAq)ƇƎi Òì‡x•Õ;+ãGxM`oŸ¡h“içdžL™Rm%m™Çõ¤–Tî1-%±Šè ¯Ë˜Å9wàv ?–ñFdœÇˆ„9]e­~P·m ,/xèÕ~Ѩ+yÎjg‰ë ù^t•1 d\Ä¢ŒŸà5 —d¼‰·dü”ýÑ{0“rtJÐN»Ó¨  -Ú:‡@TÌ£"ºˆàè<*çPm›ƒmŸC(ÚœCu´NÃç\Ž·Òz-$ AX<„:ñ(¶ŠÇpxÛÅhO"N8=¨dþ8ˆ!À…Xï€ ±æ.ĺ]ˆµ¯$íá¶¼Ž’‹?Í¢æ9l[„<Ù¼„£Ñó†/àªyÔ¾ÕšÅÕ¹ëHñ5ÁU­ ØÀ1Ú<›ÅV¶€x ’xš´;ÄiôŠg1 fÜÔ{Òó/Ä'0Lº Æí¾Ž#¤= ÉØNRBYÔÍ å- ^`±e”{ÍìrÑùùâÂzŠxÉ'{Œ|q‚g;_H·+ä OÈÙ<Ÿ*>g èCyú;rJ ƒ ÉF~— 9ƒ¦ =«5”´Z5ï/`«'u[Ü#{ œY¼ß{ùµ9\WÚ ôNl[ÀXl× —nlmÏ¢ñ•ÿþÓc³ý2v/bÇ(íçÑ4æE´PTF#$´™fÑéð`Æ'(‹XÞ¾ë2"…ý]ݳ¼]²|7Ù âUlg)T_'‡ÏâÓâ¦Ä8%Îãy‘ÅòØßÅþ!.âßâ’kÝ(Yðè(…@À6܉£n€¼ë[¼—FÁOâSµ D»Û÷E>’Ø;ÑÖ¶ö†`Cå<Ĺþ›v%ððòá&C¥Ä.4æ§ŽŒ„Ÿ:2’~êÈÐÜÔa茻‰>áJÐñA÷ÅUØ…iÜþçg òÿPÓÎÜE_Ô†°…¾_ÿÕ5—ƒáÿPK =o%@Æj‘£ ÷<org/gradle/cli/CommandLineParser$MissingOptionArgState.class•mOÓPÇÿwÝÖ(ˆÌeÊ1D@@1N4™™ šèÝÖÌ’î–´Ñïä I_øüPÆsÛ2[2Xš´çÜžó;iÿüýõ@ [*bÈ«ˆ£'iAª·U$°(ÏŠRZŠb9Š; еç–ˆb…aò•'¿æ¶£ÛU—»:ƒö\Ý.›Üqt‡a¥bÙ­bËæMS/6L£X¶Úm.šCè¾_¦²IQ¶ a¸Ö²£r5†HÙjR>Òp»Ó®ëö^7édªb5¸Yã¶!õà0â~2(Ýé—†ã¢å#Ú­ ªõáY ô¤R’mþµ®“f»þ;Š’­ìòϼhrÑ*V]›Ü6s; an·d~}/Æ-q ±31:Z÷–ضÄQ¨Ä±ù>”ûð0Ç$-ÑcòD4©öl®Å]0¼ièÃ}JÞb„¾,É[‰!sµjuì†þÔ‹2Óg³(û¡aIy[ՠ✆5ÌjXÇ= WpUÃæ¢ Öêh{İp–3,Ÿ½ éáí`˜?ÅpüFÇ çh‡Toà{¦.Ã,eϼ0ª×ŠN[.Cj˜3Rô‹C®Ò”œI BrBt2IÚ3ÒBôLäÙ!BùÂO„÷I ‘9ÈBeçélÆ7Ç’àIË躈ٺ@•|á‘o]ž¹ÔzGér\ÂeC[p^P|Êãù`¬°påû Ü®‡Kù†]Üx€“’JRˆäk˜ À÷ƒãL9FOB­žã]h¼›c 7Ôš§(Êñíÿö©Ò¹ˆ±Ž‡Ó|C—M!@“eØoØ!Øþ‰dÞ÷TØÛ°›^ã¥t ó^EYÏ3G5iDh8%hù+aòVÂuÒÓôD2öPK =o%@q󛉙ª=org/gradle/cli/CommandLineParser$OptionAwareParserState.class­UÛnÓ@=›¸qâ¸$½¥@[(%¥{ITJ/\JEQ¥¨ E*o›ÄÇFk‡Ë§ð¼ðD%>€B̦nH• ÄKÆ3sæœÉάýãç·ï–q7$®jБ•OÓý\Ó0ƒY 9*æ4¨XP±¨!%Ë* ɪÛhp§V´“aªèŠz¾.xÍ6óUÛÊ?âÂ3kÛ¿1 1ÿ™åe—z ;p­B!Ñ›–cù·̆ÃÃåseeÛ­Q³)Øk6*¦xÌ+6E‹n•Ûe.,éAE¶ËyøÂ·\gëZÉç>åõ]Ç1ŶÍ=Ï$ÜZh—ÙÞLô_Ó þ¦b’'üc ÃÈlñ€¿äy›;õ|É–SßÈ=aˆrQ— w%i$®³ç:'ÉSÍÞëEÞñé6µ’ÛUsÇ’Ç“éB/J)¤u `EG?Îé¸1«:nbMÅºŽ l2¬„*o=õM±c Ï/5+Aša¸WXªÝbX8çñùÐÀôNWrЮ­þã æÿæ,UÜaÃLøjg—[«·¼“ÁN†í:C?¯Õî¿ö/s»iþa™ÊÝT]ê4s^­šž—]Y¢‹;}†«(—ôù¹²g=›Ý.µçš Ç)“ô†ÔéÝÁ°\q –KO‘(Ú£AšìyEBDɦ¹C0ƒ}AĘ?DôcP ª¥<€Æ‘bC¡X†rTCöÐz’⼈±€y|‰ŠsŸ¡¼oóÅ ×j´ƒ'Öæ‰a”g¸„É€ç}-TÁø„(Qõ‘e_{‹ÌÔ}éÉ u‡Ôû«}hkj’#Î&:t mÝB Á•VÍΓ5H9Iß—Q%Bg™ÃeE~er˜'D‚lžx¯“E:þ PK =o%@gºŠ½ÓÛ7org/gradle/cli/CommandLineParser$OptionComparator.class•UmOÓP~îÖÑQ:oSðDÌ6ÞÊA("8Å,.`2CâÇ2šYÒµ¤íˆ?ÿ€‘ÄðÙŸaÔŸa<·mæ`“â‡öž{Îsžsïyi¿ýþò@ÛR˜•ÐË_=˜1/AÀ‚„E,‰x,bYB’ï“x"b•Ã×D¨"ÖEÐúʆ¥ï4êûºóVÛ7I3P¶«š¹§9߇JÁ{o¸ éÝ#ϰ­¢]?Òͳ¹dYºS45×Õ ±X¶šRs´SWª¦¡¶®Y<ÌÍqugò*‡Ê Výz•»† ðT£ùqÚ¾\`˜ˆvhÂè®uƒ{ ”µcM15«¦T<ǰjj`#H6×bÜÝ?Ô«žÚ®á§ˆ}˜¿LÚ¸¥ ‚ÊŸ.2k•Wmò&@†îŠQ³4¯Á3Zþ×Qža*˰¥ ¢–*véêÛo‹L[ø9N-#~ϰ)b‹aå†-d¹µ¹2 œ?+⹌"^PW^-ÃfdÈ¢æê%ËÕ-×ðŒc½=öXBÆ^2ŒGeãF ÿ=—.TŽa¨Sé¨Å£Û‚JWÓ½  j.ßÒ·ä5w X†[ã›&) ‹Ó`PÚsåNöÎ §æ;Å¥Ñ ç®]“/až¾o½4<}ôuã-G»Ú)´Ò\!1u†Ø'b¤wW²ï"YÆm𠤅Ή,Aëòô)âçÞ±3$>£ëâÎL›jM8G’ï»gG„SH'Íh½ˆñ ²ŸÈ²_~Ô¥€9ŒÊ¥;¸ëŸd÷Hâžqc䛥‹“$¤·ètÂÓ½& ñ"55}žzN!Ÿt¼âxlKa‚È™/M’KƒQH¼Jk,Ì뜳Lh&ˆ0Gö8ò>~ Óþ:ƒ[´NPSTŠ eö­H'I£Ðl”~P V0úPK =o%@“X¨Ú§¦8org/gradle/cli/CommandLineParser$OptionParserState.class•RÑjA=³®®Ý³ÚÖÒ456µTKé&%/ÁRh„’‚$Cú6ê°Ygev,þVŸyèô£Jï¬BŒ;çÎÝsÏåž;þÞþp„7>r¨ûpQ÷ÐððŠ¡ðI*i>3äZík·›ŒÃNO*q>› „¾âƒ˜2Õ^2äñ5×ÒÞ—I×ü)Cåbjd¢.¹N…înèWé›RBwcž¦‚(ǽDGa¤ù(á0–a7™L¸Ù>‹ºæ=‘C9Qjs.ææ‹Ž<0l­ô9lµ×K¯Šú‰"­ÙD(ÃpÚêùOÆ\Eaßh©¢ÎÆŠåH˜3žÞ©’™ß³FT9…^3€ámk½öQÇn™24¦Fýd¦‡â«´K©Ýã|°–GÁC“áãæ«`î\ºŒÅ†|¿‰K ëGah¬#¹ zÂ.ìW€cg"W=º…„d1òïnàü¢ÀA1#YßçxDqiA€mÀ¥µ¡’a3|‚§Öl>°ÌçKñBg)Îþ/^[âY´‹YÙ^ÆIíA¹}l¹>vÂg„ŠÿPK =o%@Îm œ˜œ3org/gradle/cli/CommandLineParser$OptionString.class•S[OAþ¦¶,+¬å&Ц`•vKYŠx‘Xcb$`‚ÁàÛЮeÉv·Ù]Œþ¯’$šøü-N6Áº›‰À+$OWŒÂä>b;-ð 7šGg `,š‚q9á]Eq=…k¸Þƌĵ2;8ÆlL–ŽaBÚFä•ÄèvoâT\¡zê/PK =o%@ ­¾ñ—ƒ=org/gradle/cli/CommandLineParser$OptionStringComparator.classTÏOAþf»eam¡"TE+( E–‚¤„Hš˜1Áèm(“2dÙ%»[â¿'oìÅ $šÏþ=ÆÑßl× ´¦ÆÃî{óÞ7ï}ûÍ›ýtúèÁ„ S½ L˜2¡cZ½,3*M¶``ÖÀCײtd°ÂËMl2è%w[0ô•¥#žÔö¶„÷ŒoÙé/»norOªuÔƒé3¤×÷é:'jÉÝÛç\!±æ8Â+ÙÜ÷á–Ê®Wµªß¶…U±¥EØ=îl«fO¹ç /Û¾R‘Á¨„+j:ž+ïònÙÜ©Z d±52±F{ܰZA±o4Ó³$‚¿ãzáØ‹ß‹Ù Ö·vE%(¶FT#íåÌùQNeHéy„å:~~¡¨!û/@†ž YuxPS¢,ÿj-¶õGÉåV!V¨”¹áÖ¼Šx$Õ©¦[ÚM«M $Là> ,2<ìȱÄ}±æøÂñe Dëx w@¨Ž£ "ͺțañ?§é\±†X íÔb¸Óù$hbláTƒðÑ4ŒtÚƒº„&Ä%º²:4%,­zie‘¥iA|òÚ[r4ôÑ»KÙg¤ÈO4¸Œ¨¹"y¢Ío£8°š?FLC =¶2uvµ gaêGˆkõÌ‘r×ëï¡?g'ˆç ÝUo6¾Eÿ°/èe_‘aß0ƾ#Ç~ À~Òßã4$4ßhRÞU\ I®â:y‘›Ãn½ ²¸IžžZ%♈øcÊÄÈ&'óaLÑsŒîzÛ¯i›Í’Dq8l–¤Ü0´”Rh4*¼DV‹ädíåL7Í‚q*˜¥| wCüÆC›Ã²CïAýäÝ&‹T7`÷0ô PK =o%@R¼·2org/gradle/cli/CommandLineParser$ParserState.class•SÁnÓ@}ã8qpRšZ  m IÓÆ” â@RÔ"¥ê¡·Mb¹®ì5Ú¸þ‰ 8ð|0k§%i"…X²ggvæÍ{;ë_¿üpÇF;6rØÉ£fã žZhXhr/}éǯ™Fó„`v£‘KXïùÒ=¼®:ƒ€#•^4Á‰P¾ö'A3>óÇ„Â{¡Æ®êÇ"æ`ñ”®êb\öT|ô!ö#IØhôÎÅGáBzN?V¾ô:ÍSBÞ_¦d„ò4˹<ÂZ$§Ð,ìÊéz†÷é‚& Ú.—3‡Í ‘<Œä%Ù׋ô¬|N‘œJy#GZêåP=mãÓ3Bí² v?ºPC÷­¯¿9—ÓւаçYì·[öŠØGÙB›°·Š4VöïpŽçî0&<_ýÔ ÛË…Í4K'A°BÏôå­.C0«ügå  †–ϸÁžÃ–§ìîw_yaÀæo. þA¿Å4í:`2”  Û¤ÃU††nU2ß`~™…¡L³™¦¤0Éênƒpwà{Ø‚¾÷¯ØµŸßk̨0ÅŒRÈ’†|8)|Á֘Ⱥ^<‘•òÉ^ñÉâªIÙã$7Ùn!Ã;u¬™6WÔq‡í¶(åÿPK =o%@7Ùßn?org/gradle/cli/CommandLineParser$UnknownOptionParserState.class½UKOQþî´Ó–é¥@Å"¢´C¡”‡Š ŠF‚&( v—vRG§3d:Uþ‚ÿÅ…$<&n|°pãÆþã¹3“R¡¤Ô…›sî=÷|ß=÷;§Óƒßï?È㮂Æt`¢ƒV9a&…É‹ƒ)Ó˜‰âz7äªË]=Š9†øîTugUÔG–¥;“W«z•abÙvʹ²ÃK¦ž+šF®`W*Ü*-–îãFàó !î”’Ë/ø+ž3¹UέºŽa•é(^<Ä2 eöxJ ü‰,–á.2èé㌭ Ú+>³Æ.Ø%*®[¤¬Ô*ºó”o˜ºx‘]äæw ±‚a÷¹A" <³^Zökëñ¦kØÖ_rž¢„“Àôü®²î>äÕ%§\«è–Kê¦3ë¶-ÊpÜ}Ë]rO¦3íöI±­CÚ{MÔm›1Æë|DNÙ›¦.FìÞü‡¶ÎÎ{M–¶&…É 3%Ì4ÃÈiÀô²U»æõ†hêX΄x£Š^ô 3¯¢ =HªPÐ¥bƒQ,¨¸Å(î0Ìýót0LµÄ6õ4‰eÛ™~¸­…bMŸ¶C­†€¡“—J÷·\‡¯q³FûþfãÚ„êØ•¢a},CHІÐ*)Zäyêù$Ñ>šØ~ÚUh&߯±}HÚØ.BZvam|ò6HH‘MA¦ÿ™}†Â¾ ›}E;À:Ó| àà­Ä…Ì[‰+%o%Š Qô<.WgÉ‹,)ü¶~ODDØ7WõO^†‹ ¹)k{ˆ¼;þÞ–ëàK¤Œž#/þáS~BýE2.{/bb¼šEÊW$´Rk¡=DÉɇŒŠ`a?g¿JJø¬Ô‘^\ ¸ÖIAÒ1m,;¾¶}¤ª~ÆÏ©Wõ@çFcH{:‹UÆëŒ„1-‹NòÉcjXücÎâ,Uy…<blfq3¬üPK =o%@ƒ•Žû*%&org/gradle/cli/CommandLineParser.classZy|×}ÿþ¤ÝÕh!°Ø¤ Ⲹl0Øâ°À`´#±°Ú;+@>bœ`Ç!Nì86)ä q«ií48F ä#N]稸mÚôˆí’6NSÇmãºM›¶ï›Ù]íJƒ%úóÞ¾÷»¯÷ûéÃ.žÀ|ùlÂxS}ÞRŸ¿×±4üL‡ ðøGuüsoã:wÿ¤á—þ¹ïàW: ¼«£ÿ¢á_uáß ñk¼WˆÇûêóþSÇ]øMÿ¥£ÿ­á·:BøŸ þWýþ?õ¹¨ .é8 ŠðDòÔ'_ø‚â'{ EÓ$¨c.³h¢ë¨Â… rC}Æ)Œñê3A("]™¨>ÅšLÒ±P&kR¢É‹eªŽz™V(!™®ÉU:–‘®„ðž&Wk2CÇ*±R®Ñd¦ŽÕê²T® Ê,Z@f«›² :•$åêó!]æH…ÚUjRUˆ&©J&µj;W±® Ê<%ãü ,P¿¯Ód¡ŽŠð"¼ÇÔÓðJ…2N“ÅAY¢tXªc·4¨Ý² ,'_ZZVè²RVir½cC,f%ÖDMÛ¶lÁ”ÍÝÉH<Ö’LDbkâ]ÝfÂLÆš4 f®1mkC̶bv$9h ¹ØÙx«Ó¶ÅöÇâ‡bîå3a[‰–¤™´4YCŽ7]æn­`¢Çñ:AISĶÉÚ½mLt:WÔ¥±#i%ÜS[“õ‚ÉÎÉúHÂN¶ô´Q®.3&ÕVGó YדŒDëšÌîe‚‚–HgÌLö$(ïºÜÛåîϨë¬s ,ÛOtÖu&ÌpÔªkFêR’nŠÄ,—õ²•¤9ÑŒF㇚"‡­pJyìLrÎs¬Ï›â°Õ°ÚMDzäBQm—w$^·¹'ÙÝ“$Ëì"íIe*2îÚˆm¶E-0°<‹$W ò+*· |kâaKiK¹š{ºÚ¬ÄVH^›âíft»™ˆ¨ß©C_ro„rÌúå\C“½¿[í‹+v´Nåp Z8‹)¶ý¤:dúºÃíV:l6 –TdAm ”àccg8§ü X8ª’e#bœTV,̸¦eñt”)ƒzˆ/æÍ'n<Å;ßTò"ẽ¬Hsôan.ËçªÉxꮘ‡·¼”×ÄT6Î]õ\¥§äKow:`¼¼á‘,*6vLÞœ9”Y¬©H²cCyVV1‚WëÝ*Ó¶Ùf'õ Uxg›J%#žSR&Ça+‘Ž'÷Ôέ+-V’ &0§;9Ó0EY0›"¶Êßoõ2§šÑ/—ެ.¶bÉ„BZç®%¹5«Ì9V¤ã=I†*Ëj—™tJJ6äúô1!Çç¨DAýQ2äšßeÌÎUí2~.¦ÜeÀ–yIëUg=±¯.ʘªñ¢Ñ«º'7ß¾x„Y»¼" M<µÚÒ^åÏ£øY\UàdŠÍmûHD•çÒΔûá<è@Ûʼ涞ŽåÉi#­vn»õ†2¤= .¯RŠ­òÖH]ŽQ©±U¯ðõ™‰ëŸ/jÅÊ2E’ÐÍöv˶ËÍ›'(¯=…+ùžæž7„¹Da^7Ì=@šÄRE"¸œhîcª·Ä{ílKTÑ›2‚Ò\EÇÀý8jà^1ðQµû8ޱb±¸Ñ´÷’&78/› <€iÒdH³l6ðŽ JG«|#2ú5ÙbÈÍr 9J‹úlÔZá=-…½M“í†ì[5i5جì2ä6Ùͪ5Üφì‘ÛiûÚZCîSP;*Óì6Pñj£çkkwíY±»Úv¹Ý°X†t‰ïU§žº]1·Ê}²_D éæcйR7xG¥]{jwÏ­bZ ‰Ú˜î‘Ö%ñ„!q%èÔ‘Y‰†UB ué–†$Ä6$©”!å!‡%fH¯òê$ªþÿlMXý#˜?ÆVc¨=WƹS}îÒänCî‘§¥NÖØ~+œ ¨‘a3"ߘ¨caøè`Ƚr$GáÆDÂìU•]“û ùˆ²g^M©?Á+†|T™í¨ÜoÈrD“xQ4äãÃhd*¾!ÇTlùÊíòXNˆ¹•ÑOÈnC’O’I¹ã›OÑÑvi©B0äaåŒ)Þ5P“Gü§ùœf5¬qf”\OßÏLwɆÂÕ¿tN¹=§4b—šQ¾üáÞÒ0«¤xTyä3†<¦â¾a‹Å“¥f8\ÏÂ5‰KŸ´»0vÒL$KE’{KçÔΙûsÝ¡É㆗]”~Tϱµ¼~T QGÄ¥£’¸Ü´8–èòž% ®¼ Ku»ÌºhljÄX:Öì>œ j®¤ÕK Íl«/ïãÙ%¼×NZ]™^ ¯3qf¦Ë¢a Ï—9`Ú*íÕ«¼kdS9²©—“ð$à´·¤4­¢òrmNè2M–êÀ§z¼Ù?†×~ô©bô±h¾Ã­x¤|"©é)G½¬©®xä)«Ù^Ón¶'‘½Œ/æü˜\QéÕ(u™½mjK$Ó¥½¤Â£Û©FÕ=fÔv6Œ°Úÿß&Áö½Ê¹vO› Ï’Š žmã8ÁY*ìôPáÊúÊÙǧ˜)#;£û¼1L†Ã&`- [‡7wÐ=TiƒòñoÕt§Þ8™'Xíåš+å]Ø%ÍH̾I͈³»ÛR5©Ö“öe:’ &ã™ÙµÂSôñV’=ÅøºÛ’D-UšìÔ;“{0¥ ã±æx,íÀ"2­Æ:%ßœÑs2;Ãr>ý$9wY5Äi¥|n£Ñ( lŠd†Ø‰9ÙèÎäãsk•ú‹L8ì`­e·'"é?Ôt«Ùy‰Gþ\¶›ë8×;rºl2•ý*€hÇ 3Æ;0A²ßîþ À­ënwnš>³]6JΞí¯öÊÄ¡àðwD{lJ5Ù˦|ÅÆk©ÙséÉš„žÕŒ ;=”½#¢Œ7aÄù9ó1lÙ‘„Îôû*{zl\‹0¶ð#OfÜÇ_yøÿqJsö÷;+Ô<MSÓ„åÇï'ø« ùÜS«ÎÂW5ëYÎ ¯êhg<ízˆßbøø­çw1& Sä}|2EŽèø†úóþ#ø41é\ó¸TUŸCA?ôofˆ¤õ).PŠ€Ú=ŠÏðþ1î}\wˆw‰æ?J IÆ7ˆÂÖA­UÏ"oãg1þ,&4 ¢¨µªFÎbbsõŠÙÏúB¾LœWÕn²àÛ(ið׆üý˜rBžù‹§öcÚ  "ÔªP§7÷Éx|U?®>é„ ù <£×4B~Ì$ÀÝ(uæ†üE+úqm}À…,!Ä,«…´ùîppgé"•9H×:°> ”dCþ@næ3(?‰BˆÐ'Q8ˆ9ôLÅ‹D!PC@©  2'0EÑ ¤8:ÒáÇ)Ú š©¥ ï«D U×ô£V×öS~MáCÁ~Ô@q(˜V—¢à˜:ž×ì¯/()P&›ÿ–P+þRzÍjÐsIê)’z†ä¼æ£Òwéå>¬¢,’-nê¾å£É¥€tÇe šû.Îãíu5*žòxúªù½ÓÐ‚ÙØŠFlÃFlçnLÜŠýhE/v2Svþ6ÆÔn| {ð,nÇK¸¯ê§hÃ[hÇo˜Y—`É8tÈTtÊ ì•RD¤ûe1¢Ò‚.Ù…˜ìC·tã€Üƒ„ƒ-O")Oñ÷–çp§¼‚»äG¸WÞÁù5çø÷ñ€\ı<Ç*îû™R½Ì„Ïâ÷ø}3éž“Ü}é¥Î4Je¸·”Ã…ÓÈi>‡ÏC«ðbP¢6ç6Hž©]%¾‡/N#7H­ÞÃ)žÐ(çñ%îü¨–¿À—ñ„Jî<_:¹{_aÞM“_á«”(³åžDíýûé¤w ¾ž©<ÀÝâ©T]YÄ•ãZ•ï ò«†R_wÒýa²~$«~h™úq¿7 Aâ1’xÜ“ÄÓŒ‡DþêÊj!¯ bakõY,by¨gÙXÜÊ,_rK›k3õc yØ1ˆe Ãå ¾Ú¬`ñ`ŽºÅ¯ªS€ ù ~^~½_ÂJg%]@GºkÔ.%VâWù7ÿnª÷÷]zS¡l‰ÒAiRV@³ƒî0¿ª¦x³ïyliÍW7 Zúq ZZ“Ö‡µ%Lê­ÅÛ\¥ü9à­¾EñÒC4ÏöÓ™´á*~¿È ?…º’¡¼€Á¼…Ák2pc ÝC Ûã ÜS ܤo08ÞÆá]|¿Åi\ij¢ã Ó½_ŠpV✬ÁyéÄ Âsò0^ïá%yßɤíq¬%&!ÞÝNúß×Iñ4ÃðŸ¯gð-&ÜÛ(c‰ù€oÐÃ?Ç>Fäƒøƒ_:¼‘9™±|Êy òøûÏyÜ·ÒÆ'i£ Ñ/sç#Þ8'F}H2ª•¥ó•U2mÛIüØiÛöÑW*¾óŠ‚øKüUª–×qU–VËjXXŸUÅýø‰"Hä¿Æßx ç o"½‘ÿÖ“³Œ3Uþ»Lw\åܰù„p?,–S_|ùßBùiç¥É¦”ÇäPÔßÀ^®wòï`'¡„YÅ5‚é4M˜Èt6ÐaD¹vqÑeq®ÝÄ<À5áÓasMBý¿£0z¸äzˆ÷E\síåz§/wq½›ð÷pý0ášðÎ ~PK =o%@ôi_1È-org/gradle/cli/CommandLineParserFactory.class;õo×>CNvvvF¶ä¢ÔÄ’TF MŸü¢týô¢Ä”œTýäœL}çüÜÜļŸÌ¼Ô€Ä¢âÔ"kF®àüÒ¢äT·Ì Y n‰É%ùE•zY‰e‰Œ ê„ „*gdiÐÏIÌK×÷OÊJM.acd`d`bFFf‹H21°PK =o%@þÄÌiÁ&org/gradle/cli/ParsedCommandLine.class•VéWWÿM¶ ÃÁã‚@F[Û*P,¢–Ý…‚­eHÆ06dâÌÄŠ­vß÷½Ú½_üÒÚS¡”Óå[{ú7ôcÿŽÚûÞLB–¡Ò“sfî{ï¾{ïïw—ÌŸÿüô €½øVB¦D(<˜ª@3¦EÄ%øíEB„*!h/ÎU"‰™Jh8ÏOˆH‰˜•P) UHWBÇŒˆL%.ÀÂaIt-+a.ŠxRB¦‚¸ÄÞsA\f律ÆÓìævíªˆg‚xVÂv;«¤CZZ=Æ=vv“媌¡šjÚ²·Ìb磪E*;Šw\rCê%ËPzŒdv–Ì‘¡µ׆4“YÚY²µ‚©@—–Ö¬nZ ú-ÕP¦Sjgë˜_¯žPY°„f$;;­§Ø™€ÐWRcŠ¡±µ³YaSL.˜B™Om§€Ú‚è¸3K7èLÎpúl‚´¬–]¡;w¶—ÞqÓöY3šé¢[fŸtE=—®Z7†ÔÓ0—ÉQ±ßE¿ëîá±´tºecUwYÆ‚–ž«ïÚ–V·$Ȳº¥ö¤ºÆˆvO¾ÛÍ€éXmÁdÜg­LÖÐPváPVK%T–ZQ3j†IZÂ$ˬ<× íZµ®k¼3Š™«§õ-å­“%.rû«¯½š¤j)éÈPŽ÷žÜU¶¹æ5J"Á-Ž)©¬ºBà”hÿEû¼‚ôs ϺèÞ½pþ\iTÏqõ¨Æj¼®Lo7ó.ã^¼BÌ,£íSÌ¡2Z); Q'£»¬[>è1 eŽ‘$cöŠxUÆkx]Ä2ÞÄ[2ÞÆ;ÂwCF¬¯™Œwñžˆ÷iš–ò'ââ#[aÐn2£áâ1ÌöŠ.›>¯Æ)ú~ ÈøŸÐ]¡?h*FÃ2>Å5jf£OF7N˸ŽÏd|Ž/hXtA*¥&•TÎó‘KqÕÁZoc 77™Íá´n…ê9B˜ØÍ2)âK_1‹_ã›rîʈ¡ñÁj:ýÑxKi—íÉæmaÕ*ïKš=š3Ω6ŠÊ½`̇Êwi@P£Ž£Ü:5¥/ÍÅ̦”!õ\þ´¦È‘ýOº¦h£hMeHNøÄÚßRn¼|Ç5‚À9ݘUÈÆ—†;óßF–§©’ɨ鄀v×´ò8 Æõ´¥h ýz Œ@o’áÞåvꆧªx2Ñ}*,ÂD¢'•¢áÞRÀq¯N%·'Ç$¶Ñ'XhªÃ‹kp’ÛèëЃ(­©¯óë­©™óë{èÓTšûH¾6’‘v®F D–à™X€÷6|$úI ܆HbÄŠÛÚQ)`8ºYÀ5 ’°FÀo¨YB5é¬íðµÏ£f!þ¿£fW\׈ü_C Á·ˆZ/ÆoÜùëÆïoQ^ÜOÏ$zn„ðUcIõhÂ&Äfôa }Ä6â2¸B<@š}½FŸ²ûqŒ/è¤oá>BÚ…ÉÎAZwÓÓKܜ৆¡àÒ!ô?‡I–émïÉ3v”$ô$¾0@^˜N8´Þÿ3ê&¼Â#.`Ã脉DýM~—!²õ›x´¶ý°ãÛÕüMï½O.¡ˆÜ8ìë¶Éîð1ª8û˜äÐèßrR4´i›Ç£¡-üÕà/Xy»oÜù#:Æ›%ܶR0©ª'J¿vª†ñ²‡bÚËy¦ê`ÑvSD-ô]?HÜú©Ž:9{>ež½“âì É0F…D6Žá8ù\f”iÈ3z’¤Qœrí§–‘šHÛ<¶Ž3: y؃ïòJ\…sVg_ÈQCgÈœÀF¸cÖ¤Âð2¸¬ÞÈà6ñV=ýõKØ>ÚáãékcÉZÀÎ_£Ë qŒýTU$RM s·aÛ`Þm«ã¶Šê“Õš‡ä1Œ;ñ€?«ŠÒr8QP~Ç MÎ#ôœÀ¤ƒâ°CŽÌŒŠ&Æo•ðr•äv™9 Œ3<@àQ<æXL“ƒ×XÄË£=Ê[w¹h_Ž·Šƒž ÷$µàî'b[Èûiäí'p‰µš‡´×rJ¼´{–Ûzü_PK =o%@)*÷Í¥â,org/gradle/cli/ParsedCommandLineOption.classS[OAþ¶·-ír±\TX.B[„ïZ¬Ä„¤“ ¼ íd²Ý%{!Â?ñÝ ‰† ‰úì2žÙ] I|Ø™3g¿óóÍ9óûÏ÷ñ2‡^̪(æÀlzPÊ£Œ9w²˜Ï!ƒy6²¸+÷E÷ä~_ÅUiMQ&YÆí0fæ/PK =o%@`}ò6Á¿ 9org/gradle/cli/SystemPropertiesCommandLineConverter.class­V[WUþN.L¦\"P)ˆ)…špK/µ\”B*©Ül„¢í ah2g&4ñVï®å»¯ú’Š.]}ögøCÔ}&Cšd²Ú”åË9söÙçÛßÞûì}æ¯~ûÀu|'âbîða+"â¸'â#¬°Æçu"Z±‰EÜG¢ [ø¤ ÛØáçìŠð`/€m¸ˆ}¾øŒŸ‹èÃCø, 8dhKì&¶bk7ïol2Wå9š‘µt4aª–že¸°¤k¦%kÖ¶œÉ+ -sª¦Z Þpd›Á·¤§HÚ±ªjÊz>{ [òAFá`zRÎlˆÊ׎Ðg©&ÃÔªn¤£iCNe”h2£FEÓR²›†žS KUÌ%=›•µ%ó'$T âÒšÔµC57j$\RuhS6L:Á ¶äìo†¡WëS@4åIÜö7I6ºÂ‘rHò–š‰®É9Î!¡¦5Ù²9ÌÔïϹ#è–,Š,»ÅpÇå‡M&UÅn¶Ž„›”7§SXYœÂþX)Ú™Šr†bšª®1xÔa†îªSqЧléÜcAÏY¤d6›ƒ˜«$‰g½žHomÖ‹¹³ÌO3Pb¬TÊ ¤¾íp5iê¼™ì>»öÆÆÁ±’´H¼Ò4Ïês ¡<…k|¸^[ •íT½¡ÅÓ2ä¤Õ¨ˆæÎ奈„ž7’Ê]•g3ÒLÁNr$ ƒx›¡³•në2•›iãLðK%@‘pˆ´€# *Ž©¼Š*k„œkW é‡!ëH ÝÛ^ …•Éôdhb9[ä»óÙâ ¿ø‘I ‘¡ê}áêŠl‘»²Ü„&@—à &,y 'x"¡€yb6/¡ˆ/ á+|-á|ˇ§"¥–XC ˜d¸yŽ–Æ0ö¹skWi-é|VѬJ¹0„^Õï¨9êŽîLø;ñ‘—tÌ ûàìK­l8àÒ‘lžñ£®1n ¸N-+fÒP˜éðÿDÑU‰ sÍ`»ÎU,\mN“^´R~H)Áš×cU5y5·×JªÓ«©¹Ö¨êáA·”;Åo])XöK½Go¯f/UK)…C†žF>Çùc’'½[aw³i²aµšy~í*ï Çã·n½‘—é÷äý 1û1@ó[´òÀ‹ú¦^Bcˆ$Qš©@á}ö‹­r™Æ[؃!ðâµpÃ6à®:‡·Hê¡y`Ìÿ<»Þ 7±ë ú%øKh %v^`ж.§Óoãö–Ï:¸üë„ ÙÇ»íq 7hæÖ¿£u÷ÄŸëV1 8Hc¶Î8ɨ¡ÃçobÚBóþXÐ[B[ Ò).0¬Oœ¢áÄ裃á9<·}}¾`g ]Óþÿè§eðox±óúiåí!çºû|=~ߣzœ­çܼ6·A4Ÿ+Äc˜þHGð>y·Cží‘oœóñ'®Q\³cû.i ïôz7 ‰ØVb³OûS¶—û˜Æ ùw«â7—¼G’Ûôí#ɬ¹Îe²7ïJt ½õalèÎE ß‚“†¢Ã ‰£cãÏq±„7#„ÊZÚ"¹]¦-â,Öô84ï`Éž—ÿPK org/gradle/cli/CommandLineArgumentException.classPK =o%@$¸Rü<Y)¤ü?org/gradle/cli/CommandLineConverter.classPK =o%@6êg WF &¤Aorg/gradle/cli/CommandLineOption.classPK =o%@2_e¦è(¤Forg/gradle/cli/CommandLineParser$1.classPK =o%@©Ö¡È<Ê ;¤Gorg/gradle/cli/CommandLineParser$AfterFirstSubCommand.classPK =o%@¬€Ú„£)3¤›Jorg/gradle/cli/CommandLineParser$AfterOptions.classPK =o%@“¤ùé| <¤Morg/gradle/cli/CommandLineParser$BeforeFirstSubCommand.classPK =o%@·Ø(kPF¤ÒQorg/gradle/cli/CommandLineParser$CaseInsensitiveStringComparator.classPK =o%@›gžœ=¤†Torg/gradle/cli/CommandLineParser$KnownOptionParserState.classPK =o%@Æj‘£ ÷<¤}\org/gradle/cli/CommandLineParser$MissingOptionArgState.classPK =o%@q󛉙ª=¤w_org/gradle/cli/CommandLineParser$OptionAwareParserState.classPK =o%@gºŠ½ÓÛ7¤kborg/gradle/cli/CommandLineParser$OptionComparator.classPK =o%@“X¨Ú§¦8¤“eorg/gradle/cli/CommandLineParser$OptionParserState.classPK =o%@Îm œ˜œ3¤gorg/gradle/cli/CommandLineParser$OptionString.classPK =o%@ ­¾ñ—ƒ=¤yjorg/gradle/cli/CommandLineParser$OptionStringComparator.classPK =o%@R¼·2¤kmorg/gradle/cli/CommandLineParser$ParserState.classPK =o%@7Ùßn?¤Àoorg/gradle/cli/CommandLineParser$UnknownOptionParserState.classPK =o%@ƒ•Žû*%&¤ürorg/gradle/cli/CommandLineParser.classPK =o%@ôi_1È-¤;ƒorg/gradle/cli/CommandLineParserFactory.classPK =o%@þÄÌiÁ&¤„org/gradle/cli/ParsedCommandLine.classPK =o%@)*÷Í¥â,¤ÃŠorg/gradle/cli/ParsedCommandLineOption.classPK =o%@`}ò6Á¿ 9¤²org/gradle/cli/SystemPropertiesCommandLineConverter.classPK  \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" APP_HOME="`pwd -P`" cd "$SAVED" CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query businessSystem maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add APP_NAME to the JAVA_OPTS as -Xdock:name if $darwin; then JAVA_OPTS="$JAVA_OPTS -Xdock:name=$APP_NAME" # we may also want to set -Xdock:image fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" spock-0.6-groovy-1.8/gradlew.bat000066400000000000000000000045441202022523300164400ustar00rootroot00000000000000@if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega spock-0.6-groovy-1.8/settings.gradle000077500000000000000000000004161202022523300173400ustar00rootroot00000000000000include "spock-core" include "spock-guice" include "spock-maven" include "spock-specs" include "spock-spring" include "spock-tapestry" include "spock-unitils" rootProject.name = "spock" rootProject.children.each { it.buildFileName = it.name + ".gradle" - "spock-" } spock-0.6-groovy-1.8/spock-core/000077500000000000000000000000001202022523300163615ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/core.gradle000077500000000000000000000013771202022523300205040ustar00rootroot00000000000000apply from: script("publishMaven") displayName = "Spock Framework - Core Module" description = "Spock is a testing and specification framework for Java and Groovy applications. \ What makes it stand out from the crowd is its beautiful and highly expressive specification language. \ Thanks to its JUnit runner, Spock is compatible with most IDEs, build tools, and continuous integration servers. \ Spock is inspired from JUnit, jMock, RSpec, Groovy, Scala, Vulcans, and other fascinating life forms." dependencies { compile libs.groovy // simplest way to add Groovy dependency to POM compile libs.junit compile libs.hamcrest_core compile libs.ant, optional compile libs.asm, optional compile libs.cglib, optional compile libs.objenesis, optional } spock-0.6-groovy-1.8/spock-core/src/000077500000000000000000000000001202022523300171505ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/000077500000000000000000000000001202022523300200745ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/groovy/000077500000000000000000000000001202022523300214215ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/groovy/spock/000077500000000000000000000000001202022523300225405ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/groovy/spock/util/000077500000000000000000000000001202022523300235155ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/groovy/spock/util/EmbeddedSpecCompiler.groovy000066400000000000000000000067251202022523300307750ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util import org.codehaus.groovy.control.MultipleCompilationErrorsException import org.junit.Test import org.junit.internal.runners.model.MultipleFailureException import org.junit.runner.RunWith import org.spockframework.runtime.SpecUtil import org.spockframework.util.NotThreadSafe import spock.lang.Specification /** * Utility class that allows to compile (fragments of) specs programmatically. * Mainly intended for spec'ing Spock itself. * * @author Peter Niederwieser */ @NotThreadSafe class EmbeddedSpecCompiler { final GroovyClassLoader loader = new GroovyClassLoader(getClass().classLoader) boolean unwrapCompileException = true String imports = "" void addPackageImport(String pkg) { imports += "import $pkg.*;" } void addPackageImport(Package pkg) { addPackageImport(pkg.name) } void addClassImport(String className) { imports += "import $className;" } void addClassImport(Class clazz) { def importName = clazz.name if (clazz.memberClass) { importName = importName.reverse().replaceFirst(/\$/, ".").reverse() } addClassImport(importName) } void addClassMemberImport(String className) { imports += "import static $className.*;" } void addClassMemberImport(Class clazz) { addClassMemberImport(clazz.name) } /** * Compiles the given source code, and returns all Spock specifications * contained therein (but not other classes). */ List compile(String source) { doCompile(imports + source) } List compileWithImports(String source) { addPackageImport(Specification.package ) // one-liner keeps line numbers intact doCompile "package apackage; $imports ${source.trim()}" } Class compileSpecBody(String source) { // one-liner keeps line numbers intact; newline safeguards against source ending in a line comment compileWithImports("class ASpec extends Specification { ${source.trim() + '\n'} }")[0] } Class compileFeatureBody(String source) { // one-liner keeps line numbers intact; newline safeguards against source ending in a line comment compileSpecBody "def 'a feature'() { ${source.trim() + '\n'} }" } private List doCompile(String source) { loader.clearCache() try { loader.parseClass(source.trim()) } catch (MultipleCompilationErrorsException e) { def errors = e.errorCollector.errors if (unwrapCompileException && errors.every { it.hasProperty("cause") }) if (errors.size() == 1) throw errors[0].cause else throw new MultipleFailureException(errors.cause) throw e } loader.loadedClasses.findAll { SpecUtil.isSpec(it) || isJUnitTest(it) // need JUnit tests sometimes } as List } private boolean isJUnitTest(Class clazz) { clazz.isAnnotationPresent(RunWith) || clazz.methods.any { it.getAnnotation(Test) } } }spock-0.6-groovy-1.8/spock-core/src/main/groovy/spock/util/EmbeddedSpecRunner.groovy000066400000000000000000000066071202022523300304730ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util import org.junit.runner.notification.RunListener import org.junit.runner.* import org.spockframework.util.NotThreadSafe import org.spockframework.util.IThrowableFunction import org.spockframework.runtime.RunContext import org.spockframework.runtime.ConfigurationScriptLoader import java.lang.reflect.Modifier /** * Utility class that allows to run (fragments of) specs programmatically. * Mainly intended for spec'ing Spock itself. * * @author Peter Niederwieser */ @NotThreadSafe class EmbeddedSpecRunner { private final EmbeddedSpecCompiler compiler = new EmbeddedSpecCompiler(unwrapCompileException: false) boolean throwFailure = true List listeners = [] Closure configurationScript = null List extensionClasses = [] boolean inheritParentExtensions = true void addPackageImport(String pkg) { compiler.addPackageImport(pkg) } void addPackageImport(Package pkg) { compiler.addPackageImport(pkg) } void addClassImport(String className) { compiler.addClassImport(className) } void addClassImport(Class clazz) { compiler.addClassImport(clazz) } void addClassMemberImport(String className) { compiler.addClassMemberImport(className) } void addClassMemberImport(Class clazz) { compiler.addClassMemberImport(clazz) } Result runRequest(Request request) { withNewContext { doRunRequest(request) } } Result runClasses(List classes) { withNewContext { doRunRequest(Request.classes(classes.findAll { !Modifier.isAbstract(it.modifiers) } as Class[])) } } // it's very important to open a new context BEFORE Request.aClass/classes is invoked // this is because Sputnik is already constructed by those methods, and has to pop // the correct context from the stack Result runClass(Class clazz) { withNewContext { doRunRequest(Request.aClass(clazz)) } } Result run(String source) { runClasses(compiler.compile(source)) } Result runWithImports(String source) { runClasses(compiler.compileWithImports(source)) } Result runSpecBody(String source) { runClass(compiler.compileSpecBody(source)) } Result runFeatureBody(String source) { runClass(compiler.compileFeatureBody(source)) } def withNewContext(Closure block) { def script = configurationScript ? new ConfigurationScriptLoader().loadClosureBasedScript(configurationScript) : null RunContext.withNewContext(script, extensionClasses, inheritParentExtensions, block as IThrowableFunction) } private Result doRunRequest(Request request) { def junitCore = new JUnitCore() listeners.each { junitCore.addListener(it) } def result = junitCore.run(request) if (throwFailure && result.failureCount > 0) throw result.failures[0].exception result } }spock-0.6-groovy-1.8/spock-core/src/main/groovy/spock/util/concurrent/000077500000000000000000000000001202022523300256775ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/groovy/spock/util/concurrent/BlockingVariables.groovy000066400000000000000000000056111202022523300325320ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.concurrent import java.util.concurrent.TimeUnit import org.spockframework.util.ThreadSafe /** * Provides an unlimited number of dynamic variables. Reading the value of a * variable will block until some other thread has set the value of the variable, * or a timeout expires. Useful for verifying state in an expect- or then-block * that has been captured in some other thread. * *

Example: * *

 * // create object under specification
 * def machine = new Machine()
 *
 * BlockingVariables vars = new BlockingVariables()
 *
 * // register async callback
 * machine.workDone << { result ->
 *  vars.result = result
 * }
 *
 * when:
 * machine.start()
 *
 * then:
 * // blocks until workDone callback has set result, or a timeout expires
 * vars.result == WorkResult.OK
 *
 * cleanup:
 * // shut down all threads
 * machine?.shutdown()
 * 
* * @author Peter Niederwieser */ @ThreadSafe class BlockingVariables { private final BlockingVariablesImpl impl /** * Same as BlockingVariables(1, TimeUnit.SECONDS). */ BlockingVariables() { this(1, TimeUnit.SECONDS) } /** * Instantiates a BlockingVariable with the specified timeout in seconds. * * @param timeout timeout (seconds) for reading a variable's value. */ BlockingVariables(int timeout) { this(timeout, TimeUnit.SECONDS) } /** * Instantiates a BlockingVariables instance with the specified * timeout. * * @param timeout timeout for reading a variable's value * * @param unit the timeout's time unit */ BlockingVariables(int timeout, TimeUnit unit) { impl = new BlockingVariablesImpl(timeout, unit) } /** * Sets a variable's value. This method should not be called directly * but by setting a dynamic variable's value. * * @param name the variable's name * @param value the variable's value */ void setProperty(String name, Object value) { impl.put(name, value) } /** * Gets a variable's value. Blocks until a value has been set for the variable * or a timeout expires. This method should not be called directly but by * getting a dynamic variable's value. * * @param name the variable's name * * @return the variable's value */ Object getProperty(String name) { impl.get(name) } }spock-0.6-groovy-1.8/spock-core/src/main/groovy/spock/util/matcher/000077500000000000000000000000001202022523300251405ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/groovy/spock/util/matcher/HamcrestMatchers.groovy000066400000000000000000000027301202022523300316460ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.matcher import org.hamcrest.Matcher /** * Factory for Hamcrest matchers that ship with Spock. * * @author Peter Niederwieser */ class HamcrestMatchers { /** * Tells if two numbers are equal within some range of acceptable error. * In contrast to the equally named matcher in the Hamcrest library, this * matcher also handles BigDecimals (and any other Numbers), * which is important for Groovy interoperability. * * Example usage: * *
   * expect:
   * myPi closeTo(3.1415, 0.01)
   * 
   *
   * @param operand the expected number
   * @param error the range of acceptable error
   * @return a matcher that tells if two numbers are equal within some range of
   * acceptable error
   */

  static Matcher closeTo(Number operand, Number error) {
    return new IsCloseTo(operand, error)
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/groovy/spock/util/matcher/IsCloseTo.groovy000066400000000000000000000033631202022523300302600ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package spock.util.matcher

import org.hamcrest.TypeSafeMatcher
import org.hamcrest.Description

/**
 * Generalization of org.hamcrest.number.IsCloseTo to arbitrary
 * Numbers (in particular BigDecimals). Otherwise almost
 * identical to that class.
 */
public class IsCloseTo extends TypeSafeMatcher {
    private final Number delta
    private final Number value

  IsCloseTo(Number value, Number error) {
        this.delta = error
        this.value = value
    }

    @Override
    boolean matchesSafely(Number item) {
        actualDelta(item) <= 0
    }

    @Override
    void describeMismatchSafely(Number item, Description mismatchDescription) {
      mismatchDescription.appendValue(item)
                         .appendText(" differed by ")
                         .appendValue(actualDelta(item))
    }

    void describeTo(Description description) {
        description.appendText("a numeric value within ")
                .appendValue(delta)
                .appendText(" of ")
                .appendValue(value)
    }

    private Number actualDelta(Number item) {
      (item - value).abs() - delta
    }
}

spock-0.6-groovy-1.8/spock-core/src/main/java/000077500000000000000000000000001202022523300210155ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/000077500000000000000000000000001202022523300216045ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/000077500000000000000000000000001202022523300246415ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/000077500000000000000000000000001202022523300262675ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/AddSlotFactory.java000066400000000000000000000022261202022523300320160ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.Type;

import groovy.lang.MetaMethod;
import org.spockframework.util.GroovyRuntimeUtil;

public class AddSlotFactory implements ISlotFactory {
  public ISlot create(Object owner, Type ownerType, String name) {
    String addMethodName = GroovyRuntimeUtil.propertyToMethodName("add", name);
    MetaMethod addMethod = GroovyRuntimeUtil.getMetaClass(owner).pickMethod(addMethodName, new Class[]{Object.class});
    return addMethod != null ? new SetterLikeSlot(owner, ownerType, addMethod) : null;
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/BuilderHelper.java000066400000000000000000000032761202022523300316700ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.Modifier;

import org.codehaus.groovy.runtime.MetaClassHelper;
import org.spockframework.util.GroovyRuntimeUtil;

public class BuilderHelper {
  public static Object createInstance(Class clazz, Object... args) {
    if (args.length == 1) {
      Object arg = args[0];
      if (MetaClassHelper.isAssignableFrom(clazz, arg.getClass())) return arg;
      // IDEA: could do additional coercions here, like Groovy does when setting a property
      // (note that we don't know if we are setting a property or invoking a method):
      // int -> byte (at least if it fits), etc.
    }

    // IDEA: could support creation of collection types here
    
    if ((clazz.getModifiers() & Modifier.ABSTRACT) != 0) {
      String kind = clazz.isPrimitive() ? "primitive" : clazz.isInterface() ? "interface" : "abstract";
      throw new RuntimeException(String.format( "Cannot instantiate %s type %s", kind, clazz.getName()));
    }

    // TODO: need exception handling for better error messages?
    return GroovyRuntimeUtil.invokeConstructor(clazz, args);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/ClosureBlueprint.java000066400000000000000000000023711202022523300324360ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import groovy.lang.Closure;

import org.spockframework.util.GroovyRuntimeUtil;

public class ClosureBlueprint implements IBlueprint {
  private final Closure closure;
  private final Object subject;
  
  public ClosureBlueprint(Closure closure, Object subject) {
    this.closure = closure;
    this.subject = subject;
    closure.setResolveStrategy(Closure.DELEGATE_ONLY);
  }

  public Object getThisObject() {
    return closure.getThisObject();
  }

  public void setDelegate(Object delegate) {
    closure.setDelegate(delegate);
  }

  public void evaluate() {
    GroovyRuntimeUtil.invokeClosure(closure, subject);
  }
}spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/CollectionSlot.java000066400000000000000000000054761202022523300321030ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.*;
import java.util.*;

import org.spockframework.gentyref.GenericTypeReflector;
import org.spockframework.util.MopUtil;
import org.spockframework.util.UnreachableCodeError;

import groovy.lang.MetaProperty;

public class CollectionSlot implements ISlot {
  private final String name;
  private final Object owner;
  private final Type ownerType;
  private final MetaProperty property;

  CollectionSlot(String name, Object owner, Type ownerType, MetaProperty property) {
    this.name = name;
    this.owner = owner;
    this.ownerType = ownerType;
    this.property = property;
  }

  public Type getType() {
    Type type = getCollectionType();
    if (type instanceof ParameterizedType) return ((ParameterizedType)type).getActualTypeArguments()[0];
    if (type instanceof Class) return Object.class;
    throw new UnreachableCodeError();
  }

  private Type getCollectionType() {
     Method getter = MopUtil.getterFor(property);
    if (getter != null) return GenericTypeReflector.getExactReturnType(getter, ownerType);

    Field field = MopUtil.fieldFor(property);
    if (field != null) return GenericTypeReflector.getExactFieldType(field, ownerType);

    throw new UnreachableCodeError();
  }

  @SuppressWarnings("unchecked")
  public void write(Object value) {
    Collection collection = (Collection) property.getProperty(owner);
    if (collection == null) {
      if (MopUtil.isWriteable(property)) {
        collection = createCollection(property.getType());
        property.setProperty(owner, collection);
      } else {
        throw new RuntimeException(String.format(
"Cannot add element to collection property '%s' because it is neither initialized nor does it have a setter",
            name));
      }
    }
    collection.add(value);
  }

  private Collection createCollection(Class clazz) {
    if ((clazz.getModifiers() & Modifier.ABSTRACT) == 0) {
      return (Collection)BuilderHelper.createInstance(clazz);
    }

    if (List.class.isAssignableFrom(clazz)) return new ArrayList();
    if (Set.class.isAssignableFrom(clazz)) return new HashSet();

    throw new RuntimeException(String.format("Don't know how to create a collection of type '%s'", clazz.getName()));
  }
}

spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/CollectionSlotFactory.java000066400000000000000000000032421202022523300334200ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.Type;
import java.util.Collection;
import java.util.regex.Pattern;

import org.spockframework.util.GroovyRuntimeUtil;
import org.spockframework.util.MopUtil;

import groovy.lang.MetaProperty;

public class CollectionSlotFactory implements ISlotFactory {
  private static final Pattern pluralIESPattern = Pattern.compile(".*[^aeiouy]y", Pattern.CASE_INSENSITIVE);

  public ISlot create(Object owner, Type ownerType, String name) {
    String plural = toPluralForm(name);
    MetaProperty property = GroovyRuntimeUtil.getMetaClass(owner).getMetaProperty(plural);
    return property != null && Collection.class.isAssignableFrom(property.getType()) && MopUtil.isReadable(property) ?
      new CollectionSlot(plural, owner, ownerType, property) : null;
  }

  private String toPluralForm(String word) {
    if (word.toLowerCase().endsWith("s")) return word + "es";
    boolean matchesIESRule = pluralIESPattern.matcher(word).matches();
    return matchesIESRule ? word.substring(0, word.length() - 1) + "ies" : word + "s";
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/DelegatingScript.java000066400000000000000000000031641202022523300323660ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import groovy.lang.*;
import org.spockframework.util.GroovyRuntimeUtil;

public abstract class DelegatingScript extends Script {
  private volatile Object $delegate;

  public void $setDelegate(Object delegate) {
    this.$delegate = delegate;
  }

  @Override
  public Object getProperty(String property) {
    try {
      return GroovyRuntimeUtil.getProperty($delegate, property);
    } catch (MissingPropertyException e) {
      return super.getProperty(property);   
    }
  }

  @Override
  public void setProperty(String property, Object newValue) {
    try {
      GroovyRuntimeUtil.setProperty($delegate, property, newValue);
    } catch (MissingPropertyException e) {
      super.setProperty(property, newValue);
    }
  }

  @Override
  public Object invokeMethod(String name, Object args) {
    try {
      return GroovyRuntimeUtil.invokeMethod($delegate, name, GroovyRuntimeUtil.asArray(args));
    } catch (MissingMethodException e) {
      return super.invokeMethod(name, args);
    }
  }
}
DelegatingScriptBlueprint.java000066400000000000000000000020221202022523300341640ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

public class DelegatingScriptBlueprint implements IBlueprint {
  private final DelegatingScript script;

  public DelegatingScriptBlueprint(DelegatingScript script) {
    this.script = script;
  }

  public Object getThisObject() {
    return null;
  }

  public void setDelegate(final Object delegate) {
    script.$setDelegate(delegate);
  }

  public void evaluate() {
    script.run();
  }
}spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/GestaltBuilder.java000066400000000000000000000013631202022523300320470ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

public class GestaltBuilder {
  public void build(IGestalt root) {
    new Sculpturer().$form(root);
  }
}

spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/IBlueprint.java000066400000000000000000000014621202022523300312120ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import org.spockframework.util.Nullable;

public interface IBlueprint {
  @Nullable
  Object getThisObject();

  void setDelegate(Object delegate);
  
  void evaluate();
}spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/IConfigurationRegistry.java000066400000000000000000000013331202022523300336030ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

public interface IConfigurationRegistry {
  Object getConfiguration(String name);
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/IGestalt.java000066400000000000000000000015741202022523300306550ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import org.spockframework.util.Nullable;

public interface IGestalt {
  @Nullable IBlueprint getBlueprint();

  Object getProperty(String name);
  void setProperty(String name, Object value);
  Object invokeMethod(String name, Object[] args);
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/ISlot.java000066400000000000000000000013571202022523300301720ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.Type;

public interface ISlot {
  Type getType();
  void write(Object value);
}spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/ISlotFactory.java000066400000000000000000000014671202022523300315240ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.Type;

import org.spockframework.util.Nullable;

public interface ISlotFactory {
  @Nullable ISlot create(Object owner, Type ownerType, String name);
}spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/PojoBuilder.java000066400000000000000000000035161202022523300313550ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.util.Arrays;
import java.util.List;

import groovy.lang.Closure;

// TODO: test building pojo enriched with expandometaclass/category property
// TODO: test call to void varargs method in expect: block
// (related: find all calls to MetaMethod.invoke and replace with doMethodInvoke)
// IDEA: allow syntax foo = { ... } to make it clear built object should be assigned to a property (can't handle all cases with method syntax)
// IDEA: helpful coercions (esp. for configuration): List -> Set (enables the use of list literals for sets), potentially String -> Enum
// TODO: provide a way to set visibility of methods/properties to look for
public class PojoBuilder {
  private final GestaltBuilder gestaltBuilder = new GestaltBuilder();
  private final List slotFactories =
      Arrays.asList(new SetterSlotFactory(), new AddSlotFactory(), new CollectionSlotFactory());

  public Object build(Object pojo, Closure closure) {
    return build(pojo, new ClosureBlueprint(closure, pojo));
  }

  public Object build(Object pojo, IBlueprint blueprint) {
    IGestalt gestalt = new PojoGestalt(pojo, pojo.getClass(), blueprint, slotFactories);
    gestaltBuilder.build(gestalt);
    return pojo;
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/PojoGestalt.java000066400000000000000000000064051202022523300313720ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.Type;
import java.util.List;

import org.spockframework.gentyref.GenericTypeReflector;
import org.spockframework.util.CollectionUtil;

import groovy.lang.Closure;
import org.spockframework.util.GroovyRuntimeUtil;

public class PojoGestalt implements IGestalt {
  private final Object pojo;
  private final Type pojoType;
  private final IBlueprint blueprint;
  private final List slotFactories;

  public PojoGestalt(Object pojo, Type pojoType, IBlueprint blueprint, List slotFactories) {
    this.pojo = pojo;
    this.pojoType = pojoType;
    this.blueprint = blueprint;
    this.slotFactories = slotFactories;
  }

  public Object getSubject() {
    return pojo;
  }

  public IBlueprint getBlueprint() {
    return blueprint;
  }

  public Object getProperty(String name) {
    return GroovyRuntimeUtil.getProperty(pojo, name);
  }

  public void setProperty(String name, Object value) {
    GroovyRuntimeUtil.setProperty(pojo, name, value);
  }

  // foo([a:1],b) and foo(a:1,b) are currently not distinguishable in Groovy
  // neither are foo([a:1],b) and foo(b,a:1)
  // so we should probably add some heuristics to tell them apart (look at subject's method signatures)
  // same for telling apart last arg (could be blueprint or last constructor arg)
  // current impl is dead stupid:
  // - named args not treated specially
  // - last arg is closure => treat as blueprint
  public Object invokeMethod(String name, Object[] args) {
    ISlot slot = findSlot(name, args);
    PojoGestalt gestalt = createGestalt(slot.getType(), args);
    new Sculpturer().$form(gestalt);
    slot.write(gestalt.getSubject());
    return gestalt.getSubject();
  }

  private ISlot findSlot(String name, Object[] args) {
    for (ISlotFactory factory : slotFactories) {
      ISlot slot = factory.create(pojo, pojoType, name);
      if (slot != null) return slot;
    }
    throw new RuntimeException(String.format("Cannot find a slot named '%s'", name));
  }

  private PojoGestalt createGestalt(Type newType, Object[] args) {
    Closure closure = null;
    if (args != null && args.length > 0 && args[args.length - 1] instanceof Closure) {
      closure = (Closure)args[args.length - 1];
      args = CollectionUtil.copyArray(args, 0, args.length - 1);
    }

    Class newClazz = GenericTypeReflector.erase(newType); // TODO: check that this succeeds (Type could be a TypeVariable etc.)
    Object newPojo = BuilderHelper.createInstance(newClazz, args);
    ClosureBlueprint newBlueprint = closure == null ? null : new ClosureBlueprint(closure, newPojo);
    return new PojoGestalt(newPojo, newType, newBlueprint, slotFactories);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/PropertySlot.java000066400000000000000000000032221202022523300316170ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.*;

import org.spockframework.gentyref.GenericTypeReflector;
import org.spockframework.util.MopUtil;
import org.spockframework.util.UnreachableCodeError;

import groovy.lang.MetaProperty;

public class PropertySlot implements ISlot {
  private final Object owner;
  private final Type ownerType;
  private final MetaProperty property;

  PropertySlot(Object owner, Type ownerType, MetaProperty property) {
    this.owner = owner;
    this.ownerType = ownerType;
    this.property = property;
  }

  public Type getType() {
    // could possibly add fast path here, but be careful (inner classes etc.)

    Method setter = MopUtil.setterFor(property);
    if (setter != null) return GenericTypeReflector.getExactParameterTypes(setter, ownerType)[0];

    Field field = MopUtil.fieldFor(property);
    if (field != null) return GenericTypeReflector.getExactFieldType(field, ownerType);

    throw new UnreachableCodeError();
  }

  public void write(Object value) {
    property.setProperty(owner, value);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/Sculpturer.java000066400000000000000000000041131202022523300313010ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import groovy.lang.*;
import org.spockframework.util.GroovyRuntimeUtil;

/**
 * Forms a gestalt from its blueprint.
 */
public class Sculpturer extends GroovyObjectSupport {
  private IGestalt $gestalt;

  public void $form(IGestalt gestalt) {
    IBlueprint blueprint = gestalt.getBlueprint();
    if (blueprint == null) return;

    $gestalt = gestalt;
    blueprint.setDelegate(this);
    blueprint.evaluate();
  }

  public Object getProperty(String name) {
    Object thisObject = $gestalt.getBlueprint().getThisObject();
    if (thisObject != null) {
      try {
        return GroovyRuntimeUtil.getProperty(thisObject, name);
      } catch (MissingPropertyException ignored) {}
    }
    return $gestalt.getProperty(name);
  }

  public void setProperty(String name, Object value) {
    Object thisObject = $gestalt.getBlueprint().getThisObject();
    if (thisObject != null) {
      try {
        GroovyRuntimeUtil.setProperty(thisObject, name, value);
        return;
      } catch (MissingPropertyException ignored) {}
    }
    $gestalt.setProperty(name, value);
  }

  public Object invokeMethod(String name, Object args) {
    Object thisObject = $gestalt.getBlueprint().getThisObject();
    if (thisObject != null) {
      try {
        return GroovyRuntimeUtil.invokeMethod(thisObject, name, GroovyRuntimeUtil.asArray(args));
      } catch (MissingMethodException ignored) {}
    }
    return $gestalt.invokeMethod(name, GroovyRuntimeUtil.asArray(args));
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/SetterLikeSlot.java000066400000000000000000000030571202022523300320540ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.Method;
import java.lang.reflect.Type;

import org.spockframework.gentyref.GenericTypeReflector;
import org.spockframework.util.GroovyRuntimeUtil;
import org.spockframework.util.MopUtil;

import groovy.lang.MetaMethod;

public class SetterLikeSlot implements ISlot {
  private final Object owner;
  private final Type ownerType;
  private final MetaMethod setterLikeMethod;

  public SetterLikeSlot(Object owner, Type ownerType, MetaMethod setterLikeMethod) {
    this.owner = owner;
    this.ownerType = ownerType;
    this.setterLikeMethod = setterLikeMethod;
  }

  public Type getType() {
    Method m = MopUtil.methodFor(setterLikeMethod);
    return m != null ? GenericTypeReflector.getExactParameterTypes(m, ownerType)[0] :
        setterLikeMethod.getNativeParameterTypes()[0];
  }

  public void write(Object value) {
    setterLikeMethod.doMethodInvoke(owner, GroovyRuntimeUtil.asArray(value));
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/SetterSlotFactory.java000066400000000000000000000021631202022523300325740ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.lang.reflect.Type;

import org.spockframework.util.GroovyRuntimeUtil;
import org.spockframework.util.MopUtil;

import groovy.lang.MetaProperty;

public class SetterSlotFactory implements ISlotFactory {
  public ISlot create(Object owner, Type ownerType, String name) {
    MetaProperty property = GroovyRuntimeUtil.getMetaClass(owner).getMetaProperty(name);
    return property != null && MopUtil.isWriteable(property) ? new PropertySlot(owner, ownerType, property) : null;
  }
}
SpockConfigurationGestalt.java000066400000000000000000000047421202022523300342150ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/builder/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.builder;

import java.util.List;

import groovy.lang.*;

public class SpockConfigurationGestalt implements IGestalt {
  private final List configurations;
  private final IBlueprint blueprint;
  private final List slotFactories;

  public SpockConfigurationGestalt(List configurations, IBlueprint blueprint,
      List slotFactories) {
    this.configurations = configurations;
    this.blueprint = blueprint;
    this.slotFactories = slotFactories;
  }

  public IBlueprint getBlueprint() {
    return blueprint;
  }

  public Object getProperty(String name) {
    Object config = getConfiguration(name);
    if (config == null) throw new MissingPropertyException("configuration not found");
    return config;
  }

  public void setProperty(String name, Object value) {
    throw new MissingPropertyException("configurations cannot be set directly");
  }

  public Object invokeMethod(String name, Object[] args) {
    if (args.length != 1 || !(args[0] instanceof Closure))
      throw new MissingMethodException(name, this.getClass(), args);

    Object config = getConfiguration(name);
    if (config == null) throw new MissingMethodException(name, this.getClass(), args);

    ClosureBlueprint blueprint = new ClosureBlueprint((Closure)args[0], config);
    IGestalt gestalt = new PojoGestalt(config, config.getClass(), blueprint, slotFactories);
    new Sculpturer().$form(gestalt);
    return null;
  }

  private Object getConfiguration(String name) {
    for (Object config : configurations) {
      String configName = getConfigurationName(config);
      if (configName.equalsIgnoreCase(name)) return config;
    }

    return null;
  }

  private String getConfigurationName(Object config) {
    String className = config.getClass().getSimpleName();
    return className.substring(0, className.length() - "Configuration".length());
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/buildsupport/000077500000000000000000000000001202022523300273755ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/buildsupport/AsmClassReader.java000066400000000000000000000037411202022523300330760ustar00rootroot00000000000000/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.buildsupport;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;

import org.spockframework.util.*;

/**
 * Wrapper for org.objectweb.asm.ClassReader that works with ASM 2.2.3, 3.0, 3.1, and 3.2.
 */
class AsmClassReader {
  private static final Method acceptMethod;
  private static final Object acceptMethodSecondArg;

  private final ClassReader reader;

  static {
    Method m = ReflectionUtil.getMethodBySignature(ClassReader.class, "accept", ClassVisitor.class, boolean.class); // ASM 2.2.3
    Object arg = true;

    if (m == null) {
      m = ReflectionUtil.getMethodBySignature(ClassReader.class, "accept", ClassVisitor.class, int.class); // ASM 3.0 and higher
      arg = 1 | 2 | 4; // ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES
    }

    if (m == null)
      throw new InternalSpockError(
"failed to find method org.objectweb.asm.ClassReader.accept(); seems like an incompatible version of ASM is on the class path");

    acceptMethod = m;
    acceptMethodSecondArg = arg;
  }

  AsmClassReader(InputStream stream) throws IOException {
    reader = new ClassReader(stream);
  }

  void accept(SpecClassFileVisitor visitor) {
    ReflectionUtil.invokeMethod(reader, acceptMethod, visitor, acceptMethodSecondArg);
  }
}
EmptyAnnotationVisitor.java000066400000000000000000000020321202022523300346670ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/buildsupport/*
 * Copyright 2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.buildsupport;

import org.objectweb.asm.AnnotationVisitor;

class EmptyAnnotationVisitor implements AnnotationVisitor {
  public void visit(String s, Object o) {}

  public void visitEnum(String s, String s1, String s2) {}

  public AnnotationVisitor visitAnnotation(String s, String s1) {
    return this;
  }

  public AnnotationVisitor visitArray(String s) {
    return this;
  }

  public void visitEnd() {}
}SpecClassFileFinder.java000066400000000000000000000036261202022523300340000ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/buildsupport/**
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.buildsupport;

import java.io.*;
import java.util.*;

/**
 * Finds all class files below a base directory that contain a runnable spec.
 *
 * @author Peter Niederwieser
 */
public class SpecClassFileFinder {
  public List findRunnableSpecs(File baseDir) throws IOException {
    if (!baseDir.isDirectory())
      throw new FileNotFoundException(String.format("directory %s not found", baseDir));

    List specs = new ArrayList();
    doFindRunnableSpecs(baseDir, specs);
    Collections.sort(specs);
    return specs;
  }

  private void doFindRunnableSpecs(File dir, List foundSpecs) throws IOException {
    for (File path: dir.listFiles())
      if (path.isDirectory())
        doFindRunnableSpecs(path, foundSpecs);
      else if (isRunnableSpec(path))
        foundSpecs.add(path);
  }

  public boolean isRunnableSpec(File file) throws IOException {
    if (!(file.getName().endsWith(".class") && file.isFile()))
      return false;
    
    InputStream stream = new BufferedInputStream(new FileInputStream(file));
    try {
      SpecClassFileVisitor visitor = new SpecClassFileVisitor();
      AsmClassReader reader = new AsmClassReader(stream);
      reader.accept(visitor);
      return visitor.isRunnableSpec();
    } finally {
      stream.close();
    }
  }
}
SpecClassFileVisitor.java000066400000000000000000000037141202022523300342260ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/buildsupport/**
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.buildsupport;

import org.objectweb.asm.*;

class SpecClassFileVisitor implements ClassVisitor {
  private final AnnotationVisitor annVisitor = new EmptyAnnotationVisitor();

  private boolean hasSpecMetadataAnnotation = false;
  private boolean isAbstract;

  public boolean isSpec() {
    return hasSpecMetadataAnnotation;
  }
  
  public boolean isRunnableSpec() {
    return isSpec() && !isAbstract;
  }

  public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
    if ("Lorg/spockframework/runtime/model/SpecMetadata;".equals(desc))
      hasSpecMetadataAnnotation = true;
    return annVisitor;
  }

  public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
    isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
  }

  public void visitSource(String s, String s1) {}

  public void visitOuterClass(String s, String s1, String s2) {}

  public void visitAttribute(Attribute attribute) {}

  public void visitInnerClass(String s, String s1, String s2, int i) {}

  public FieldVisitor visitField(int i, String s, String s1, String s2, Object o) {
    return null; // allowed as per contract
  }

  public MethodVisitor visitMethod(int i, String s, String s1, String s2, String[] strings) {
    return null; // allowed as per contract
  }

  public void visitEnd() {}
}

spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/buildsupport/ant/000077500000000000000000000000001202022523300301575ustar00rootroot00000000000000SpecClassFileSelector.java000066400000000000000000000026311202022523300351260ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/buildsupport/ant/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.buildsupport.ant;

import java.io.File;
import java.io.IOException;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.selectors.BaseExtendSelector;

import org.spockframework.buildsupport.SpecClassFileFinder;

/**
 * Ant selector that selects class files containing Spock specifications.
 */
public class SpecClassFileSelector extends BaseExtendSelector {
  private final SpecClassFileFinder finder = new SpecClassFileFinder();

  @Override
  public boolean isSelected(File baseDir, String filename, File file) {
    try {
      return finder.isRunnableSpec(file);
    } catch (IOException e) {
      String msg = e.getMessage();
      log("Error reading class file '" + filename + (msg == null ? "'" : "': " + msg), Project.MSG_WARN);
      return false;
    }
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/000077500000000000000000000000001202022523300264535ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/AbstractSpecVisitor.java000077500000000000000000000032641202022523300332640ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import org.spockframework.compiler.model.*;

// IDEA: store context (SpecInfo, method, etc.); e.g. by overriding new visitNode method and making it final
public class AbstractSpecVisitor implements ISpecVisitor {
  public void visitSpec(Spec spec) throws Exception {}
  public void visitSpecAgain(Spec spec) throws Exception {}
  public void visitField(Field field) throws Exception {}
  public void visitMethod(Method method) throws Exception {}
  public void visitMethodAgain(Method method) throws Exception {}
  public void visitAnyBlock(Block block) throws Exception {}
  public void visitAnonymousBlock(AnonymousBlock block) throws Exception {}
  public void visitSetupBlock(SetupBlock block) throws Exception {}
  public void visitExpectBlock(ExpectBlock block) throws Exception {}
  public void visitWhenBlock(WhenBlock block) throws Exception {}
  public void visitThenBlock(ThenBlock block) throws Exception {}
  public void visitCleanupBlock(CleanupBlock block) throws Exception {}
  public void visitWhereBlock(WhereBlock block) throws Exception {}
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/AstNodeCache.java000077500000000000000000000065071202022523300316120ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import org.codehaus.groovy.ast.*;

import org.spockframework.mock.*;
import org.spockframework.runtime.SpockRuntime;
import org.spockframework.runtime.ValueRecorder;
import org.spockframework.runtime.model.*;

import spock.lang.*;

/**
 * Provides access to frequently used AST nodes.
 *
 * @author Peter Niederwieser
 */

public class AstNodeCache {
  public final ClassNode SpockRuntime = ClassHelper.makeWithoutCaching(SpockRuntime.class);
  public final ClassNode ValueRecorder = ClassHelper.makeWithoutCaching(ValueRecorder.class);
  public final ClassNode Specification = ClassHelper.makeWithoutCaching(Specification.class);
  
  public final MethodNode SpockRuntime_VerifyCondition =
      SpockRuntime.getDeclaredMethods(org.spockframework.runtime.SpockRuntime.VERIFY_CONDITION).get(0);

  public final MethodNode SpockRuntime_VerifyMethodCondition =
      SpockRuntime.getDeclaredMethods(org.spockframework.runtime.SpockRuntime.VERIFY_METHOD_CONDITION).get(0);

  public final MethodNode ValueRecorder_Reset =
      ValueRecorder.getDeclaredMethods(org.spockframework.runtime.ValueRecorder.RESET).get(0);

  public final MethodNode ValueRecorder_Record =
      ValueRecorder.getDeclaredMethods(org.spockframework.runtime.ValueRecorder.RECORD).get(0);

  public final MethodNode ValueRecorder_RealizeNas =
      ValueRecorder.getDeclaredMethods(org.spockframework.runtime.ValueRecorder.REALIZE_NAS).get(0);

  // annotations and annotation elements
  public final ClassNode SpecMetadata = ClassHelper.makeWithoutCaching(SpecMetadata.class);
  public final ClassNode FieldMetadata = ClassHelper.makeWithoutCaching(FieldMetadata.class);
  public final ClassNode FeatureMetadata = ClassHelper.makeWithoutCaching(FeatureMetadata.class);
  public final ClassNode DataProviderMetadata = ClassHelper.makeWithoutCaching(DataProviderMetadata.class);
  public final ClassNode BlockMetadata = ClassHelper.makeWithoutCaching(BlockMetadata.class);
  public final ClassNode BlockKind = ClassHelper.makeWithoutCaching(BlockKind.class);

  // mocking API
  public final ClassNode MockController = ClassHelper.makeWithoutCaching(MockController.class);
  public final ClassNode InteractionBuilder = ClassHelper.makeWithoutCaching(InteractionBuilder.class);
  public final FieldNode DefaultMockFactory_INSTANCE;

  // external types
  public final ClassNode Throwable = ClassHelper.makeWithoutCaching(Throwable.class);

  public AstNodeCache() {
    ClassNode factory = ClassHelper.makeWithoutCaching(DefaultMockFactory.class);
    // since ClassNode.getField(String) does not trigger class node initialization, we call getFields() first
    factory.getFields();
    DefaultMockFactory_INSTANCE = factory.getField(DefaultMockFactory.INSTANCE_FIELD);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/AstUtil.java000077500000000000000000000355421202022523300307170ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.*;

import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.*;
import org.codehaus.groovy.syntax.Types;
import org.objectweb.asm.Opcodes;

import org.spockframework.lang.Wildcard;
import org.spockframework.runtime.SpockRuntime;
import org.spockframework.util.InternalSpockError;
import org.spockframework.util.Nullable;

import spock.lang.Specification;

/**
 * Utility methods for AST processing.
 * 
 * @author Peter Niederwieser
 */
public abstract class AstUtil {
  /**
   * Tells whether the given node has an annotation of the given type.
   *
   * @param node an AST node
   * @param annotationType an annotation type
   * @return true iff the given node has an annotation of the given type
   */
  public static boolean hasAnnotation(ASTNode node, Class annotationType) {
    return getAnnotation(node, annotationType) != null;
  }

  public static AnnotationNode getAnnotation(ASTNode node, Class annotationType) {
    if (!(node instanceof AnnotatedNode)) return null;

    AnnotatedNode annotated = (AnnotatedNode)node;
    @SuppressWarnings("unchecked")
    List annotations = annotated.getAnnotations();
    for (AnnotationNode a : annotations)
      if (a.getClassNode().getName().equals(annotationType.getName())) return a;
    return null;
  }

  /**
   * Returns a list of statements of the given method. Modifications to the returned list
   * will affect the method's statements.
   *
   * @param method a method (node)
   * @return a list of statements of the given method
   */
  @SuppressWarnings("unchecked")
  public static List getStatements(MethodNode method) {
    Statement code = method.getCode();
    if (!(code instanceof BlockStatement)) { // null or single statement
      BlockStatement block = new BlockStatement();
      if (code != null) block.addStatement(code);
      method.setCode(block);
    }
    return ((BlockStatement)method.getCode()).getStatements();
  }

  @SuppressWarnings("unchecked")
  public static List getStatements(ClosureExpression closure) {
    BlockStatement blockStat = (BlockStatement)closure.getCode();
    return blockStat == null ?
        Collections. emptyList() : // it's not possible to add any statements to such a ClosureExpression, so immutable list is OK
        blockStat.getStatements();
  }

  public static boolean isMethodInvocation(Expression expr) {
    return expr instanceof MethodCallExpression
        || expr instanceof StaticMethodCallExpression;
  }

  public static Expression getInvocationTarget(Expression expr) {
    if (expr instanceof PropertyExpression)
      return ((PropertyExpression)expr).getObjectExpression();
    if (expr instanceof MethodCallExpression)
      return ((MethodCallExpression)expr).getObjectExpression();
    if (expr instanceof StaticMethodCallExpression)
      return new ClassExpression(((StaticMethodCallExpression)expr).getOwnerType());

    return null;
  }

  public static boolean isWildcardRef(Expression expr) {
    VariableExpression varExpr = AstUtil.asInstance(expr, VariableExpression.class);
    if (varExpr == null || !varExpr.getName().equals(Wildcard.INSTANCE.toString())) return false;

    Variable accessedVar = varExpr.getAccessedVariable();
    if (!(accessedVar instanceof FieldNode)) return false;

    return ((FieldNode) accessedVar).getOwner().getName().equals(Specification.class.getName());
  }

  public static boolean isJavaIdentifier(String id) {
    if (id == null || id.length() == 0
        || !Character.isJavaIdentifierStart(id.charAt(0)))
      return false;

    for (int i = 1; i < id.length(); i++)
      if (!Character.isJavaIdentifierPart(id.charAt(i)))
        return false;

    return true;
  }

  public static  T getExpression(Statement stat, Class type) {
    ExpressionStatement exprStat = asInstance(stat, ExpressionStatement.class);
    if (exprStat == null) return null;
    return asInstance(exprStat.getExpression(), type);
  }

  @SuppressWarnings("unchecked")
  public static @Nullable  T asInstance(Object obj, Class type) {
    return type.isInstance(obj) ? (T) obj : null;
  }

  public static boolean isSynthetic(MethodNode method) {
    return method.isSynthetic() || (method.getModifiers() & Opcodes.ACC_SYNTHETIC) != 0;
  }

  /**
   * Tells if the source position for the given AST node is plausible.
   * Does not imply that the source position is correct.
   *
   * @param node an AST node
   * @return true iff the AST node has a plausible source position
   */
  public static boolean hasPlausibleSourcePosition(ASTNode node) {
    return node.getLineNumber() > 0 && node.getLastLineNumber() >= node.getLineNumber()
        && node.getColumnNumber() > 0 && node.getLastColumnNumber() > node.getColumnNumber();
  }

  // Note: The returned list may contain SpreadExpression's,
  // which can't be used outside an ArgumentListExpression.
  // To pass an argument list to the Groovy or Spock runtime,
  // use this method together with AstUtil.toArgumentArray().
  public static List getArguments(Expression expr) {
    if (expr instanceof MethodCallExpression)
      return getArguments((MethodCallExpression)expr);
    else if (expr instanceof StaticMethodCallExpression)
      return getArguments((StaticMethodCallExpression)expr);
    else return null;
  }
  
  @SuppressWarnings("unchecked")
  public static List getArguments(MethodCallExpression expr) {
    // MethodCallExpression.getArguments() may return an ArgumentListExpression,
    // a TupleExpression that wraps a NamedArgumentListExpression,
    // or (at least in 1.6) a NamedArgumentListExpression

    if (expr.getArguments() instanceof NamedArgumentListExpression)
      // return same result as for NamedArgumentListExpression wrapped in TupleExpression
      return Collections.singletonList(expr.getArguments());
    
    return ((TupleExpression) expr.getArguments()).getExpressions();
  }

  @SuppressWarnings("unchecked")
  public static List getArguments(StaticMethodCallExpression expr) {
    // see comments in getArguments(MethodCallExpression)

    if (expr.getArguments() instanceof NamedArgumentListExpression)
      return Collections.singletonList(expr.getArguments());

    return ((TupleExpression)expr.getArguments()).getExpressions();
  }

  /**
   * Turns an argument list obtained from AstUtil.getArguments() into an Object[] array
   * suitable to be passed to InvokerHelper or SpockRuntime. The main challenge is
   * to handle SpreadExpression's correctly.
   */
  public static Expression toArgumentArray(List argList, IRewriteResources resources) {
    List normalArgs = new ArrayList();
    List spreadArgs = new ArrayList();
    List spreadPositions = new ArrayList();

    for (int i = 0; i < argList.size(); i++) {
      Expression arg = argList.get(i);
      if (arg instanceof SpreadExpression) {
        spreadArgs.add(((SpreadExpression) arg).getExpression());
        spreadPositions.add(new ConstantExpression(i));
      } else {
        normalArgs.add(arg);
      }
    }

    if (spreadArgs.isEmpty())
      return new ArrayExpression(ClassHelper.OBJECT_TYPE, argList);

    return new MethodCallExpression(
        new ClassExpression(resources.getAstNodeCache().SpockRuntime),
        new ConstantExpression(SpockRuntime.DESPREAD_LIST),
        new ArgumentListExpression(
            new ArrayExpression(ClassHelper.OBJECT_TYPE, normalArgs),
            new ArrayExpression(ClassHelper.OBJECT_TYPE, spreadArgs),
            new ArrayExpression(ClassHelper.int_TYPE, spreadPositions)
        ));
  }

  public static boolean isBuiltinMemberAssignmentOrCall(Expression expr, String methodName, int minArgs, int maxArgs) {
    return expr instanceof BinaryExpression
        && isBuiltinMemberAssignment((BinaryExpression)expr, methodName, minArgs, maxArgs)
        || expr instanceof MethodCallExpression
        && isBuiltinMemberCall((MethodCallExpression) expr, methodName, minArgs, maxArgs);
  }

  public static boolean isBuiltinMemberAssignment(BinaryExpression expr, String methodName, int minArgs, int maxArgs) {
    return expr.getOperation().getType() == Types.ASSIGN
        && isBuiltinMemberAssignmentOrCall(expr.getRightExpression(), methodName, minArgs, maxArgs);
  }

  public static boolean isBuiltinMemberCall(Expression expr, String methodName, int minArgs, int maxArgs) {
    return expr instanceof MethodCallExpression
        && isBuiltinMemberCall((MethodCallExpression)expr, methodName, minArgs, maxArgs);
  }

  // call of the form "this.(...)" or "(...)"
  public static boolean isBuiltinMemberCall(MethodCallExpression expr, String methodName, int minArgs, int maxArgs) {
    return
        (isThisExpression(expr.getObjectExpression()) || isSuperExpression(expr.getObjectExpression()))
        && methodName.equals(expr.getMethodAsString()) // getMethodAsString() may return null
        && getArguments(expr).size() >= minArgs
        && getArguments(expr).size() <= maxArgs;
  }

  public static void expandBuiltinMemberAssignmentOrCall(Expression builtinMemberAssignmentOrCall, Expression... additionalArgs)
      throws InvalidSpecCompileException {
    if (builtinMemberAssignmentOrCall instanceof BinaryExpression)
      expandBuiltinMemberAssignment((BinaryExpression)builtinMemberAssignmentOrCall, additionalArgs);
    else
      expandBuiltinMemberCall(builtinMemberAssignmentOrCall, additionalArgs);
  }

  /*
   * Expands an assignment of the form "(def) x = builtinMethodCall(...)", where x is a field or local variable.
   * Assumes isBuiltinMemberAssignment(...).
   */
  public static void expandBuiltinMemberAssignment(BinaryExpression builtinMemberAssignment, Expression... additionalArgs)
      throws InvalidSpecCompileException {
    Expression builtinMemberCall = builtinMemberAssignment.getRightExpression();
    String name = getInferredName(builtinMemberAssignment);
    Expression type = getType(builtinMemberCall, getInferredType(builtinMemberAssignment));

    doExpandBuiltinMemberCall(builtinMemberCall, name, type, additionalArgs);
  }

  public static void expandBuiltinMemberCall(Expression builtinMemberCall, Expression... additionalArgs)
      throws InvalidSpecCompileException {
    doExpandBuiltinMemberCall(builtinMemberCall, null, getType(builtinMemberCall, null), additionalArgs);
  }

  private static Expression getType(Expression builtinMemberCall, Expression inferredType)
      throws InvalidSpecCompileException {
    List args = AstUtil.getArguments(builtinMemberCall);
    assert args != null;

    if (args.isEmpty()) {
      if (inferredType == null)
        // TODO: improve error message (not clear that it originates from Mock() or thrown())
        throw new InvalidSpecCompileException(builtinMemberCall, "Type cannot be inferred; please specify one explicitely");
      return inferredType;
    }

    return args.get(0);
  }

  private static String getInferredName(BinaryExpression builtinMemberAssignment) {
    Expression left = builtinMemberAssignment.getLeftExpression();
    if (left instanceof Variable) return ((Variable)left).getName();
    if (left instanceof FieldExpression) return ((FieldExpression)left).getFieldName();
    return null;
  }

  private static ClassExpression getInferredType(BinaryExpression builtinMemberAssignment) {
    ClassNode type = builtinMemberAssignment.getLeftExpression().getType();
    return type == null || type == ClassHelper.DYNAMIC_TYPE ?
        null : new ClassExpression(type);
  }

  private static void doExpandBuiltinMemberCall(Expression builtinMemberCall, String name,
      Expression type, Expression... additionalArgs) {
    checkIsSafeToMutateArgs(builtinMemberCall);

    List args = getArguments(builtinMemberCall);
    args.clear();
    args.add(type);
    args.add(new ConstantExpression(name));
    args.addAll(Arrays.asList(additionalArgs));
  }

  private static void checkIsSafeToMutateArgs(Expression methodCall) {
    Expression args = ((MethodCallExpression)methodCall).getArguments();

    if (args == ArgumentListExpression.EMPTY_ARGUMENTS)
      throw new InternalSpockError("checkIsSafeToMutateArgs");
  }

  @Nullable
  public static Expression getAssertionMessage(AssertStatement stat) {
    Expression msg = stat.getMessageExpression();
    if (msg == null) return null; // should not happen
    if (!(msg instanceof ConstantExpression)) return msg;
    return ((ConstantExpression) msg).isNullExpression() ? null : msg;
  }

  public static boolean isThisExpression(Expression expr) {
    return expr instanceof VariableExpression
        && ((VariableExpression)expr).isThisExpression();
  }

  public static boolean isSuperExpression(Expression expr) {
    return expr instanceof VariableExpression
        && ((VariableExpression)expr).isSuperExpression();
  }

  public static void setVisibility(MethodNode method, int visibility) {
    int modifiers = method.getModifiers();
    modifiers &= ~(Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
    method.setModifiers(modifiers | visibility);
  }

  public static int getVisibility(FieldNode field) {
    return field.getModifiers() & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);  
  }

  public static void setVisibility(FieldNode field, int visibility) {
    int modifiers = field.getModifiers();
    modifiers &= ~(Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
    field.setModifiers(modifiers | visibility);
  }

  public static boolean isJointCompiled(ClassNode clazz) {
    return clazz.getModule().getUnit().getConfig().getJointCompilationOptions() != null;
  }

  public static MethodCallExpression createDirectMethodCall(Expression target, MethodNode method, Expression arguments) {
    MethodCallExpression result = new MethodCallExpression(target, method.getName(), arguments);
    result.setMethodTarget(method);
    result.setImplicitThis(false); // see http://groovy.329449.n5.nabble.com/Problem-with-latest-2-0-beta-3-snapshot-and-Spock-td5496353.html
    return result;
  }

  public static void deleteMethod(ClassNode clazz, MethodNode method) {
    // as of 1.8.6, this is the best possible implementation
    clazz.getMethods().remove(method);
    clazz.getDeclaredMethods(method.getName()).remove(method);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/ConditionRewriter.java000077500000000000000000000525771202022523300330130ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.*;

import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.*;
import org.codehaus.groovy.classgen.BytecodeExpression;
import org.codehaus.groovy.syntax.Types;

import org.spockframework.runtime.ValueRecorder;
import org.spockframework.util.*;

// NOTE: currently some conversions reference old expression objects rather than copying them;
// this can potentially lead to aliasing problems (e.g. for Condition.originalExpression)
// background: it was found that transformExpression() cannot be used to copy all expressions
// (some implementations just return original expression); as a consequence, the design goal
// of copying everything was dropped for the time being

// IDEA: record type literals as class objects (since we also record other literals)
// but since a type literal cannot be evaluated, we would have to record class object
// before/after evaluating next/previous expression

/**
 * Rewrites explicit ("assert x > 3") and implicit ("x > 3") condition
 * statements. Replacing the original statement with the rewritten one is up
 * to clients.
 *
 * @author Peter Niederwieser
 */
public class ConditionRewriter extends AbstractExpressionConverter {
  private final IRewriteResources resources;

  private int recordCount = 0;
  private boolean doNotRecordNextConstant = false;

  private ConditionRewriter(IRewriteResources resources) {
    this.resources = resources;
  }

  public static Statement rewriteExplicitCondition(AssertStatement stat, IRewriteResources resources) {
    ConditionRewriter rewriter = new ConditionRewriter(resources);
    Expression message = AstUtil.getAssertionMessage(stat);
    return rewriter.rewriteCondition(stat, stat.getBooleanExpression().getExpression(), message, true);
  }

  public static Statement rewriteImplicitCondition(ExpressionStatement stat, IRewriteResources resources) {
    ConditionRewriter rewriter = new ConditionRewriter(resources);
    return rewriter.rewriteCondition(stat, stat.getExpression(), null, false);
  }

  public void visitMethodCallExpression(MethodCallExpression expr) {
    // at runtime, condition AST is only parsed up to phase conversion,
    // and hence looks differently in cases where groovyc inserts ".call"
    // in phase semantic analysis; we need to compensate for that
    // (in other cases, ".call" is only inserted after transform has
    // run, and hence we don't need to compensate)
    boolean objectExprSeenAsMethodNameAtRuntime =
        !expr.isImplicitThis()
        && expr.getObjectExpression() instanceof VariableExpression
        && "call".equals(expr.getMethodAsString())
        && (!AstUtil.hasPlausibleSourcePosition(expr.getMethod()) // before GROOVY-4344 fix
            || (expr.getMethod().getColumnNumber() == expr.getObjectExpression().getColumnNumber())); // after GROOVY-4344 fix

    MethodCallExpression conversion =
        new MethodCallExpression(
            expr.isImplicitThis() ?
                expr.getObjectExpression() :
                convert(expr.getObjectExpression()),
            objectExprSeenAsMethodNameAtRuntime ?
                expr.getMethod() :
                convert(expr.getMethod()),
            convert(expr.getArguments()));

    conversion.setSafe(expr.isSafe());
    conversion.setSpreadSafe(expr.isSpreadSafe());
    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  // only used for statically imported methods called by their simple name
  public void visitStaticMethodCallExpression(StaticMethodCallExpression expr) {
    StaticMethodCallExpression conversion =
        new StaticMethodCallExpression(
            expr.getOwnerType(),
            recordNa(expr.getMethod()),
            convert(expr.getArguments()));

    conversion.setSourcePosition(expr);
    conversion.setMetaMethod(expr.getMetaMethod());
    result = record(conversion);
  }

  public void visitBytecodeExpression(BytecodeExpression expr) {
    unsupported(); // cannot occur in condition
  }

  @SuppressWarnings("unchecked")
  public void visitArgumentlistExpression(ArgumentListExpression expr) {
    ArgumentListExpression conversion =
        new ArgumentListExpression(
            convertAll(expr.getExpressions()));

    conversion.setSourcePosition(expr);
    result = recordNa(conversion);
  }

  public void visitPropertyExpression(PropertyExpression expr) {
    PropertyExpression conversion =
        new PropertyExpression(
            expr.isImplicitThis() ?
                expr.getObjectExpression() :
                convert(expr.getObjectExpression()),
            expr.getProperty(),
            expr.isSafe());

    conversion.setSourcePosition(expr);
    conversion.setSpreadSafe(expr.isSpreadSafe());
    conversion.setStatic(expr.isStatic());
    conversion.setImplicitThis(expr.isImplicitThis());
    result = record(conversion);
  }

  public void visitAttributeExpression(AttributeExpression expr) {
    AttributeExpression conversion =
        new AttributeExpression(
            expr.isImplicitThis() ?
                expr.getObjectExpression() :
                convert(expr.getObjectExpression()),
            expr.getProperty(),
            expr.isSafe());

    conversion.setSourcePosition(expr);
    conversion.setSpreadSafe(expr.isSpreadSafe());
    conversion.setStatic(expr.isStatic());
    conversion.setImplicitThis(expr.isImplicitThis());
    result = record(conversion);
  }

  // as of Groovy 1.7.3, used for:
  // - references to statically imported fields
  // - compiler-generated code
  // - code generated by some transforms
  public void visitFieldExpression(FieldExpression expr) {
    result = record(expr);
  }

  public void visitMethodPointerExpression(MethodPointerExpression expr) {
    MethodPointerExpression conversion =
        new MethodPointerExpression(
            convert(expr.getExpression()),
            convert(expr.getMethodName()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitVariableExpression(VariableExpression expr) {
    if (expr instanceof OldValueExpression) {
      Expression originalExpr = ((OldValueExpression)expr).getOrginalExpression();
      originalExpr.visit(this); // just to count up recordCount and produce the correct number of N/A values at runtime
      doNotRecordNextConstant = true; // we know Specification.old() has been rewritten to include a dummy as second argument
      result = expr;
      return;
    }

    result = record(expr);
  }

  public void visitDeclarationExpression(DeclarationExpression expr) {
    unsupported(); // cannot occur in condition
  }

  public void visitBinaryExpression(BinaryExpression expr) {
    BinaryExpression conversion =
        new BinaryExpression(
            Types.ofType(expr.getOperation().getType(), Types.ASSIGNMENT_OPERATOR) ?
                // prevent lvalue from getting turned into record(lvalue), which can no longer be assigned to
                convertAndRecordNa(expr.getLeftExpression()) :
                convert(expr.getLeftExpression()),
            expr.getOperation(),
            convert(expr.getRightExpression()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitConstantExpression(ConstantExpression expr) {
    if (doNotRecordNextConstant) {
      doNotRecordNextConstant = false;
      result = expr;
      return;
    }

    result = record(expr);
  }

  public void visitClassExpression(ClassExpression expr) {
    result = expr;
    // ensure this isn't the class part of a class member access where the member has been
    // imported statically and the class is therefore not present in the
    // code; instead of looking through imports, we try to infer this from
    // source position information
    if (!AstUtil.hasPlausibleSourcePosition(expr)) return;
    // because runtime condition parsing only proceeds up to compiler phase
    // CONVERSION, this ClassExpression will be seen as a VariableExpression
    // (e.g. "Type"), or a VariableExpression nested within one or more PropertyExpressions
    // (e.g. "org.Type", "Type.class", "org.Type.class");
    // therefore we have to provide one N/A value for every part of the class name
    String text = resources.getSourceText(expr);
    // NOTE: remove guessing (text == null) once underlying Groovy problem has been fixed
    recordCount += text == null ? 1 : TextUtil.countOccurrences(text, '.') + 1;
  }

  public void visitUnaryMinusExpression(UnaryMinusExpression expr) {
    UnaryMinusExpression conversion =
        new UnaryMinusExpression(
            convert(expr.getExpression()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitUnaryPlusExpression(UnaryPlusExpression expr) {
    UnaryPlusExpression conversion =
        new UnaryPlusExpression(
            convert(expr.getExpression()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitBitwiseNegationExpression(BitwiseNegationExpression expr) {
    BitwiseNegationExpression conversion =
        new BitwiseNegationExpression(
            convert(expr.getExpression()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitCastExpression(CastExpression expr) {
    CastExpression conversion =
        new CastExpression(
            expr.getType(),
            convert(expr.getExpression()),
            expr.isIgnoringAutoboxing());

    conversion.setSourcePosition(expr);
    conversion.setCoerce(expr.isCoerce());
    result = record(conversion);
  }

  public void visitClosureListExpression(ClosureListExpression expr) {
    unsupported(); // cannot occur in condition
  }

  public void visitNotExpression(NotExpression expr) {
    NotExpression conversion =
        new NotExpression(
            convert(expr.getExpression()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  @SuppressWarnings("unchecked")
  public void visitListExpression(ListExpression expr) {
    ListExpression conversion =
        new ListExpression(
            convertAll(expr.getExpressions()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitRangeExpression(RangeExpression expr) {
    RangeExpression conversion =
        new RangeExpression(
            convert(expr.getFrom()),
            convert(expr.getTo()),
            expr.isInclusive());

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  @SuppressWarnings("unchecked")
  public void visitMapExpression(MapExpression expr) {
    boolean namedArgumentListExpr = expr instanceof NamedArgumentListExpression;

    MapExpression conversion =
        namedArgumentListExpr ?
            new NamedArgumentListExpression(
                (List) convertAll(expr.getMapEntryExpressions())) :
            new MapExpression(
                (List) convertAll(expr.getMapEntryExpressions()));

    conversion.setSourcePosition(expr);
    result = namedArgumentListExpr ? recordNa(conversion) : record(conversion);
  }

  public void visitMapEntryExpression(MapEntryExpression expr) {
    MapEntryExpression conversion =
        new MapEntryExpression(
            convert(expr.getKeyExpression()),
            convert(expr.getValueExpression()));

    conversion.setSourcePosition(expr);
    result = recordNa(conversion);
  }

  public void visitConstructorCallExpression(ConstructorCallExpression expr) {
    ConstructorCallExpression conversion =
        new ConstructorCallExpression(
            expr.getType(),
            convert(expr.getArguments()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  @SuppressWarnings("unchecked")
  public void visitGStringExpression(GStringExpression expr) {
    GStringExpression conversion =
        new GStringExpression(
            expr.getText(),
            expr.getStrings(),
            convertAll(expr.getValues()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  @SuppressWarnings("unchecked")
  public void visitArrayExpression(ArrayExpression expr) {
    ArrayExpression conversion =
        new ArrayExpression(
            expr.getElementType(),
            convertAll(expr.getExpressions()),
            convertAll(expr.getSizeExpression()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitSpreadExpression(SpreadExpression expr) {
    SpreadExpression conversion =
        new SpreadExpression(
            convert(expr.getExpression()));

    conversion.setSourcePosition(expr);
    result = recordNa(conversion);
  }

  public void visitSpreadMapExpression(SpreadMapExpression expr) {
    // to not record the underlying MapExpression twice, we do nothing here
    // see http://jira.codehaus.org/browse/GROOVY-3421
    result = recordNa(expr);
  }

  public void visitTernaryExpression(TernaryExpression expr) {
    TernaryExpression conversion =
        new TernaryExpression(
            convertCompatibly(expr.getBooleanExpression()),
            convert(expr.getTrueExpression()),
            convert(expr.getFalseExpression()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitShortTernaryExpression(ElvisOperatorExpression expr) {
    ElvisOperatorExpression conversion =
        new ElvisOperatorExpression(
            convert(expr.getTrueExpression()),
            convert(expr.getFalseExpression()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitPrefixExpression(PrefixExpression expr) {
    PrefixExpression conversion =
        new PrefixExpression(
            expr.getOperation(),
            convertAndRecordNa(expr.getExpression()));

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitPostfixExpression(PostfixExpression expr) {
    PostfixExpression conversion =
        new PostfixExpression(
            convertAndRecordNa(expr.getExpression()),
            expr.getOperation());

    conversion.setSourcePosition(expr);
    result = record(conversion);
  }

  public void visitBooleanExpression(BooleanExpression expr) {
    BooleanExpression conversion =
        new BooleanExpression(
            convert(expr.getExpression())
        );

    conversion.setSourcePosition(expr);
    result = recordNa(conversion);
  }

  public void visitClosureExpression(ClosureExpression expr) {
    result = record(expr);
  }

  // used in the following places:
  // - LHS of multi-assignment
  // - wraps NamedArgumentListExpression (not always in 1.6.x)
  @SuppressWarnings("unchecked")
  public void visitTupleExpression(TupleExpression expr) {
    TupleExpression conversion =
        new TupleExpression(
            // prevent each lvalue from getting turned into record(lvalue),
            // which no longer is an lvalue
            convertAllAndRecordNa(expr.getExpressions()));

    conversion.setSourcePosition(expr);
    result = recordNa(conversion);
  }

  private Expression record(Expression expr) {
    return AstUtil.createDirectMethodCall(
        new VariableExpression("$spock_valueRecorder"),
        resources.getAstNodeCache().ValueRecorder_Record,
        new ArgumentListExpression(new ConstantExpression(recordCount++), expr));
  }

  private Expression realizeNas(Expression expr) {
    return AstUtil.createDirectMethodCall(
        new VariableExpression("$spock_valueRecorder"),
        resources.getAstNodeCache().ValueRecorder_RealizeNas,
        new ArgumentListExpression(new ConstantExpression(recordCount), expr));
  }

  private  T recordNa(T expr) {
    recordCount++;
    return expr;
  }

  private Expression convertAndRecordNa(Expression expr) {
    return unrecord(convert(expr));
  }

  private List convertAllAndRecordNa(List expressions) {
    List conversions = new ArrayList(expressions.size());
    for (Expression expr : expressions) conversions.add(convertAndRecordNa(expr));
    return conversions;
  }

  @SuppressWarnings("unchecked")
  private  T convertCompatibly(T expr) {
    Expression conversion = convert(expr);
    Assert.that(expr.getClass().isInstance(conversion));
    return (T) conversion;
  }

  // unrecord(record(expr)) == expr
  // does not change recordCount, resulting in one N/A value at runtime
  private Expression unrecord(Expression expr) {
    if (!(expr instanceof MethodCallExpression)) return expr;
    MethodCallExpression methodExpr = (MethodCallExpression) expr;
    Expression targetExpr = methodExpr.getObjectExpression();
    if (!(targetExpr instanceof VariableExpression)) return expr;
    VariableExpression var = (VariableExpression)targetExpr;
    if (!var.getName().equals("$spock_valueRecorder")) return expr;
    if(!methodExpr.getMethodAsString().equals(ValueRecorder.RECORD)) return expr;
    return ((ArgumentListExpression)methodExpr.getArguments()).getExpression(1);
  }

  private Statement rewriteCondition(Statement conditionStat, Expression conditionExpr, Expression message, boolean explicit) {
    Statement result = new ExpressionStatement(rewriteCondition(conditionExpr, message, explicit));
    result.setSourcePosition(conditionStat);
    return result;
  }

  private Expression rewriteCondition(Expression expr, Expression message, boolean explicit) {
    // method conditions with spread operator are not lifted because MOP doesn't support spreading
    if (expr instanceof MethodCallExpression && !((MethodCallExpression) expr).isSpreadSafe())
      return rewriteMethodCondition((MethodCallExpression) expr, message, explicit);

    if (expr instanceof StaticMethodCallExpression)
      return rewriteStaticMethodCondition((StaticMethodCallExpression) expr, message, explicit);

    return rewriteOtherCondition(expr, message);
  }

  private Expression rewriteMethodCondition(MethodCallExpression condition, Expression message, boolean explicit) {
    MethodCallExpression rewritten = message == null ?
        (MethodCallExpression) unrecord(convert(condition)) : condition;

    List args = new ArrayList();
    args.add(rewritten.getObjectExpression());
    args.add(rewritten.getMethod());
    args.add(AstUtil.toArgumentArray(AstUtil.getArguments(rewritten), resources));
    // rewriting has produced N/A's that haven't been realized yet, so do that now
    args.add(realizeNas(new ConstantExpression(rewritten.isSafe())));
    args.add(new ConstantExpression(explicit));

    return rewriteToSpockRuntimeCall(resources.getAstNodeCache().SpockRuntime_VerifyMethodCondition, condition, message, args);
  }

  private Expression rewriteStaticMethodCondition(StaticMethodCallExpression condition, Expression message,
      boolean explicit) {
    StaticMethodCallExpression rewritten = message == null ?
        (StaticMethodCallExpression) unrecord(convert(condition)) : condition;

    List args = new ArrayList();
    args.add(new ClassExpression(rewritten.getOwnerType()));
    args.add(new ConstantExpression(rewritten.getMethod()));
    args.add(AstUtil.toArgumentArray(AstUtil.getArguments(rewritten), resources));
    // rewriting has produced N/A's that haven't been realized yet, so do that now
    args.add(realizeNas(ConstantExpression.FALSE));
    args.add(new ConstantExpression(explicit));

    return rewriteToSpockRuntimeCall(resources.getAstNodeCache().SpockRuntime_VerifyMethodCondition, condition, message, args);
  }

  private Expression rewriteOtherCondition(Expression condition, Expression message) {
    Expression rewritten = message == null ? convert(condition) : condition;

    return rewriteToSpockRuntimeCall(resources.getAstNodeCache().SpockRuntime_VerifyCondition,
        condition, message, Collections.singletonList(rewritten));
  }

  private Expression rewriteToSpockRuntimeCall(MethodNode method, Expression condition, Expression message,
      List additionalArgs) {
    List args = new ArrayList();

    MethodCallExpression result = AstUtil.createDirectMethodCall(
        new ClassExpression(resources.getAstNodeCache().SpockRuntime), method,
        new ArgumentListExpression(args));

    args.add(message == null ?
        AstUtil.createDirectMethodCall(
            new VariableExpression("$spock_valueRecorder"),
            resources.getAstNodeCache().ValueRecorder_Reset,
            ArgumentListExpression.EMPTY_ARGUMENTS) :
        new ConstantExpression(null));
    args.add(new ConstantExpression(resources.getSourceText(condition)));
    args.add(new ConstantExpression(condition.getLineNumber()));
    args.add(new ConstantExpression(condition.getColumnNumber()));
    // the following means that "assert x, exprEvaluatingToNull" will be
    // treated the same as "assert x"; but probably it doesn't matter too much
    args.add(message == null ? new ConstantExpression(null) : message);
    args.addAll(additionalArgs);

    result.setSourcePosition(condition);
    return result;
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/DeepStatementRewriter.java000066400000000000000000000156061202022523300336140ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.List;

import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.*;

import org.spockframework.compiler.model.*;
import org.spockframework.util.Identifiers;

/**
 * Walks the statement and expression tree to:
 * - rewrite explicit conditions,
 * - rewrite interactions,
 * - rewrite core language primitives (members of class Specification)
 * - Forbid
 * 
 * Also records whether conditions and interactions were found.
 *
 * @author Peter Niederwieser
 */
public class DeepStatementRewriter extends StatementReplacingVisitorSupport {
  private final IRewriteResources resources;

  private boolean conditionFound = false;
  private boolean interactionFound = false;
  // scope for the current closure; null if not in a closure
  private VariableScope closureScope;

  public DeepStatementRewriter(IRewriteResources resources) {
    this.resources = resources;
  }
  
  public boolean isConditionFound() {
    return conditionFound;
  }

  public boolean isInteractionFound() {
    return interactionFound;
  }

  public void visitBlock(Block block) {
    replaceAll(block.getAst());
  }
  
  @Override
  public void visitAssertStatement(AssertStatement stat) {
    super.visitAssertStatement(stat);
    conditionFound = true;
    replaceVisitedStatementWith(
        ConditionRewriter.rewriteExplicitCondition(stat, resources));
  }

  @Override
  public void visitExpressionStatement(ExpressionStatement stat) {
    super.visitExpressionStatement(stat);

    Statement rewritten = new InteractionRewriter(resources).rewrite(stat);
    if (rewritten == null) return;
    
    interactionFound = true;
    replaceVisitedStatementWith(rewritten);
  }

  @Override
  public void visitClosureExpression(ClosureExpression expr) {
    // because a closure might be executed asynchronously, its conditions
    // and interactions are handled independently from the conditions
    // and interactions of the closure's context

    boolean oldConditionFound = conditionFound;
    boolean oldInteractionFound = interactionFound;
    VariableScope oldClosureScope = closureScope;
    conditionFound = false;
    interactionFound = false;
    closureScope = expr.getVariableScope();

    fixupParameters(closureScope, true);
    super.visitClosureExpression(expr);
    if (conditionFound) defineValueRecorder(expr);

    conditionFound = oldConditionFound;
    interactionFound = oldInteractionFound;
    closureScope = oldClosureScope;
  }

  private void defineValueRecorder(ClosureExpression expr) {
    resources.defineValueRecorder(AstUtil.getStatements(expr));
  }

  private void fixupParameters(VariableScope scope, boolean isClosureScope) {
    Method method = resources.getCurrentMethod();
    if (!(method instanceof FeatureMethod)) return;

    // if this is a parameterized feature method w/o explicit parameter list,
    // update any references to parameterization variables
    // (parameterization variables used to be free variables,
    // but have been changed to method parameters by WhereBlockRewriter)
    for (Parameter param : method.getAst().getParameters()) {
      Variable var = scope.getReferencedClassVariable(param.getName());
      if (var instanceof DynamicVariable) {
        scope.removeReferencedClassVariable(param.getName());
        scope.putReferencedLocalVariable(param);
        if (isClosureScope)
          param.setClosureSharedVariable(true);
      }
    }
  }

  @Override
  public void visitBlockStatement(BlockStatement stat) {
    super.visitBlockStatement(stat);
    fixupParameters(stat.getVariableScope(), false);
  }

  @Override
  public void visitDeclarationExpression(DeclarationExpression expr) {
    visitBinaryExpression(expr);
  }

  @Override
  public void visitBinaryExpression(BinaryExpression expr) {
    if (AstUtil.isBuiltinMemberAssignment(expr, Identifiers.MOCK, 0, 1))
      try {
        AstUtil.expandBuiltinMemberAssignment(expr, resources.getMockControllerRef());
      } catch (InvalidSpecCompileException e) {
        resources.getErrorReporter().error(e);
        return;
      }

    // only descend after we have expanded Specification.Mock so that it's not
    // expanded by visit(Static)MethodCallExpression instead
    super.visitBinaryExpression(expr);
  }

  @Override
  public void visitMethodCallExpression(MethodCallExpression expr) {
    super.visitMethodCallExpression(expr);
    forbidUseOfSuperInFixtureMethod(expr);
    handleMockAndOldCalls(expr);
  }

  // Forbid the use of super.foo() in fixture method foo,
  // because it is most likely a mistake (user thinks he is overriding
  // the base method and doesn't know that it will be run automatically)
  private void forbidUseOfSuperInFixtureMethod(MethodCallExpression expr) {
    Method currMethod = resources.getCurrentMethod();
    Expression target = expr.getObjectExpression();
    
    if (currMethod instanceof FixtureMethod
        && target instanceof VariableExpression
        && ((VariableExpression)target).isSuperExpression()
        && currMethod.getName().equals(expr.getMethodAsString())) {
      resources.getErrorReporter().error(expr,
        "A base class fixture method should not be called explicitely " +
        "because it is always run automatically by the framework");
    }
  }

  private void handleMockAndOldCalls(Expression expr) {
    if (AstUtil.isBuiltinMemberCall(expr, Identifiers.MOCK, 0, 1))
      handleMockCall(expr);
    else if (AstUtil.isBuiltinMemberCall(expr, Identifiers.OLD, 1, 1))
      handleOldCall(expr);
  }

  private void handleMockCall(Expression expr) {
    try {
      AstUtil.expandBuiltinMemberCall(expr, resources.getMockControllerRef());
    } catch (InvalidSpecCompileException e) {
      resources.getErrorReporter().error(e);
    }
  }

  private void handleOldCall(Expression expr) {
    if (!(resources.getCurrentBlock() instanceof ThenBlock)) {
      resources.getErrorReporter().error(expr, "old() may only be used in a 'then' block");
      return;
    }

    List args = AstUtil.getArguments(expr);
    VariableExpression oldValue = resources.captureOldValue(args.get(0));
    args.set(0, oldValue);
    args.add(ConstantExpression.FALSE); // dummy arg

    if (closureScope != null) {
      oldValue.setClosureSharedVariable(true);
      closureScope.putReferencedLocalVariable(oldValue);
    }
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/ErrorReporter.java000066400000000000000000000045521202022523300321400ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.io.PrintWriter;
import java.io.StringWriter;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.control.*;
import org.codehaus.groovy.control.messages.*;

import org.spockframework.util.TextUtil;

/**
 * Reporting facility for problems found during compilation.
 * In general, error(ASTNode) is the preferred method to use.
 * error(InvalidSpecCompileException) should only be used if compilation cannot
 * continue in the same method where the error was found (because some
 * steps need to be skipped). In that case, a InvalidSpecCompileException should be
 * thrown at the point where the error is detected, and an outer method
 * should catch the exception and pass it on to ErrorReporter.
 *
 * @author Peter Niederwieser
 */
public class ErrorReporter {
  private final SourceUnit sourceUnit;

  public ErrorReporter(SourceUnit sourceUnit) {
    this.sourceUnit = sourceUnit;
  }
  
  public void error(String msg, Object... args) {
    sourceUnit.getErrorCollector().addErrorAndContinue(
        new SimpleMessage(String.format(msg, args), sourceUnit));
  }

  public void error(String msg, Throwable cause, Object... args) {
    sourceUnit.getErrorCollector().addErrorAndContinue(
        new SimpleMessage(String.format(msg, args) + "\n\n" + TextUtil.printStackTrace(cause), sourceUnit));
  }

  public void error(ASTNode node, String msg, Object... args) {
    error(new InvalidSpecCompileException(node, msg, args));
  }

  public void error(int line, int column, String msg, Object... args) {
    error(new InvalidSpecCompileException(line, column, msg, args));
  }

  public void error(InvalidSpecCompileException e) {
    sourceUnit.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(e, sourceUnit));
  }
}
ExpressionReplacingVisitorSupport.java000066400000000000000000000313001202022523300361750ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.List;
import java.util.ListIterator;

import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.*;
import org.codehaus.groovy.classgen.BytecodeExpression;

/**
 * Groovy AST visitor that allows to replace both statements and expressions.
 *
 * @author Peter Niederwieser
 */
public class ExpressionReplacingVisitorSupport extends StatementReplacingVisitorSupport {
  private Expression replacementExpr;

  public Expression replaceExpr(Expression expr) {
    replacementExpr = null;
    expr.visit(this);
    Expression result = replacementExpr == null ? expr : replacementExpr;
    replacementExpr = null;
    return result;
  }

  @SuppressWarnings("unchecked")
  protected  void replaceAllExprs(List exprs) {
    ListIterator iter = exprs.listIterator();
    while (iter.hasNext())
      iter.set((T) replaceExpr(iter.next()));
  }

  /*
   * Replaces the currently visited expression with the specified expression.
   */
  protected void replaceVisitedExpressionWith(Expression other) {
    replacementExpr = other;
  }

  @Override
  @SuppressWarnings("unchecked")
  public void visitBlockStatement(BlockStatement stat) {
    replaceAll(stat.getStatements());
  }

  @Override
  public void visitForLoop(ForStatement stat) {
    stat.setCollectionExpression(replaceExpr(stat.getCollectionExpression()));
    stat.setLoopBlock(replace(stat.getLoopBlock()));
  }

  @Override
  public void visitWhileLoop(WhileStatement stat) {
    stat.setBooleanExpression((BooleanExpression)replaceExpr(stat.getBooleanExpression()));
    stat.setLoopBlock(replace(stat.getLoopBlock()));
  }

  @Override
  public void visitDoWhileLoop(DoWhileStatement stat) {
    stat.setBooleanExpression((BooleanExpression)replaceExpr(stat.getBooleanExpression()));
    stat.setLoopBlock(replace(stat.getLoopBlock()));
  }

  @Override
  public void visitIfElse(IfStatement stat) {
    stat.setBooleanExpression((BooleanExpression)replaceExpr(stat.getBooleanExpression()));
    stat.setIfBlock(replace(stat.getIfBlock()));
    stat.setElseBlock(replace(stat.getElseBlock()));
  }

  @Override
  @SuppressWarnings("unchecked")
  public void visitTryCatchFinally(TryCatchStatement stat) {
    stat.setTryStatement(replace(stat.getTryStatement()));
    replaceAll(stat.getCatchStatements());
    stat.setFinallyStatement(replace(stat.getFinallyStatement()));
  }

  @Override
  @SuppressWarnings("unchecked")
  public void visitSwitch(SwitchStatement stat) {
    stat.setExpression(replaceExpr(stat.getExpression()));
    replaceAll(stat.getCaseStatements());
    stat.setDefaultStatement(replace(stat.getDefaultStatement()));
  }

  @Override
  public void visitCaseStatement(CaseStatement stat) {
    stat.setExpression(replaceExpr(stat.getExpression()));
    stat.setCode(replace(stat.getCode()));
  }

  @Override
  public void visitSynchronizedStatement(SynchronizedStatement stat) {
    stat.setExpression(replaceExpr(stat.getExpression()));
    stat.setCode(replace(stat.getCode()));
  }

  @Override
  public void visitCatchStatement(CatchStatement stat) {
    stat.setCode(replace(stat.getCode()));
  }

  @Override
  public void visitMethodCallExpression(MethodCallExpression expr) {
    expr.setObjectExpression(replaceExpr(expr.getObjectExpression()));
    expr.setMethod(replaceExpr(expr.getMethod()));
    expr.setArguments(replaceExpr(expr.getArguments()));
  }

  @Override
  public void visitStaticMethodCallExpression(StaticMethodCallExpression expr) {
    StaticMethodCallExpression result = new StaticMethodCallExpression(
        expr.getOwnerType(),
        expr.getMethod(),
        replaceExpr(expr.getArguments()));
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitConstructorCallExpression(ConstructorCallExpression expr) {
    ConstructorCallExpression result = new ConstructorCallExpression(
        expr.getType(),
        replaceExpr(expr.getArguments()));
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitBinaryExpression(BinaryExpression expr) {
    expr.setLeftExpression(replaceExpr(expr.getLeftExpression()));
    expr.setRightExpression(replaceExpr(expr.getRightExpression()));
  }

  @Override
  public void visitTernaryExpression(TernaryExpression expr) {
    TernaryExpression result = new TernaryExpression(
        (BooleanExpression)replaceExpr(expr.getBooleanExpression()),
        replaceExpr(expr.getTrueExpression()),
        replaceExpr(expr.getFalseExpression()));
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitShortTernaryExpression(ElvisOperatorExpression expr) {
    ElvisOperatorExpression result = new ElvisOperatorExpression(
        replaceExpr(expr.getTrueExpression()),
        replaceExpr(expr.getFalseExpression()));
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitPostfixExpression(PostfixExpression expr) {
    expr.setExpression(replaceExpr(expr.getExpression()));
  }

  @Override
  public void visitPrefixExpression(PrefixExpression expr) {
    expr.setExpression(replaceExpr(expr.getExpression()));
  }

  @Override
  public void visitBooleanExpression(BooleanExpression expr) {
    BooleanExpression result = new BooleanExpression(
        replaceExpr(expr.getExpression()));
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitNotExpression(NotExpression expr) {
    NotExpression result = new NotExpression(
        replaceExpr(expr.getExpression()));
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitClosureExpression(ClosureExpression expr) {
    super.visitClosureExpression(expr);
    replaceVisitedExpressionWith(expr);
  }

  @Override
  @SuppressWarnings("unchecked")
  public void visitTupleExpression(TupleExpression expr) {
    replaceAllExprs(expr.getExpressions());
  }

  @Override
  @SuppressWarnings("unchecked")
  public void visitListExpression(ListExpression expr) {
    replaceAllExprs(expr.getExpressions());
  }

  @Override
  @SuppressWarnings("unchecked")
  public void visitArrayExpression(ArrayExpression expr) {
    replaceAllExprs(expr.getExpressions());
    replaceAllExprs(expr.getSizeExpression());
  }

  @Override
  @SuppressWarnings("unchecked")
  public void visitMapExpression(MapExpression expr) {
    replaceAllExprs(expr.getMapEntryExpressions());

  }

  @Override
  public void visitMapEntryExpression(MapEntryExpression expr) {
    MapEntryExpression result = new MapEntryExpression(
      replaceExpr(expr.getKeyExpression()),
      replaceExpr(expr.getValueExpression())
    );
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitRangeExpression(RangeExpression expr) {
    RangeExpression result = new RangeExpression(
        replaceExpr(expr.getFrom()),
        replaceExpr(expr.getTo()),
        expr.isInclusive()
    );
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitSpreadExpression(SpreadExpression expr) {
    SpreadExpression result = new SpreadExpression(
        replaceExpr(expr.getExpression())
    );
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitSpreadMapExpression(SpreadMapExpression expr) {
    SpreadMapExpression result = new SpreadMapExpression(
        replaceExpr(expr.getExpression())
    );
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitMethodPointerExpression(MethodPointerExpression expr) {
    MethodPointerExpression result = new MethodPointerExpression(
        replaceExpr(expr.getExpression()),
        expr.getMethodName()
    );
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitUnaryMinusExpression(UnaryMinusExpression expr) {
    UnaryMinusExpression result = new UnaryMinusExpression(
        replaceExpr(expr.getExpression())
    );
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitUnaryPlusExpression(UnaryPlusExpression expr) {
    UnaryPlusExpression result = new UnaryPlusExpression(
        replaceExpr(expr.getExpression())
    );
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitBitwiseNegationExpression(BitwiseNegationExpression expr) {
    BitwiseNegationExpression result = new BitwiseNegationExpression(
        replaceExpr(expr.getExpression())
    );
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitCastExpression(CastExpression expr) {
    CastExpression result = new CastExpression(
        expr.getType(),
        replaceExpr(expr.getExpression()),
        expr.isIgnoringAutoboxing()
    );
    result.setCoerce(expr.isCoerce());
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitDeclarationExpression(DeclarationExpression expr) {
    visitBinaryExpression(expr);
    replaceVisitedExpressionWith(expr);
  }

  @Override
  public void visitPropertyExpression(PropertyExpression expr) {
    PropertyExpression result = new PropertyExpression(
        replaceExpr(expr.getObjectExpression()),
        replaceExpr(expr.getProperty()),
        expr.isSafe()
    );
    result.setSpreadSafe(expr.isSpreadSafe());
    result.setStatic(expr.isStatic());
    result.setImplicitThis(expr.isImplicitThis());
    result.setType(expr.getType());
    result.setSourcePosition(expr);
    replaceVisitedExpressionWith(result);
  }

  @Override
  public void visitAttributeExpression(AttributeExpression expr) {
    visitPropertyExpression(expr);
    replaceVisitedExpressionWith(expr);
  }

  @Override
  @SuppressWarnings("unchecked")
  public void visitGStringExpression(GStringExpression expr) {
    replaceAllExprs(expr.getStrings());
    replaceAllExprs(expr.getValues());
  }

  @Override
  public void visitArgumentlistExpression(ArgumentListExpression expr) {
    visitTupleExpression(expr);
    replaceVisitedExpressionWith(expr);
  }

  @Override
  public void visitClosureListExpression(ClosureListExpression expr) {
    visitListExpression(expr);
    replaceVisitedExpressionWith(expr);
  }

  @Override
  public void visitAssertStatement(AssertStatement stat) {
    replaceExpr(stat.getBooleanExpression());
    replaceExpr(stat.getMessageExpression());
  }

  @Override
  public void visitExpressionStatement(ExpressionStatement stat) {
    replaceExpr(stat.getExpression());
  }

  @Override
  public void visitReturnStatement(ReturnStatement stat) {
    replaceExpr(stat.getExpression());
  }

  @Override
  public void visitThrowStatement(ThrowStatement stat) {
    replaceExpr(stat.getExpression());
  }

  @Override
  protected void visitListOfExpressions(List exprs) {
    throw new UnsupportedOperationException("visitListOfExpressions");
  }

  // remaining methods are here to make sure we didn't forget anything
  
  @Override
  public void visitBreakStatement(BreakStatement stat) {}
  @Override
  public void visitContinueStatement(ContinueStatement stat) {}
  @Override
  public void visitConstantExpression(ConstantExpression expr) {}
  @Override
  public void visitClassExpression(ClassExpression expr) {}
  @Override
  public void visitVariableExpression(VariableExpression expr) {}
  @Override
  public void visitFieldExpression(FieldExpression expr) {}
  @Override
  public void visitBytecodeExpression(BytecodeExpression expr) {}
}
FieldInitializationExpression.java000066400000000000000000000026031202022523300352530ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.expr.BinaryExpression;
import org.codehaus.groovy.ast.expr.FieldExpression;
import org.codehaus.groovy.syntax.Token;
import org.codehaus.groovy.syntax.Types;

/**
 * An assignment of the form "x = expr", where x is a field and expr is a field
 * initializer expression. The purpose of this class is to make field
 * initializations distinguishable from other assignments while traversing
 * the AST.
 * 
 * @author Peter Niederwieser
 */
public class FieldInitializationExpression extends BinaryExpression {
  public FieldInitializationExpression(FieldNode field) {
    super(new FieldExpression(field), Token.newSymbol(Types.ASSIGN, -1, -1), field.getInitialValueExpression());
  }
}spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/IRewriteResources.java000066400000000000000000000026411202022523300327460ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.List;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.Statement;

import org.spockframework.compiler.model.Block;
import org.spockframework.compiler.model.Method;
import org.spockframework.compiler.model.Spec;

/**
 *
 * @author Peter Niederwieser
 */
public interface IRewriteResources {
  Spec getCurrentSpec();
  Method getCurrentMethod();
  Block getCurrentBlock();

  void defineValueRecorder(List stats);
  VariableExpression captureOldValue(Expression oldValue);
  VariableExpression getMockControllerRef();

  AstNodeCache getAstNodeCache();
  String getSourceText(ASTNode node);
  ErrorReporter getErrorReporter();
}
InstanceFieldAccessChecker.java000066400000000000000000000051161202022523300343610ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.Variable;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.FieldExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.control.SourceUnit;

import org.spockframework.compiler.model.Block;
import org.spockframework.compiler.model.Method;
import org.spockframework.util.UnreachableCodeError;

import spock.lang.Shared;

// we don't currently check this.x and super.x because
// it's not as clear how this should be done (for example,
// 'x' could refer to a property)
public class InstanceFieldAccessChecker extends ClassCodeVisitorSupport {
  private final IRewriteResources resources;

  public InstanceFieldAccessChecker(IRewriteResources resources) {
    this.resources = resources;
  }

  public void check(Expression expr) {
    expr.visit(this);
  }

  public void check(Method method) {
    for (Block block : method.getBlocks())
      for (Statement stat : block.getAst())
        stat.visit(this);
  }

  @Override
  public void visitVariableExpression(VariableExpression expr) {
    super.visitVariableExpression(expr);

    Variable var = expr.getAccessedVariable();
    if (!(var instanceof FieldNode)) return;

    checkFieldAccess(expr, (FieldNode) var);
  }

  @Override
  public void visitFieldExpression(FieldExpression expr) {
    super.visitFieldExpression(expr);

    checkFieldAccess(expr, expr.getField());
  }

  @Override
  protected SourceUnit getSourceUnit() {
    throw new UnreachableCodeError();
  }

  private void checkFieldAccess(ASTNode context, FieldNode field) {
    if (AstUtil.hasAnnotation(field, Shared.class) || field.isStatic()) return;

    resources.getErrorReporter().error(context, "Only @Shared and static fields may be accessed from here");
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/InteractionRewriter.java000077500000000000000000000253621202022523300333340ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.syntax.Types;

import org.spockframework.lang.Wildcard;
import org.spockframework.mock.InteractionBuilder;
import org.spockframework.mock.MockController;
import org.spockframework.util.Assert;
import org.spockframework.util.Nullable;

/**
 * Creates the AST representation of an InteractionBuilder build sequence.
 *
 * @author Peter Niederwieser
 */
public class InteractionRewriter {
  private final IRewriteResources resources;

  // information about the interaction; filled in by parse()
  private ExpressionStatement stat;
  private Expression count;
  private Expression call;
  private boolean wildcardCall;
  private List results = new ArrayList();

  // holds the incrementally constructed expression, which looks roughly as follows:
  // "new InteractionBuilder(..).setCount(..).setTarget(..).setMethod(..).addArg(..).addResult(..).build()"
  private Expression builderExpr;

  public InteractionRewriter(IRewriteResources resources) {
    this.resources = resources;
  }

  /**
   * If the given statement is a valid interaction definition, returns the rewritten statement.
   * If the given statement is not an interaction definition, returns null.
   * If the given statement is an invalid interaction definition, records a compile error
   * and returns null.
   */
  public @Nullable Statement rewrite(ExpressionStatement stat) {
    try {
      if (!parse(stat)) return null;

      createBuilder();
      setCount();
      setCall();
      addResults();
      build();
      return register();
    } catch (InvalidSpecCompileException e) {
      resources.getErrorReporter().error(e);
      return null;
    }
  }

  private boolean parse(ExpressionStatement stat) throws InvalidSpecCompileException {
    this.stat = stat;
    
    Expression expr = parseCount(parseResults(stat.getExpression()));
    return (count != null || !results.isEmpty()) && parseCall(expr);
  }
  
  private Expression parseResults(Expression expr) {
    while (expr instanceof BinaryExpression) {
      BinaryExpression binExpr = (BinaryExpression) expr;
      int type = binExpr.getOperation().getType();
      if (type != Types.RIGHT_SHIFT && type != Types.RIGHT_SHIFT_UNSIGNED) break;
      results.add(new InteractionResult(binExpr.getRightExpression(), type == Types.RIGHT_SHIFT_UNSIGNED));
      expr = binExpr.getLeftExpression();
    }
    return expr;
  }
  
  private Expression parseCount(Expression expr) {
    BinaryExpression binExpr = AstUtil.asInstance(expr, BinaryExpression.class);
    if (binExpr == null || binExpr.getOperation().getType() != Types.MULTIPLY) return expr;
    count = binExpr.getLeftExpression();
    return binExpr.getRightExpression();
  }

  private boolean parseCall(Expression expr) throws InvalidSpecCompileException {
    call = expr;

    if (AstUtil.isWildcardRef(expr)) {
      wildcardCall = true;
      return true;
    }

    if (expr instanceof PropertyExpression) {
      PropertyExpression propExpr = (PropertyExpression)expr;

      // isImplicitThis() and isStatic() always seem to return false for
      // properties, but checking them can't hurt
      if (propExpr.isImplicitThis()) return false;
      if (propExpr.isStatic()) staticMembersNotSupported(expr);

      if (propExpr.getObjectExpression() instanceof ClassExpression)
        staticMembersNotSupported(expr);
      return true;
    }

    if (expr instanceof MethodCallExpression) {
      MethodCallExpression mcExpr = (MethodCallExpression)expr;
      if (mcExpr.isImplicitThis()) return false;
      if (mcExpr.getObjectExpression() instanceof ClassExpression)
        staticMembersNotSupported(expr);
      return true;
    }

    // StaticMethodCallExpression is only used for unqualified calls to static methods
    if (expr instanceof StaticMethodCallExpression) return false;

    return false;
  }

  private void staticMembersNotSupported(Expression expr) throws InvalidSpecCompileException {
    throw new InvalidSpecCompileException(expr,
        "Stubbing/mocking of static methods and properties is not supported.");
  }

  private void createBuilder() {
    // ExpressionStatements w/ label have wrong source position,
    // but source position of the contained expression is OK
    Expression expr = stat.getExpression();

    builderExpr = new ConstructorCallExpression(
        resources.getAstNodeCache().InteractionBuilder,
        new ArgumentListExpression(
            Arrays. asList(
                new ConstantExpression(expr.getLineNumber()),
                new ConstantExpression(expr.getColumnNumber()),
                new ConstantExpression(resources.getSourceText(expr)))));
  }

  private void setCount() {
    if (count == null) return;

    if (count instanceof RangeExpression) {
      RangeExpression range = (RangeExpression)count;
      call(InteractionBuilder.SET_RANGE_COUNT,
          range.getFrom(),
          range.getTo(),
          new ConstantExpression(range.isInclusive()));

      return;
    }

    call(InteractionBuilder.SET_FIXED_COUNT, count);
  }

  private void setCall() {
    if (wildcardCall)
      call(InteractionBuilder.ADD_EQUAL_METHOD_NAME, new ConstantExpression(Wildcard.INSTANCE.toString()));
    else if (call instanceof PropertyExpression)
      setPropertyCall();
    else
      setMethodCall();
  }

  private void setPropertyCall() {
    setTarget();
    setPropertyName();
  }

  private void setPropertyName() {
    Expression propertyNameExpr = ((PropertyExpression)call).getProperty();
    String constraint = selectNameConstraint(propertyNameExpr,
        InteractionBuilder.ADD_EQUAL_PROPERTY_NAME, InteractionBuilder.ADD_REGEX_PROPERTY_NAME);
    call(constraint, propertyNameExpr);
  }

  private void setMethodCall() {
    setTarget();
    setMethodName();
    addArgs();
  }

  private void setTarget() {
    call(InteractionBuilder.ADD_EQUAL_TARGET, AstUtil.getInvocationTarget(call));
  }

  private void setMethodName() {
    Expression methodNameExpr = ((MethodCallExpression)call).getMethod();
    String constraint = selectNameConstraint(methodNameExpr,
        InteractionBuilder.ADD_EQUAL_METHOD_NAME, InteractionBuilder.ADD_REGEX_METHOD_NAME);
    call(constraint, methodNameExpr);
  }

  private String selectNameConstraint(Expression nameExpr, String constraint1, String constraint2) {
    if (!(nameExpr instanceof ConstantExpression)) // dynamically generated name
      return constraint1;

    String method = (String)((ConstantExpression)nameExpr).getValue();
    // NOTE: we cannot tell from the AST if a method (or property) name is defined using
    // slashy string syntax ("/somePattern/"); hence, we consider any name
    // that isn't a valid Java identifier a pattern. While this isn't entirely
    // safe (the JVM allows almost all characters in method names), it should
    // work out well in practice because it's very unlikely that a
    // collaborator has a method name that is not a valid Java identifier.
    return AstUtil.isJavaIdentifier(method) ? constraint1 : constraint2;
  }

  private void addArgs() {
    if (call instanceof PropertyExpression) return;

    Expression args = ((MethodCallExpression)call).getArguments();
    if (args == ArgumentListExpression.EMPTY_ARGUMENTS) return; // fast lane
    
    call(InteractionBuilder.SET_ARG_LIST_KIND,
        new ConstantExpression(args instanceof ArgumentListExpression));
    
    if (args instanceof ArgumentListExpression)
      addPositionalArgs((ArgumentListExpression)args);
    else if (args instanceof NamedArgumentListExpression)
      addNamedArgs((NamedArgumentListExpression)args);
    else Assert.that(false, "unknown kind of argument list: " + args);
  }

  @SuppressWarnings("unchecked")
  private void addPositionalArgs(ArgumentListExpression args) {
    for (Expression arg: args.getExpressions())
      addArg(arg);
  }

  @SuppressWarnings("unchecked")
  private void addNamedArgs(NamedArgumentListExpression args) {
    for (MapEntryExpression arg : args.getMapEntryExpressions()) {
      addName(arg.getKeyExpression());
      addArg(arg.getValueExpression());
    }
  }

  private void addName(Expression name) {
    call(InteractionBuilder.ADD_ARG_NAME, name);
  }

  private void addArg(Expression arg) {
    if (arg instanceof NotExpression) {
      NotExpression not = (NotExpression)arg;
      addArg(not.getExpression());
      call(InteractionBuilder.NEGATE_LAST_ARG);
      return;
    }

    if (arg instanceof CastExpression) {
      CastExpression cast = (CastExpression)arg;
      addArg(cast.getExpression());
      call(InteractionBuilder.TYPE_LAST_ARG, new ClassExpression(cast.getType()));
      return;
    }

    if (arg instanceof ClosureExpression) {
      call(InteractionBuilder.ADD_CODE_ARG, arg);
      return;
    }

    call(InteractionBuilder.ADD_EQUAL_ARG, arg);
  }

  private void addResults() {
    for (InteractionResult result : results) {
      if (result.iterable) {
        call(InteractionBuilder.ADD_ITERABLE_RESULT, result.expr);
      } else if (result.expr instanceof ClosureExpression) {
        call(InteractionBuilder.ADD_CODE_RESULT, result.expr);
      } else {
        call(InteractionBuilder.ADD_CONSTANT_RESULT, result.expr);
      }
    }
  }

  private void build() {
    call(InteractionBuilder.BUILD);
  }

  private Statement register() {
    Statement result =
        new ExpressionStatement(
            new MethodCallExpression(
                resources.getMockControllerRef(),
                MockController.ADD_INTERACTION,
                new ArgumentListExpression(builderExpr)));

    result.setSourcePosition(stat);
    return result;
  }

  private void call(String method, Expression... args) {
    builderExpr = new MethodCallExpression(
        builderExpr,
        method,
        new ArgumentListExpression(args));
  }
  
  private static class InteractionResult {
    final Expression expr;
    final boolean iterable;

    private InteractionResult(Expression expr, boolean iterable) {
      this.expr = expr;
      this.iterable = iterable;
    }
  }
}
InvalidSpecCompileException.java000077500000000000000000000034331202022523300346360ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.syntax.SyntaxException;

/**
 * Indicates that a spec was found to contain a (syntactic or semantic)
 * error during compilation. As such, this is the compile-time equivalent
 * of InvalidSpecException.
 * Inherits from SyntaxException so that line information can
 * be exploited by integrators (IDEs etc.).
 *
 * Most of the time it is not necessary to use this class directly (see
 * documentation of class ErrorReporter).
 * 
 * @author Peter Niederwieser
 */
public class InvalidSpecCompileException extends SyntaxException {
  public InvalidSpecCompileException(int line, int column, String msg, Object... args) {
    super(String.format(msg, args), line, column);
  }

  public InvalidSpecCompileException(ASTNode node, String msg, Object... args) {
    this(getLine(node), getColumn(node), msg, args);
  }

  private static int getLine(ASTNode node) {
    return node.getLineNumber() > 0 ? node.getLineNumber() : node.getLastLineNumber();
  }

  private static int getColumn(ASTNode node) {
    return node.getColumnNumber() > 0 ? node.getColumnNumber() : node.getLastColumnNumber();
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/OldValueExpression.java000066400000000000000000000025341202022523300331150ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.VariableExpression;

/**
 * Used to represent the argument to Specification.old() once it has been processed
 * by IRewriteResources.captureOldValue(). The original expression is
 * kept in case ConditionRewriter still needs it.
 * 
 * @author Peter Niederwieser
 */
public class OldValueExpression extends VariableExpression {
  private final Expression originalExpression;

  public OldValueExpression(Expression originalExpression, String substitutedVariable) {
    super(substitutedVariable);
    this.originalExpression = originalExpression;
  }

  public Expression getOrginalExpression() {
    return originalExpression;
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/SourceLookup.java000066400000000000000000000043271202022523300317560ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.control.Janitor;
import org.codehaus.groovy.control.SourceUnit;

public class SourceLookup {
  private final SourceUnit sourceUnit;
  private final Janitor janitor = new Janitor();

  public SourceLookup(SourceUnit sourceUnit) {
    this.sourceUnit = sourceUnit;
  }

  public String lookup(ASTNode node) {
    String text = "";
    for (int i = node.getLineNumber(); i <= node.getLastLineNumber(); i++) {
      String line = sourceUnit.getSample(i, 0, janitor);
      if (line == null) {
        return null; // most probably a Groovy bug, but we'd like to handle this situation gracefully
        // throw new Error(String.format("null line detected; lineNum=%s, expr=%s", i, node.getText()));
      }

      try {
        if (i == node.getLastLineNumber()) line = line.substring(0, node.getLastColumnNumber() - 1);
        if (i == node.getLineNumber()) line = line.substring(node.getColumnNumber() - 1);
        text += line;
        if (i != node.getLastLineNumber()) text += '\n';
      } catch (StringIndexOutOfBoundsException e) {
        return null; // most probably a Groovy bug, but we'd like to handle this situation gracefully
        // throw new RuntimeException(String.format("error getting node text; expr='%s', lineNumber='%s', lastLineNumber='%s', columnNumber='%s', lastColumnNumber='%s', currentLine='%s'", node, node.getLineNumber(), node.getLastLineNumber(), node.getColumnNumber(), node.getLastColumnNumber(), line), e);
      }
    }
    return text.trim();
  }

  public void close() {
    janitor.cleanup();
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/SpecAnnotator.java000077500000000000000000000110311202022523300320750ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.io.File;

import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.expr.*;

import org.spockframework.compiler.model.*;
import org.spockframework.runtime.model.*;

/**
 * Puts all spec information required at runtime into annotations
 * attached to class members.
 * 
 * @author Peter Niederwieser
 */
public class SpecAnnotator extends AbstractSpecVisitor {
  private final AstNodeCache nodeCache;
  private ListExpression blockAnnElems;

  public SpecAnnotator(AstNodeCache nodeCache) {
    this.nodeCache = nodeCache;
  }

  @Override
  public void visitSpec(Spec spec) throws Exception {
    addSpecMetadata(spec);
  }

  private void addSpecMetadata(Spec spec) {
    AnnotationNode ann = new AnnotationNode(nodeCache.SpecMetadata);
    String pathname = spec.getAst().getModule().getContext().getName();
    String filename = new File(pathname).getName();
    ann.setMember(SpecMetadata.FILENAME, new ConstantExpression(filename));
    ann.setMember(SpecMetadata.LINE, new ConstantExpression(spec.getAst().getLineNumber()));
    spec.getAst().addAnnotation(ann);
  }

  @Override
  public void visitField(Field field) throws Exception {
    addFieldMetadata(field);
  }

  private void addFieldMetadata(Field field) {
    AnnotationNode ann = new AnnotationNode(nodeCache.FieldMetadata);
    ann.setMember(FieldMetadata.NAME, new ConstantExpression(field.getName()));
    ann.setMember(FieldMetadata.ORDINAL, new ConstantExpression(field.getOrdinal()));
    ann.setMember(FieldMetadata.LINE, new ConstantExpression(field.getAst().getLineNumber()));
    field.getAst().addAnnotation(ann);
  }

  @Override
  public void visitMethod(Method method) throws Exception {
    if (method instanceof FeatureMethod)
      addFeatureMetadata((FeatureMethod)method);
  }

  private void addFeatureMetadata(FeatureMethod feature) {
    AnnotationNode ann = new AnnotationNode(nodeCache.FeatureMetadata);
    ann.setMember(FeatureMetadata.NAME, new ConstantExpression(feature.getName()));
    ann.setMember(FeatureMetadata.ORDINAL, new ConstantExpression(feature.getOrdinal()));
    ann.setMember(FeatureMetadata.LINE, new ConstantExpression(feature.getAst().getLineNumber()));
    ann.setMember(FeatureMetadata.BLOCKS, blockAnnElems = new ListExpression());

    ListExpression paramNames = new ListExpression();
    for (Parameter param : feature.getAst().getParameters())
      paramNames.addExpression(new ConstantExpression(param.getName()));
    ann.setMember(FeatureMetadata.PARAMETER_NAMES, paramNames);

    feature.getAst().addAnnotation(ann);
  }

  private void addBlockMetadata(Block block, BlockKind kind) {
    AnnotationNode blockAnn = new AnnotationNode(nodeCache.BlockMetadata);
    blockAnn.setMember(BlockMetadata.KIND, new PropertyExpression(
        new ClassExpression(nodeCache.BlockKind), kind.name()));
    ListExpression textExprs = new ListExpression();
    for (String text : block.getDescriptions())
      textExprs.addExpression(new ConstantExpression(text));
    blockAnn.setMember(BlockMetadata.TEXTS, textExprs);
    blockAnnElems.addExpression(new AnnotationConstantExpression(blockAnn));
  }

  @Override
  public void visitSetupBlock(SetupBlock block) throws Exception {
    addBlockMetadata(block, BlockKind.SETUP);
  }

  @Override
  public void visitExpectBlock(ExpectBlock block) throws Exception {
    addBlockMetadata(block, BlockKind.EXPECT);
  }

  @Override
  public void visitWhenBlock(WhenBlock block) throws Exception {
    addBlockMetadata(block, BlockKind.WHEN);
  }

  @Override
  public void visitThenBlock(ThenBlock block) throws Exception {
    addBlockMetadata(block, BlockKind.THEN);
  }

  @Override
  public void visitCleanupBlock(CleanupBlock block) throws Exception {
    addBlockMetadata(block, BlockKind.CLEANUP);
  }

  @Override
  public void visitWhereBlock(WhereBlock block) throws Exception {
    addBlockMetadata(block, BlockKind.WHERE);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/SpecParser.java000077500000000000000000000205661202022523300314010ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.List;

import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.stmt.Statement;

import static org.spockframework.util.Identifiers.*;
import org.spockframework.compiler.model.*;

import spock.lang.Shared;

/**
 * Given the abstract syntax tree of a Groovy class representing a Spock
 * specification, builds an object model of the specification.
 *
 * @author Peter Niederwieser
 */
public class SpecParser implements GroovyClassVisitor {
  private final ErrorReporter errorReporter;

  private Spec spec;
  private int fieldCount = 0;
  private int featureMethodCount = 0;

  public SpecParser(ErrorReporter errorReporter) {
    this.errorReporter = errorReporter;
  }

  public Spec build(ClassNode clazz) {
    spec = new Spec(clazz);
    clazz.visitContents(this);
    return spec;
  }

  public void visitClass(ClassNode clazz) {
   throw new UnsupportedOperationException("visitClass");
  }

  // might only want to include fields relating to a user-provided
  // definition, but it's hard to tell them apart; for example,
  // field.isSynthetic() is true for a property's backing field
  // although it IS related to a user-provided definition
  public void visitField(FieldNode gField) {
    PropertyNode owner = spec.getAst().getProperty(gField.getName());
    if (gField.isStatic()) return;

    Field field = new Field(spec, gField, fieldCount++);
    field.setShared(AstUtil.hasAnnotation(gField, Shared.class));
    field.setOwner(owner);
    spec.getFields().add(field);
  }

  public void visitProperty(PropertyNode node) {}

  public void visitConstructor(ConstructorNode constructor) {
    if (AstUtil.isSynthetic(constructor)) return;
    if (constructorMayHaveBeenAddedByCompiler(constructor)) return;

    errorReporter.error(constructor,
"Constructors are not allowed; instead, define a 'setup()' or 'setupSpec()' method");
  }

  // In case of joint compilation, Verifier - which may add a default constructor
  // - is run in phase CONVERSION. Additionally, groovyc 1.7 and above no longer
  // marks default constructors as synthetic (following javac). Therefore, we have
  // to add special logic to detect this case.
  private boolean constructorMayHaveBeenAddedByCompiler(ConstructorNode constructor) {
    Parameter[] params = constructor.getParameters();
    Statement firstStat = constructor.getFirstStatement();
    return AstUtil.isJointCompiled(spec.getAst()) && constructor.isPublic()
      && params != null && params.length == 0 && firstStat == null;
  }

  public void visitMethod(MethodNode method) {
    if (isIgnoredMethod(method)) return;
    
    if (isFixtureMethod(method))
      buildFixtureMethod(method);
    else if (isFeatureMethod(method))
      buildFeatureMethod(method);
    else buildHelperMethod(method);
  }

  private boolean isIgnoredMethod(MethodNode method) {
    return AstUtil.isSynthetic(method);
  }

  // IDEA: check for misspellings other than wrong capitalization
  private boolean isFixtureMethod(MethodNode method) {
    String name = method.getName();

    for (String fmName : FIXTURE_METHODS) {
      if (!fmName.equalsIgnoreCase(name)) continue;

      // assertion: is (meant to be) a fixture method, so we'll return true in the end
      
      if (method.isStatic())
        errorReporter.error(method, "Fixture methods must not be static");
      if (!fmName.equals(name))
        errorReporter.error(method, "Misspelled '%s()' method (wrong capitalization)", fmName);

      return true;
    }

    return false;
  }

  private void buildFixtureMethod(MethodNode method) {
    FixtureMethod fixtureMethod = new FixtureMethod(spec, method);

    Block block = new AnonymousBlock(fixtureMethod);
    fixtureMethod.addBlock(block);
    List stats = AstUtil.getStatements(method);
    block.getAst().addAll(stats);
    stats.clear();

    String name = method.getName();
    if (name.equals(SETUP)) spec.setSetupMethod(fixtureMethod);
    else if (name.equals(CLEANUP)) spec.setCleanupMethod(fixtureMethod);
    else if (name.equals(SETUP_SPEC_METHOD)) spec.setSetupSpecMethod(fixtureMethod);
    else spec.setCleanupSpecMethod(fixtureMethod);
  }

  // IDEA: recognize feature methods by looking at signature only
  // rationale: current solution can sometimes be unintuitive, e.g.
  // for methods with empty body, or for methods with single assert
  // potential indicators for feature methods:
  // - public visibility (and no fixture method)
  // - no visibility modifier (and no fixture method) (source lookup required?)
  // - method name given as string literal (requires source lookup)
  private boolean isFeatureMethod(MethodNode method) {
    for (Statement stat : AstUtil.getStatements(method)) {
      String label = stat.getStatementLabel();
      if (label == null) continue;

      // assertion: is (meant to be) a feature method, so we'll return true in the end
      if (method.isStatic())
        errorReporter.error(method, "Feature methods must not be static");

      return true;
    }

    return false;
  }

  private void buildFeatureMethod(MethodNode method) {
    Method feature = new FeatureMethod(spec, method, featureMethodCount++);
    try {
      buildBlocks(feature);
    } catch (InvalidSpecCompileException e) {
      errorReporter.error(e);
      return;
    }
    spec.getMethods().add(feature);
  }

  private void buildHelperMethod(MethodNode method) {  
    Method helper = new HelperMethod(spec, method);
    spec.getMethods().add(helper);

    Block block = helper.addBlock(new AnonymousBlock(helper));
    List stats = AstUtil.getStatements(method);
    block.getAst().addAll(stats);
    stats.clear();
  }

  private void buildBlocks(Method method) throws InvalidSpecCompileException {
    List stats = AstUtil.getStatements(method.getAst());
    Block currBlock = method.addBlock(new AnonymousBlock(method));

    for (Statement stat : stats) {
      if (stat.getStatementLabel() == null)
        currBlock.getAst().add(stat);
      else
        currBlock = addBlock(method, stat);
    }
    
    checkIsValidSuccessor(method, BlockParseInfo.METHOD_END,
        method.getAst().getLastLineNumber(), method.getAst().getLastColumnNumber());

    // now that statements have been copied to blocks, the original statement
    // list is cleared; statements will be copied back after rewriting is done
    stats.clear();
  }

  private Block addBlock(Method method, Statement stat) throws InvalidSpecCompileException {
    String label = stat.getStatementLabel();

    for (BlockParseInfo blockInfo: BlockParseInfo.values()) {
	  	if (!label.equals(blockInfo.toString())) continue;

      checkIsValidSuccessor(method, blockInfo, stat.getLineNumber(), stat.getColumnNumber());
      Block block = blockInfo.addNewBlock(method);
      String description = getDescription(stat);
      if (description == null)
        block.getAst().add(stat);
      else
        block.getDescriptions().add(description);

      return block;
		}

		throw new InvalidSpecCompileException(stat, "Unrecognized block label: " + label);
  }

  private String getDescription(Statement stat) {
    ConstantExpression constExpr = AstUtil.getExpression(stat, ConstantExpression.class);
    return constExpr == null || !(constExpr.getValue() instanceof String) ?
        null : (String)constExpr.getValue();
  }

  private void checkIsValidSuccessor(Method method, BlockParseInfo blockInfo, int line, int column)
      throws InvalidSpecCompileException {
    BlockParseInfo oldBlockInfo = method.getLastBlock().getParseInfo();
    if (!oldBlockInfo.getSuccessors(method).contains(blockInfo))
      throw new InvalidSpecCompileException(line, column, "'%s' is not allowed here; instead, use one of: %s",
          blockInfo, oldBlockInfo.getSuccessors(method), method.getName(), oldBlockInfo, blockInfo);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/SpecRewriter.java000077500000000000000000000625251202022523300317510ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.*;

import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.*;
import org.codehaus.groovy.runtime.MetaClassHelper;
import org.codehaus.groovy.syntax.Token;
import org.codehaus.groovy.syntax.Types;
import org.objectweb.asm.Opcodes;

import org.spockframework.compiler.model.*;
import org.spockframework.mock.MockController;
import org.spockframework.util.InternalIdentifiers;
import org.spockframework.util.Identifiers;

/**
 * A Spec visitor responsible for most of the rewriting of a Spec's AST.
 * 
 * @author Peter Niederwieser
 */
// IDEA: mock controller / leaveScope calls should only be inserted when necessary (increases robustness)
public class SpecRewriter extends AbstractSpecVisitor implements IRewriteResources {
  private final AstNodeCache nodeCache;
  private final SourceLookup lookup;
  private final ErrorReporter errorReporter;

  private Spec spec;
  private int specDepth;
  private Method method;
  private Block block;

  private VariableExpression thrownExceptionRef; // reference to field $spock_thrown; always accessed through getter
  private VariableExpression mockControllerRef;  // reference to field $spock_mockController; always accessed through getter
  private VariableExpression sharedInstanceRef;  // reference to field $spock_sharedInstance

  private boolean methodHasCondition;
  private boolean movedStatsBackToMethod;
  private boolean thenBlockHasExceptionCondition; // reset once per chain of then-blocks

  private int fieldInitializerCount = 0;
  private int sharedFieldInitializerCount = 0;
  private int oldValueCount = 0;

  public SpecRewriter(AstNodeCache nodeCache, SourceLookup lookup, ErrorReporter errorReporter) {
    this.nodeCache = nodeCache;
    this.lookup = lookup;
    this.errorReporter = errorReporter;
  }

  public void visitSpec(Spec spec) {
    this.spec = spec;
    specDepth = computeDepth(spec.getAst());
    createThrownExceptionFieldAndRef();
    createMockControllerFieldAndRef();
    createSharedInstanceFieldAndRef();
  }

  private int computeDepth(ClassNode node) {
    if (node.equals(ClassHelper.OBJECT_TYPE) || node.equals(nodeCache.Specification)) return -1;
    return computeDepth(node.getSuperClass()) + 1;
  }

  public void visitSpecAgain(Spec spec) throws Exception {
    addMockControllerFieldInitializer();
  }

  private void createThrownExceptionFieldAndRef() {
    Variable var;

    if (isDirectlyExtendingSpecification())
      var = spec.getAst().addField(
          "$spock_thrown",
          Opcodes.ACC_PROTECTED | Opcodes.ACC_SYNTHETIC,
          ClassHelper.DYNAMIC_TYPE,
          null);
    else
      var = new DynamicVariable("$spock_thrown", false);

    thrownExceptionRef = new VariableExpression(var);
  }

  private void createMockControllerFieldAndRef() {
    Variable var;

    if (isDirectlyExtendingSpecification())
      var = spec.getAst().addField(
          "$spock_mockController",
          Opcodes.ACC_PROTECTED | Opcodes.ACC_SYNTHETIC,
          ClassHelper.DYNAMIC_TYPE,
          null);
    else
      var = new DynamicVariable("$spock_mockController", false);

    mockControllerRef = new VariableExpression(var);
  }

  private void createSharedInstanceFieldAndRef() {
    Variable var;

    if (isDirectlyExtendingSpecification())
      var = spec.getAst().addField(
          InternalIdentifiers.SHARED_INSTANCE_NAME,
          Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, // public s.t. runner can easily set it
          ClassHelper.DYNAMIC_TYPE,
          null);
      else
        var = new DynamicVariable(InternalIdentifiers.SHARED_INSTANCE_NAME, false);

    sharedInstanceRef = new VariableExpression(var);
  }

  private void addMockControllerFieldInitializer() {
    if (!isDirectlyExtendingSpecification()) return;
    
    // mock controller needs to be initialized before all other fields
    getInitializerMethod().getStatements().add(0,
        new ExpressionStatement(
            new BinaryExpression(
                mockControllerRef,
                Token.newSymbol(Types.ASSIGN, -1, -1),
                new ConstructorCallExpression(
                    nodeCache.MockController,
                    new FieldExpression(nodeCache.DefaultMockFactory_INSTANCE)))));
  }

  private boolean isDirectlyExtendingSpecification() {
    ClassNode superClass = spec.getAst().getSuperClass();
    return superClass.equals(ClassHelper.OBJECT_TYPE)
        || superClass.equals(nodeCache.Specification);
  }

  public void visitField(Field field) {
    if (field.isShared())
      handleSharedField(field);
    else
      handleNonSharedField(field);
  }

  private void handleSharedField(Field field) {
    changeSharedFieldInternalName(field);
    createSharedFieldGetter(field);
    createSharedFieldSetter(field);
    moveSharedFieldInitializer(field);
    makeSharedFieldProtectedAndVolatile(field);
  }

  // field.getAst().getName() changes, field.getName() remains the same
  private void changeSharedFieldInternalName(Field field) {
    field.getAst().rename(InternalIdentifiers.getSharedFieldName(field.getName()));
  }

  private void createSharedFieldGetter(Field field) {
    String getterName = "get" + MetaClassHelper.capitalize(field.getName());
    MethodNode getter = spec.getAst().getMethod(getterName, Parameter.EMPTY_ARRAY);
    if (getter != null) {
      errorReporter.error(field.getAst(),
          "@Shared field '%s' conflicts with method '%s'; please rename either of them",
          field.getName(), getter.getName());
      return;
    }

    BlockStatement getterBlock = new BlockStatement();
    getter = new MethodNode(getterName, determineVisibilityForSharedFieldAccessor(field) | Opcodes.ACC_SYNTHETIC,
        ClassHelper.DYNAMIC_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, getterBlock);

    getterBlock.addStatement(
        new ReturnStatement(
            new ExpressionStatement(
                new AttributeExpression(
                    sharedInstanceRef,
                    // use internal name
                    new ConstantExpression(field.getAst().getName())))));

    getter.setSourcePosition(field.getAst());
    spec.getAst().addMethod(getter);
  }

  private void createSharedFieldSetter(Field field) {
    String setterName = "set" + MetaClassHelper.capitalize(field.getName());
    Parameter[] params = new Parameter[] { new Parameter(field.getAst().getType(), "$spock_value") };
    MethodNode setter = spec.getAst().getMethod(setterName, params);
    if (setter != null) {
      errorReporter.error(field.getAst(),
                "@Shared field '%s' conflicts with method '%s'; please rename either of them",
                field.getName(), setter.getName());
      return;
    }

    BlockStatement setterBlock = new BlockStatement();
    setter = new MethodNode(setterName, determineVisibilityForSharedFieldAccessor(field) | Opcodes.ACC_SYNTHETIC,
        ClassHelper.VOID_TYPE, params, ClassNode.EMPTY_ARRAY, setterBlock);

    setterBlock.addStatement(
        new ExpressionStatement(
            new BinaryExpression(
                new AttributeExpression(
                    sharedInstanceRef,
                    // use internal name
                    new ConstantExpression(field.getAst().getName())),
                Token.newSymbol(Types.ASSIGN, -1, -1),
                new VariableExpression("$spock_value"))));

    setter.setSourcePosition(field.getAst());
    spec.getAst().addMethod(setter);
  }

  // we try to use the visibility of the original field, but change
  // private to protected to solve http://issues.spockframework.org/detail?id=151
  private int determineVisibilityForSharedFieldAccessor(Field field) {
    if (field.getOwner() == null) { // true field
      int visibility = AstUtil.getVisibility(field.getAst());
      if (visibility == Opcodes.ACC_PRIVATE) visibility = Opcodes.ACC_PROTECTED;
      return visibility;
    } else { // property
      return Opcodes.ACC_PUBLIC;
    }
  }

  private void moveSharedFieldInitializer(Field field) {
    if (field.getAst().getInitialValueExpression() != null)
      moveInitializer(field, getSharedInitializerMethod(), sharedFieldInitializerCount++);
  }

  /*
     We would prefer to make shared fields private, but this doesn't work in the following case:

     class BaseSpec {
       public sharedInstance
       private sharedField = 5

       def sharedFieldGetter() { sharedInstance.sharedField }
     }

     class DerivedSpec extends BaseSpec {}

     // when DerivedSpec is run:
     
     def sharedInstance = new DerivedSpec()

     def spec = new DerivedSpec()
     spec.sharedInstance = sharedInstance

     spec.sharedFieldGetter() // would normally occur within a specification

     groovy.lang.MissingPropertyException: No such property: sharedField for class: DerivedSpec

     Solutions:
     1. Make sharedField protected
     2. Route all accesses to sharedField through sharedInstance's (!) sharedFieldGetter()
        (from there, sharedField can be accessed w/o qualification)

     Reasons why we chose 1:
     - A bit easier to implement
     - We might at some point decide that we need to reroute some
       VariableExpression/AttributeExpression/PropertyExpression that accesses
       sharedField directly (but on the wrong instance). However, these kinds of
       expressions cannot be replaced with a MethodCallExpression (calling
       sharedFieldGetter/Setter). Instead, we would have to replace them with
       an AttributeExpression/PropertyExpression of the form sharedInstance.sharedField,
       which would again require as to make sharedField protected.

     If we find that making shared fields protected can potentially cause name clashes within
     an inheritance chain, we should make sure that shared field names are unique within
     a chain. For example, this could be done by mixing in a number that measures
     the distance between the declaring class and class Specification. (That's how it's done
     in Groovy.)
   */
  private static void makeSharedFieldProtectedAndVolatile(Field field) {
    AstUtil.setVisibility(field.getAst(), Opcodes.ACC_PROTECTED);
    field.getAst().setModifiers(field.getAst().getModifiers() | Opcodes.ACC_VOLATILE);
  }

  private void handleNonSharedField(Field field) {
    if (field.getAst().getInitialValueExpression() != null)
      moveInitializer(field, getInitializerMethod(), fieldInitializerCount++);
  }

  /*
   * Moves initialization of the given field to the given position of the first block of the given method.
   */
  private void moveInitializer(Field field, Method method, int position) {
    method.getFirstBlock().getAst().add(position,
        new ExpressionStatement(
            new FieldInitializationExpression(field.getAst())));
    field.getAst().setInitialValueExpression(null);
  }

  public void visitMethod(Method method) {
    this.method = method;
    methodHasCondition = false;
    movedStatsBackToMethod = false;

    if (method instanceof FixtureMethod) {
      checkFieldAccessInFixtureMethod(method);
      // de-virtualize method s.t. multiple fixture methods along hierarchy can be called independently
      AstUtil.setVisibility(method.getAst(), Opcodes.ACC_PRIVATE);
    } else if (method instanceof FeatureMethod) {
      transplantMethod(method);
      handleWhereBlock(method);
    }
  }

  private void checkFieldAccessInFixtureMethod(Method method) {
    if (method != spec.getSetupSpecMethod() && method != spec.getCleanupSpecMethod()) return;

    new InstanceFieldAccessChecker(this).check(method);
  }

  private void transplantMethod(Method method) {
    FeatureMethod feature = (FeatureMethod) method;
    MethodNode oldAst = feature.getAst();
    MethodNode newAst = copyMethod(oldAst, createInternalName(feature));
    spec.getAst().addMethod(newAst);
    feature.setAst(newAst);
    AstUtil.deleteMethod(spec.getAst(), oldAst);
  }

  private String createInternalName(FeatureMethod feature) {
    return String.format("$spock_feature_%d_%d", specDepth, feature.getOrdinal());
  }

  private MethodNode copyMethod(MethodNode method, String newName) {
    // can't hurt to set return type to void
    MethodNode newMethod = new MethodNode(newName, method.getModifiers(),
        ClassHelper.VOID_TYPE, method.getParameters(), method.getExceptions(), method.getCode());

    newMethod.addAnnotations(method.getAnnotations());
    newMethod.setSynthetic(method.isSynthetic());
    newMethod.setDeclaringClass(method.getDeclaringClass());
    newMethod.setSourcePosition(method);
    newMethod.setVariableScope(method.getVariableScope());
    newMethod.setGenericsTypes(method.getGenericsTypes());
    newMethod.setAnnotationDefault(method.hasAnnotationDefault());

    return newMethod;
  }

  // where block must be rewritten before all other blocks
  // s.t. missing method parameters are added; these parameters
  // will then be used by DeepStatementRewriter.fixupVariableScope()
  private void handleWhereBlock(Method method) {
    Block block = method.getLastBlock();
    if (!(block instanceof WhereBlock)) {
      Parameter[] params = method.getAst().getParameters();
      if (params.length > 0)
        errorReporter.error(params[0], "Feature methods without 'where' block may not declare parameters");
      return;
    }

    new DeepStatementRewriter(this).visitBlock(block);
    WhereBlockRewriter.rewrite((WhereBlock) block, this);
  }

  public void visitMethodAgain(Method method) {
    this.block = null;
    
    if (methodHasCondition)
      defineValueRecorder(method.getStatements());

    if (!movedStatsBackToMethod)
      for (Block b : method.getBlocks())
        method.getStatements().addAll(b.getAst());

    // for global required interactions
    if (method instanceof FeatureMethod)
      method.getStatements().add(createMockControllerCall(MockController.LEAVE_SCOPE));
  }

  public void visitAnyBlock(Block block) {
    this.block = block;
    if (block instanceof ExpectBlock || block instanceof ThenBlock) return;

    DeepStatementRewriter deep = new DeepStatementRewriter(this);
    deep.visitBlock(block);
    methodHasCondition |= deep.isConditionFound();
  }

  public void visitExpectBlock(ExpectBlock block) {
    ListIterator iter = block.getAst().listIterator();

    while(iter.hasNext()) {
      Statement stat = iter.next();

      DeepStatementRewriter deep = new DeepStatementRewriter(this);
      Statement newStat = deep.replace(stat);
      methodHasCondition |= deep.isConditionFound();

      if (stat instanceof AssertStatement)
        iter.set(newStat);
      else if (isExceptionCondition(newStat)) {
        errorReporter.error(newStat, "Exception conditions are only allowed in 'then' blocks");
      } else if (statHasInteraction(newStat, deep))
        errorReporter.error(newStat, "Interactions are only allowed in 'then' blocks");
      else if (isImplicitCondition(newStat)) {
        checkIsValidCondition(newStat);
        iter.set(rewriteImplicitCondition(newStat));
        methodHasCondition = true;
      }
    }
  }

  public void visitThenBlock(ThenBlock block) {
    ListIterator iter = block.getAst().listIterator();
    List interactions = new ArrayList();
    if (block.isFirstInChain()) thenBlockHasExceptionCondition = false;

    while(iter.hasNext()) {
      Statement stat = iter.next();
      DeepStatementRewriter deep = new DeepStatementRewriter(this);
      Statement newStat = deep.replace(stat);
      methodHasCondition |= deep.isConditionFound();

      if (stat instanceof AssertStatement)
        iter.set(newStat);
      else if (isExceptionCondition(newStat)) {
        rewriteExceptionCondition(newStat);
        if (!thenBlockHasExceptionCondition) {
          rewriteWhenBlockForExceptionCondition(block.getPrevious(WhenBlock.class));
          thenBlockHasExceptionCondition = true;
        }
      } else if (statHasInteraction(newStat, deep)) {
        interactions.add(newStat);
        iter.remove();
      } else if (isImplicitCondition(newStat)) {
        checkIsValidCondition(newStat);
        iter.set(rewriteImplicitCondition(newStat));
        methodHasCondition = true;
      }
    }
    
    insertInteractions(interactions, block);
  }

  private boolean isImplicitCondition(Statement stat) {
    return stat instanceof ExpressionStatement
        && !(((ExpressionStatement)stat).getExpression() instanceof DeclarationExpression);
  }

  private void checkIsValidCondition(Statement stat) {
    BinaryExpression binExpr = AstUtil.getExpression(stat, BinaryExpression.class);
    if (binExpr == null) return;

    if (Types.ofType(binExpr.getOperation().getType(), Types.ASSIGNMENT_OPERATOR)) {
      errorReporter.error(stat, "Expected a condition, but found an assignment. Did you intend to write '==' ?");
    }
  }

  private Statement rewriteImplicitCondition(Statement stat) {
    return ConditionRewriter.rewriteImplicitCondition((ExpressionStatement)stat, this);
  }

  private boolean isExceptionCondition(Statement stat) {
    Expression expr = AstUtil.getExpression(stat, Expression.class);
    return expr != null && AstUtil.isBuiltinMemberAssignmentOrCall(expr, Identifiers.THROWN, 0, 1);
  }

  private void rewriteExceptionCondition(Statement stat) {
    if (thenBlockHasExceptionCondition) {
      errorReporter.error(stat, "A 'then' block may only have one exception condition");
      return;
    }

    Expression expr = AstUtil.getExpression(stat, Expression.class);
    assert expr != null;
    try {
      AstUtil.expandBuiltinMemberAssignmentOrCall(expr, thrownExceptionRef);
    } catch (InvalidSpecCompileException e) {
      errorReporter.error(e);
    }
  }

  private boolean statHasInteraction(Statement stat, DeepStatementRewriter deep) {
    if (deep.isInteractionFound()) return true;

    Expression expr = AstUtil.getExpression(stat, Expression.class);
    return expr != null && AstUtil.isBuiltinMemberCall(expr, Identifiers.INTERACTION, 0, 1);
  }

  private void insertInteractions(List interactions, ThenBlock block) {
    if (interactions.isEmpty()) return;

    List statsBeforeWhenBlock = block.getPrevious(WhenBlock.class).getPrevious().getAst();

    statsBeforeWhenBlock.add(createMockControllerCall(
        block.isFirstInChain() ? MockController.ENTER_SCOPE : MockController.ADD_BARRIER));

    statsBeforeWhenBlock.addAll(interactions);

    if (block.isFirstInChain())
      // insert at beginning of then-block rather than end of when-block
      // s.t. it's outside of try-block inserted for exception conditions
      block.getAst().add(0, createMockControllerCall(MockController.LEAVE_SCOPE));
  }

  private Statement createMockControllerCall(String methodName) {
    return new ExpressionStatement(
        new MethodCallExpression(
            mockControllerRef,
            methodName,
            ArgumentListExpression.EMPTY_ARGUMENTS));
  }

  public void visitCleanupBlock(CleanupBlock block) {
    for (Block b : method.getBlocks()) {
      if (b == block) break;
      moveVariableDeclarations(b.getAst(), method.getStatements());
    }

    List tryStats = new ArrayList();
    for (Block b : method.getBlocks()) {
      if (b == block) break;
      tryStats.addAll(b.getAst());
    }

    List finallyStats = new ArrayList();
    finallyStats.addAll(block.getAst());

    TryCatchStatement tryFinally =
        new TryCatchStatement(
            new BlockStatement(tryStats, new VariableScope()),
            new BlockStatement(finallyStats, new VariableScope()));

    method.getStatements().add(tryFinally);

    // a cleanup-block may only be followed by a where-block, whose
    // statements are copied to newly generated methods rather than
    // the original method
    movedStatsBackToMethod = true;
  }

  // IRewriteResources members

  public Spec getCurrentSpec() {
    return spec;
  }

  public Method getCurrentMethod() {
    return method;
  }

  public Block getCurrentBlock() {
    return block;
  }

  public void defineValueRecorder(List stats) {
    // recorder variable needs to be defined in outermost scope,
    // hence we insert it at the beginning of the block
    stats.add(0,
        new ExpressionStatement(
            new DeclarationExpression(
                new VariableExpression("$spock_valueRecorder"),
                Token.newSymbol(Types.ASSIGN, -1, -1),
                new ConstructorCallExpression(
                    nodeCache.ValueRecorder,
                    ArgumentListExpression.EMPTY_ARGUMENTS))));
  }

  public VariableExpression captureOldValue(Expression oldValue) {
    VariableExpression var = new OldValueExpression(oldValue, "$spock_oldValue" + oldValueCount++);
    DeclarationExpression decl = new DeclarationExpression(
        var,
        Token.newSymbol(Types.ASSIGN, -1, -1),
        oldValue);
    decl.setSourcePosition(oldValue);

    // add declaration at end of block immediately preceding when-block
    // avoids any problems if when-block gets wrapped in try-statement
    block.getPrevious().getPrevious().getAst().add(new ExpressionStatement(decl));
    return var;
  }

  public VariableExpression getMockControllerRef() {
    return mockControllerRef;
  }

  public AstNodeCache getAstNodeCache() {
    return nodeCache;
  }

  private FixtureMethod getInitializerMethod() {
    if (spec.getInitializerMethod() == null) {
      // method is private s.t. multiple initializer methods along hierarchy can be called independently
      MethodNode gMethod = new MethodNode(InternalIdentifiers.INITIALIZER_METHOD, Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC,
          ClassHelper.DYNAMIC_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement());
      spec.getAst().addMethod(gMethod);
      FixtureMethod method = new FixtureMethod(spec, gMethod);
      method.addBlock(new AnonymousBlock(method));
      spec.setInitializerMethod(method);
    }

    return spec.getInitializerMethod();
  }

  public String getSourceText(ASTNode node) {
    return lookup.lookup(node);
  }

  public ErrorReporter getErrorReporter() {
    return errorReporter;
  }

  private FixtureMethod getSharedInitializerMethod() {
    if (spec.getSharedInitializerMethod() == null) {
      // method is private s.t. multiple initializer methods along hierarchy can be called independently
      MethodNode gMethod = new MethodNode(InternalIdentifiers.SHARED_INITIALIZER_METHOD, Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC,
          ClassHelper.DYNAMIC_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement());
      spec.getAst().addMethod(gMethod);
      FixtureMethod method = new FixtureMethod(spec, gMethod);
      method.addBlock(new AnonymousBlock(method));
      spec.setSharedInitializerMethod(method);
    }

    return spec.getSharedInitializerMethod();
  }

  private void rewriteWhenBlockForExceptionCondition(WhenBlock block) {
    List tryStats = block.getAst();
    List blockStats = new ArrayList();
    block.setAst(blockStats);

    blockStats.add(
        new ExpressionStatement(
            new BinaryExpression(
                thrownExceptionRef,
                Token.newSymbol(Types.ASSIGN, -1, -1),
                ConstantExpression.NULL)));

    // ensure variables remain in same scope
    // by moving variable defs to the very beginning of the method, they don't
    // need to be moved again if feature method also has a cleanup-block
    moveVariableDeclarations(tryStats, method.getStatements());

    TryCatchStatement tryCatchStat =
        new TryCatchStatement(
            new BlockStatement(tryStats, new VariableScope()),
            new BlockStatement());

    blockStats.add(tryCatchStat);

    tryCatchStat.addCatch(
        new CatchStatement(
            new Parameter(nodeCache.Throwable, "$spock_ex"),
            new BlockStatement(
                Arrays. asList(
                    new ExpressionStatement(
                    new BinaryExpression(
                        thrownExceptionRef,
                        Token.newSymbol(Types.ASSIGN, -1, -1),
                        new VariableExpression("$spock_ex")))),
                new VariableScope())));
  }

  /*
   * Moves variable declarations from one statement list to another. Initializer
   * expressions are kept at their former place.
   */
  private static void moveVariableDeclarations(List from, List to) {
    for (Statement stat : from) {
      if (!(stat instanceof ExpressionStatement)) continue;
      ExpressionStatement exprStat = (ExpressionStatement)stat;
      if (!(exprStat.getExpression() instanceof DeclarationExpression)) continue;
      DeclarationExpression declExpr = (DeclarationExpression)exprStat.getExpression();

      exprStat.setExpression(
          new BinaryExpression(
              new VariableExpression(declExpr.getVariableExpression().getName()),
              Token.newSymbol(Types.ASSIGN, -1, -1),
              declExpr.getRightExpression()));

      declExpr.setRightExpression(ConstantExpression.NULL);
      to.add(new ExpressionStatement(declExpr));
    }
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/SpockTransform.java000077500000000000000000000061061202022523300322770ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.List;

import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.control.*;
import org.codehaus.groovy.transform.ASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;

import org.spockframework.compiler.model.Spec;
import org.spockframework.util.VersionChecker;

/**
 * AST transformation for rewriting Spock specifications. Runs after phase
 * SEMANTIC_ANALYSIS, which means that the AST is semantically accurate
 * and already decorated with reflection information. On the flip side,
 * because types and variables have already been resolved,
 * program elements like import statements and variable definitions
 * can no longer be manipulated at will.
 *
 * @author Peter Niederwieser
 */
@SuppressWarnings("UnusedDeclaration")
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class SpockTransform implements ASTTransformation {
  public SpockTransform() {
    VersionChecker.checkGroovyVersion("compiler plugin");
  }

  public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
    new Impl().visit(nodes, sourceUnit);
  }

  // use of nested class defers linking until after groovy version check
  private static class Impl {
    final static AstNodeCache nodeCache = new AstNodeCache();

    void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
      ErrorReporter errorReporter = new ErrorReporter(sourceUnit);
      SourceLookup sourceLookup = new SourceLookup(sourceUnit);

      try {
        ModuleNode module = (ModuleNode) nodes[0];
        @SuppressWarnings("unchecked")
        List classes = module.getClasses();

        for (ClassNode clazz : classes)
          if (isSpec(clazz)) processSpec(clazz, errorReporter, sourceLookup);
      } finally {
        sourceLookup.close();
      }
    }

    boolean isSpec(ClassNode clazz) {
      return clazz.isDerivedFrom(nodeCache.Specification);
    }

    void processSpec(ClassNode clazz, ErrorReporter errorReporter, SourceLookup sourceLookup) {
      try {
        Spec spec = new SpecParser(errorReporter).build(clazz);
        spec.accept(new SpecRewriter(nodeCache, sourceLookup, errorReporter));
        spec.accept(new SpecAnnotator(nodeCache));
      } catch (Exception e) {
        errorReporter.error(
            "Unexpected error during compilation of spec '%s'. Maybe you have used invalid Spock syntax? Anyway, please file a bug report at http://issues.spockframework.org.",
            e, clazz.getName());
      }
    }
  }
}StatementReplacingVisitorSupport.java000066400000000000000000000101641202022523300360070ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.List;
import java.util.ListIterator;

import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
import org.codehaus.groovy.ast.stmt.*;
import org.codehaus.groovy.control.SourceUnit;

/**
 * Adds the ability to replace statements.
 *
 * @author Peter Niederwieser
 */
// Implementation note: It is only necessary to override visit methods
// for AST nodes that reference statements. For ClosureExpression we rely on
// the assumption that it always references a BlockStatement and hence our
// visitBlockStatement() method gets called.
public abstract class StatementReplacingVisitorSupport extends ClassCodeVisitorSupport {
  private Statement replacement;

  /**
   * Visits the specified statement. If the statement's visit method calls
   * replaceVisitedMethodWith(), the statement will be replaced.
   */
  public Statement replace(Statement stat) {
    replacement = null;
    stat.visit(this);
    Statement result = replacement == null ? stat : replacement;
    replacement = null;
    return result;
  }

  /**
   * Visits the statements in the specified mutable list. If a statement's
   * visit method calls replaceVisitedMethodWith(), the statement will be
   * replaced.
   */
  @SuppressWarnings("unchecked")
  protected  void replaceAll(List stats) {
    ListIterator iter = stats.listIterator();
    while (iter.hasNext())
      iter.set((T) replace(iter.next()));
  }

  /**
   * Replaces the currently visited statement with the specified statement.
   */
  protected void replaceVisitedStatementWith(Statement other) {
    replacement = other;
  }

  @SuppressWarnings("unchecked")  
  @Override
  public void visitBlockStatement(BlockStatement stat) {
    replaceAll(stat.getStatements());
  }

  @Override
  public void visitForLoop(ForStatement stat) {
    stat.getCollectionExpression().visit(this);
    stat.setLoopBlock(replace(stat.getLoopBlock()));
  }

  @Override
  public void visitWhileLoop(WhileStatement stat) {
    stat.getBooleanExpression().visit(this);
    stat.setLoopBlock(replace(stat.getLoopBlock()));
  }

  @Override
  public void visitDoWhileLoop(DoWhileStatement stat) {
    stat.getBooleanExpression().visit(this);
    stat.setLoopBlock(replace(stat.getLoopBlock()));
  }

  @Override
  public void visitIfElse(IfStatement stat) {
    stat.getBooleanExpression().visit(this);
    stat.setIfBlock(replace(stat.getIfBlock()));
    stat.setElseBlock(replace(stat.getElseBlock()));
  }

  @SuppressWarnings("unchecked")
  @Override
  public void visitTryCatchFinally(TryCatchStatement stat) {
    stat.setTryStatement(replace(stat.getTryStatement()));
    replaceAll(stat.getCatchStatements());
    stat.setFinallyStatement(replace(stat.getFinallyStatement()));
  }

  @SuppressWarnings("unchecked")
  @Override
  public void visitSwitch(SwitchStatement stat) {
    stat.getExpression().visit(this);
    replaceAll(stat.getCaseStatements());
    stat.setDefaultStatement(replace(stat.getDefaultStatement()));
  }

  @Override
  public void visitCaseStatement(CaseStatement stat) {
    stat.getExpression().visit(this);
    stat.setCode(replace(stat.getCode()));
  }

  @Override
  public void visitSynchronizedStatement(SynchronizedStatement stat) {
    stat.getExpression().visit(this);
    stat.setCode(replace(stat.getCode()));
  }

  @Override
  public void visitCatchStatement(CatchStatement stat) {
    stat.setCode(replace(stat.getCode()));
  }

  @Override
  protected SourceUnit getSourceUnit() {
    throw new UnsupportedOperationException("getSourceUnit");
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/WhereBlockRewriter.java000077500000000000000000000347521202022523300331050ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler;

import java.util.*;

import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.*;
import org.codehaus.groovy.syntax.Token;
import org.codehaus.groovy.syntax.Types;
import org.objectweb.asm.Opcodes;

import org.spockframework.compiler.model.WhereBlock;
import org.spockframework.runtime.model.DataProviderMetadata;
import org.spockframework.util.*;

/**
 *
 * @author Peter Niederwieser
 */
public class WhereBlockRewriter {
  private final WhereBlock whereBlock;
  private final IRewriteResources resources;
  private final InstanceFieldAccessChecker instanceFieldAccessChecker;

  private int dataProviderCount = 0;
  // parameters of the data processor method (one for each data provider)
  private final List dataProcessorParams = new ArrayList();
  // statements of the data processor method (one for each parameterization variable)
  private final List dataProcessorStats = new ArrayList();
  // parameterization variables of the data processor method
  private final List dataProcessorVars = new ArrayList();

  private WhereBlockRewriter(WhereBlock whereBlock, IRewriteResources resources) {
    this.whereBlock = whereBlock;
    this.resources = resources;
    instanceFieldAccessChecker = new InstanceFieldAccessChecker(resources);
  }

  public static void rewrite(WhereBlock block, IRewriteResources resources) {
    new WhereBlockRewriter(block, resources).rewrite();
  }

  private void rewrite() {
    ListIterator stats = whereBlock.getAst().listIterator();
    while (stats.hasNext())
      try {
        rewriteWhereStat(stats);
      } catch (InvalidSpecCompileException e) {
        resources.getErrorReporter().error(e);
      }

    whereBlock.getAst().clear();
    handleFeatureParameters();
    createDataProcessorMethod();
  }

  private void rewriteWhereStat(ListIterator stats) throws InvalidSpecCompileException {
    Statement stat = stats.next();
    BinaryExpression binExpr = AstUtil.getExpression(stat, BinaryExpression.class);
    if (binExpr == null || binExpr.getClass() != BinaryExpression.class) // don't allow subclasses like DeclarationExpression
      notAParameterization(stat);

    @SuppressWarnings("ConstantConditions")
    int type = binExpr.getOperation().getType();

    if (type == Types.LEFT_SHIFT) {
      Expression leftExpr = binExpr.getLeftExpression();
      if (leftExpr instanceof VariableExpression)
        rewriteSimpleParameterization(binExpr, stat);
      else if (leftExpr instanceof ListExpression)
        rewriteMultiParameterization(binExpr, stat);
      else notAParameterization(stat);
    } else if (type == Types.ASSIGN)
      rewriteDerivedParameterization(binExpr, stat);
    else if (getOrExpression(binExpr) != null) {
      stats.previous();
      rewriteTableLikeParameterization(stats);
    }
    else notAParameterization(stat);
  }

  private void createDataProviderMethod(Expression dataProviderExpr, int nextDataVariableIndex) {
    instanceFieldAccessChecker.check(dataProviderExpr);

    MethodNode method =
        new MethodNode(
            InternalIdentifiers.getDataProviderName(whereBlock.getParent().getAst().getName(), dataProviderCount++),
            Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC,
            ClassHelper.OBJECT_TYPE,
            Parameter.EMPTY_ARRAY,
            ClassNode.EMPTY_ARRAY,
            new BlockStatement(
                Arrays. asList(
                    new ReturnStatement(
                        new ExpressionStatement(dataProviderExpr))),
                new VariableScope()));

    method.addAnnotation(createDataProviderAnnotation(dataProviderExpr, nextDataVariableIndex));
    whereBlock.getParent().getParent().getAst().addMethod(method);
  }

  private AnnotationNode createDataProviderAnnotation(Expression dataProviderExpr, int nextDataVariableIndex) {
    AnnotationNode ann = new AnnotationNode(resources.getAstNodeCache().DataProviderMetadata);
    ann.addMember(DataProviderMetadata.LINE, new ConstantExpression(dataProviderExpr.getLineNumber()));
    List dataVariableNames = new ArrayList();
    for (int i = nextDataVariableIndex; i < dataProcessorVars.size(); i++)
      dataVariableNames.add(new ConstantExpression(dataProcessorVars.get(i).getName()));
    ann.addMember(DataProviderMetadata.DATA_VARIABLES, new ListExpression(dataVariableNames));
    return ann;
  }

  private Parameter createDataProcessorParameter() {
    Parameter p = new Parameter(ClassHelper.DYNAMIC_TYPE, "$spock_p" + dataProcessorParams.size());
    dataProcessorParams.add(p);
    return p;
  }

  // generates: arg = argMethodParam
  private void rewriteSimpleParameterization(BinaryExpression binExpr, ASTNode sourcePos)
      throws InvalidSpecCompileException {
    int nextDataVariableIndex = dataProcessorVars.size();
    Parameter dataProcessorParameter = createDataProcessorParameter();
    VariableExpression arg = (VariableExpression) binExpr.getLeftExpression();

    VariableExpression dataVar = createDataProcessorVariable(arg, sourcePos);
    ExpressionStatement exprStat = new ExpressionStatement(
        new DeclarationExpression(
            dataVar,
            Token.newSymbol(Types.ASSIGN, -1, -1),
            new VariableExpression(dataProcessorParameter)));
    exprStat.setSourcePosition(sourcePos);
    dataProcessorStats.add(exprStat);

    createDataProviderMethod(binExpr.getRightExpression(), nextDataVariableIndex);
  }

  // generates:
  // arg0 = argMethodParam.getAt(0)
  // arg1 = argMethodParam.getAt(1)
  private void rewriteMultiParameterization(BinaryExpression binExpr, Statement enclosingStat)
      throws InvalidSpecCompileException {
    int nextDataVariableIndex = dataProcessorVars.size();
    Parameter dataProcessorParameter = createDataProcessorParameter();
    ListExpression list = (ListExpression) binExpr.getLeftExpression();

    @SuppressWarnings("unchecked")
    List listElems = list.getExpressions();
    for (int i = 0; i < listElems.size(); i++) {
      Expression listElem = listElems.get(i);
      if (AstUtil.isWildcardRef(listElem)) continue;
      VariableExpression dataVar = createDataProcessorVariable(listElem, enclosingStat);
      ExpressionStatement exprStat =
          new ExpressionStatement(
              new DeclarationExpression(
                  dataVar,
                  Token.newSymbol(Types.ASSIGN, -1, -1),
                  new MethodCallExpression(
                      new VariableExpression(dataProcessorParameter),
                      "getAt",
                      new ConstantExpression(i))));
      exprStat.setSourcePosition(enclosingStat);
      dataProcessorStats.add(exprStat);
    }

    createDataProviderMethod(binExpr.getRightExpression(), nextDataVariableIndex);
  }

  private void rewriteDerivedParameterization(BinaryExpression parameterization, Statement enclosingStat)
      throws InvalidSpecCompileException {
    VariableExpression dataVar = createDataProcessorVariable(parameterization.getLeftExpression(), enclosingStat);

    ExpressionStatement exprStat =
        new ExpressionStatement(
            new DeclarationExpression(
                dataVar,
                Token.newSymbol(Types.ASSIGN, -1, -1),
                parameterization.getRightExpression()));

    exprStat.setSourcePosition(enclosingStat);
    dataProcessorStats.add(exprStat);
  }

  private void rewriteTableLikeParameterization(ListIterator stats) throws InvalidSpecCompileException {
    LinkedList> rows = new LinkedList>();

    while (stats.hasNext()) {
      Statement stat = stats.next();
      BinaryExpression orExpr = getOrExpression(stat);
      if (orExpr == null) {
        stats.previous();
        break;
      }

      List row = new ArrayList();
      splitRow(orExpr, row);
      if (rows.size() > 0 && rows.getLast().size() != row.size())
        throw new InvalidSpecCompileException(stat, String.format("Row in data table has wrong number of elements (%s instead of %s)", row.size(), rows.getLast().size()));
      rows.add(row);
    }

    for (List column : transposeTable(rows))
      turnIntoSimpleParameterization(column);
  }

  List> transposeTable(List> rows) {
    List> columns = new ArrayList>();
    if (rows.isEmpty()) return columns;

    for (int i = 0; i < rows.get(0).size(); i++)
      columns.add(new ArrayList());

    for (List row : rows)
      for (int i = 0; i < row.size(); i++)
        columns.get(i).add(row.get(i));

    return columns;
  }

  private void turnIntoSimpleParameterization(List column) throws InvalidSpecCompileException {
    VariableExpression varExpr = AstUtil.asInstance(column.get(0), VariableExpression.class);
    if (varExpr == null)
      throw new InvalidSpecCompileException(column.get(0),
          "Header of data table may only contain variable names");

    ListExpression listExpr = new ListExpression(column.subList(1, column.size()));
    BinaryExpression binExpr = new BinaryExpression(varExpr, Token.newSymbol(Types.LEFT_SHIFT, -1, -1), listExpr);
    // NOTE: varExpr may not be the "perfect" source position here, but as long as we rewrite data tables
    // into simple parameterizations, it seems like the best approximation; also this source position is
    // unlikely to make it into a compile error, because header variable has already been checked, and the
    // assignment itself is unlikely to cause a compile error. (It's more likely that the rval causes a
    // compile error, but the rval's source position is retained.)
    rewriteSimpleParameterization(binExpr, varExpr);
  }

  private void splitRow(Expression row, List parts) {
    BinaryExpression orExpr = getOrExpression(row);
    if (orExpr == null)
      parts.add(row);
    else {
      splitRow(orExpr.getLeftExpression(), parts);
      splitRow(orExpr.getRightExpression(), parts);
    }
  }
  
  private BinaryExpression getOrExpression(Statement stat) {
    Expression expr = AstUtil.getExpression(stat, Expression.class);
    return getOrExpression(expr);
  }
  
  private BinaryExpression getOrExpression(Expression expr) {
    BinaryExpression binExpr = AstUtil.asInstance(expr, BinaryExpression.class);  
    if (binExpr == null) return null;
    
    int binExprType = binExpr.getOperation().getType();
    if (binExprType == Types.BITWISE_OR || binExprType == Types.LOGICAL_OR) return binExpr;
    
    return null;
  }

  private VariableExpression createDataProcessorVariable(Expression varExpr, ASTNode sourcePos)
      throws InvalidSpecCompileException {
    if (!(varExpr instanceof VariableExpression))
      notAParameterization(sourcePos);

    VariableExpression typedVarExpr = (VariableExpression)varExpr;
    verifyDataProcessorVariable(typedVarExpr);

    VariableExpression result = new VariableExpression(typedVarExpr.getName(), typedVarExpr.getType());
    dataProcessorVars.add(result);
    return result;
  }

  private void verifyDataProcessorVariable(VariableExpression varExpr) {
    Variable accessedVar = varExpr.getAccessedVariable();

    if (accessedVar instanceof VariableExpression) { // local variable
      resources.getErrorReporter().error(varExpr, "A variable named '%s' already exists in this scope", varExpr.getName());
      return;
    }

    if (getDataProcessorVariable(varExpr.getName()) != null) {
      resources.getErrorReporter().error(varExpr, "Duplicate declaration of data variable '%s'", varExpr.getName());
      return;
    }

    if (whereBlock.getParent().getAst().getParameters().length > 0 && !(accessedVar instanceof Parameter)) {
      resources.getErrorReporter().error(varExpr,
          "Data variable '%s' needs to be declared as method parameter",
          varExpr.getName());
    }
  }

  private VariableExpression getDataProcessorVariable(String name) {
    for (VariableExpression var : dataProcessorVars)
      if (var.getName().equals(name)) return var;

    return null;
  }

  private void handleFeatureParameters() {
    Parameter[] parameters = whereBlock.getParent().getAst().getParameters();
    if (parameters.length == 0)
      addFeatureParameters();
    else
      checkAllParametersAreDataVariables(parameters);
  }

  private void checkAllParametersAreDataVariables(Parameter[] parameters) {
    for (Parameter param : parameters)
      if (getDataProcessorVariable(param.getName()) == null)
        resources.getErrorReporter().error(param, "Parameter '%s' does not refer to a data variable", param.getName());
  }

  private void addFeatureParameters() {
    Parameter[] parameters = new Parameter[dataProcessorVars.size()];
    for (int i = 0; i < dataProcessorVars.size(); i++)
      parameters[i] = new Parameter(ClassHelper.DYNAMIC_TYPE, dataProcessorVars.get(i).getName());
    whereBlock.getParent().getAst().setParameters(parameters);
  }

  @SuppressWarnings("unchecked")
  private void createDataProcessorMethod() {
    if (dataProcessorVars.isEmpty()) return;
    
    dataProcessorStats.add(
        new ReturnStatement(
            new ArrayExpression(
                ClassHelper.OBJECT_TYPE,
                (List)dataProcessorVars)));

    whereBlock.getParent().getParent().getAst().addMethod(
      new MethodNode(
          InternalIdentifiers.getDataProcessorName(whereBlock.getParent().getAst().getName()),
          Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC,
          ClassHelper.OBJECT_TYPE,
          dataProcessorParams.toArray(new Parameter[dataProcessorParams.size()]),
          ClassNode.EMPTY_ARRAY,
          new BlockStatement(
              dataProcessorStats,
              new VariableScope())));
  }

  private static void notAParameterization(ASTNode stat) throws InvalidSpecCompileException {
    throw new InvalidSpecCompileException(stat,
"where-blocks may only contain parameterizations (e.g. 'salary << [1000, 5000, 9000]; salaryk = salary / 1000')");
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/000077500000000000000000000000001202022523300275535ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/AnonymousBlock.java000066400000000000000000000022301202022523300333560ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

/**
 * A block without a label at the beginning of a method. Every Method
 * has a (possibly empty) AnonymousBlock as its first block.
 *
 * @author Peter Niederwieser
 */
public class AnonymousBlock extends Block {
  public AnonymousBlock(Method parent) {
    super(parent);
  }

  @Override
  public void accept(ISpecVisitor visitor) throws Exception {
    visitor.visitAnyBlock(this);
    visitor.visitAnonymousBlock(this);
  }

  public BlockParseInfo getParseInfo() {
    return BlockParseInfo.ANONYMOUS;
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/Block.java000077500000000000000000000043671202022523300314650ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

import java.util.ArrayList;
import java.util.List;

import org.codehaus.groovy.ast.stmt.Statement;

/**
 * AST node representing a block in a feature method. There are six kinds
 * of blocks: setup-block, expect-block, when-block, then-block, cleanup-block,
 * and where-block. 
 * 
 * @author Peter Niederwieser
 */
public abstract class Block extends Node> {
  private final List descriptions = new ArrayList(3);
  private Block prev;
  private Block next;

  public Block(Method parent) {
    super(parent, new ArrayList());
  }

  public List getDescriptions() {
    return descriptions;
  }

  public Block getPrevious() {
    return prev;
  }

  public void setPrevious(Block block) {
    prev = block;
  }

  public Block getNext() {
    return next;
  }

  public void setNext(Block block) {
    next = block;
  }

  public  T getPrevious(Class blockType) {
    Block block = prev;
    while (block != null && !blockType.isInstance(block)) block = block.prev;
    return blockType.cast(block);
  }

  public  T getNext(Class blockType) {
    Block block = next;
    while (block != null && !blockType.isInstance(block)) block = block.next;
    return blockType.cast(block);
  }

  public boolean isFirst() {
    return prev == null;
  }

  public boolean isLast() {
    return next == null;
  }

  public boolean isFirstInChain() {
    return isFirst() || getClass() != prev.getClass();
  }

  public abstract BlockParseInfo getParseInfo();
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/BlockParseInfo.java000066400000000000000000000067461202022523300332740ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

import java.util.EnumSet;

/**
 *
 * @author Peter Niederwieser
 */
public enum BlockParseInfo {
  AND {
    public EnumSet getSuccessors(Method method) {
      return method.getLastBlock().getParseInfo().getSuccessors(method);
    }
    public Block addNewBlock(Method method) {
      return method.getLastBlock();
    }
  },

  ANONYMOUS {
    public Block addNewBlock(Method method) {
      return method.addBlock(new AnonymousBlock(method));
    }
    public EnumSet getSuccessors(Method method) {
      return EnumSet.of(SETUP, GIVEN, EXPECT, WHEN, CLEANUP, WHERE, METHOD_END);
    }
  },

  SETUP {
    public Block addNewBlock(Method method) {
      return method.addBlock(new SetupBlock(method));
    }
    public EnumSet getSuccessors(Method method) {
      return EnumSet.of(AND, EXPECT, WHEN, CLEANUP, WHERE, METHOD_END);
    }
  },

  GIVEN {
    public Block addNewBlock(Method method) {
      return SETUP.addNewBlock(method);
    }
    public EnumSet getSuccessors(Method method) {
      return SETUP.getSuccessors(method);
    }
  },

  EXPECT {
    public Block addNewBlock(Method method) {
      return method.addBlock(new ExpectBlock(method));
    }
    public EnumSet getSuccessors(Method method) {
      return EnumSet.of(AND, WHEN, CLEANUP, WHERE, METHOD_END);
    }
  },

  WHEN {
    public Block addNewBlock(Method method) {
      return method.addBlock(new WhenBlock(method));
    }
    public EnumSet getSuccessors(Method method) {
      return EnumSet.of(AND, THEN);
    }
  },

  THEN {
    public Block addNewBlock(Method method) {
      return method.addBlock(new ThenBlock(method));
    }
    public EnumSet getSuccessors(Method method) {
      return EnumSet.of(AND, EXPECT, WHEN, THEN, CLEANUP, WHERE, METHOD_END);
    }
  },

  CLEANUP {
    public Block addNewBlock(Method method) {
      return method.addBlock(new CleanupBlock(method));
    }
    public EnumSet getSuccessors(Method method) {
      return EnumSet.of(AND, WHERE, METHOD_END);
    }
  },

  WHERE {
    public Block addNewBlock(Method method) {
      return method.addBlock(new WhereBlock(method));
    }
    public EnumSet getSuccessors(Method method) {
      return EnumSet.of(AND, METHOD_END);
    }
  },

  METHOD_END {
    public Block addNewBlock(Method method) {
      throw new UnsupportedOperationException("addNewBlock");
    }
    public EnumSet getSuccessors(Method method) {
      throw new UnsupportedOperationException("getSuccessors");
    }
    public String toString() {
      return "end-of-method";
    }
  };

  public String toString() {
    return super.toString().toLowerCase();
  }

  public abstract Block addNewBlock(Method method);

  public abstract EnumSet getSuccessors(Method method);
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/CleanupBlock.java000066400000000000000000000021571202022523300327650ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

/**
 * AST node representing a cleanup-block in a feature method.
 *
 * @author Peter Niederwieser
 */
public class CleanupBlock extends Block {
  public CleanupBlock(Method parent) {
    super(parent);
  }

  @Override
  public void accept(ISpecVisitor visitor) throws Exception {
    visitor.visitAnyBlock(this);
    visitor.visitCleanupBlock(this);
  }

  public BlockParseInfo getParseInfo() {
    return BlockParseInfo.CLEANUP;
  }
}spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/ExpectBlock.java000077500000000000000000000020111202022523300326160ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

/**
 *
 * @author Peter Niederwieser
 */
public class ExpectBlock extends Block {
  public ExpectBlock(Method parent) {
    super(parent);
  }

  @Override
  public void accept(ISpecVisitor visitor) throws Exception {
    visitor.visitAnyBlock(this);
    visitor.visitExpectBlock(this);
  }

  public BlockParseInfo getParseInfo() {
    return BlockParseInfo.EXPECT;
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/FeatureMethod.java000077500000000000000000000020701202022523300331540ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

import org.codehaus.groovy.ast.MethodNode;

/**
 * AST node representing a feature method.
 * 
 * @author Peter Niederwieser
 */
public class FeatureMethod extends Method {
  private final int ordinal;

  public FeatureMethod(Spec parent, MethodNode code, int ordinal) {
    super(parent, code);
    this.ordinal = ordinal;
  }

  public int getOrdinal() {
    return ordinal;
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/Field.java000066400000000000000000000032261202022523300314440ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.PropertyNode;

/**
 * AST node representing a user-defined instance field.
 * (A generated field underlying a user-defined property also counts as such.)
 *
 * @author Peter Niederwieser
 */
public class Field extends Node {
  private final int ordinal;
  private boolean isShared;
  private PropertyNode owner;

  public Field(Spec parent, FieldNode ast, int ordinal) {
    super(parent, ast);
    setName(ast.getName());
    this.ordinal = ordinal;
  }

  public int getOrdinal() {
    return ordinal;
  }

  public boolean isShared() {
    return isShared;
  }

  public void setShared(boolean shared) {
    isShared = shared;
  }

  // null for a true field that has no associated property
  public PropertyNode getOwner() {
    return owner;
  }

  public void setOwner(PropertyNode owner) {
    this.owner = owner;
  }

  @Override
  public void accept(ISpecVisitor visitor) throws Exception {
    visitor.visitField(this);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/FixtureMethod.java000077500000000000000000000020751202022523300332140ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

import org.codehaus.groovy.ast.MethodNode;

/**
 * AST node representing a fixture method. In source code, a fixture method
 * corresponds to an instance method named one of "setup", "cleanup",
 * "setupSpec", "cleanupSpec".
 * 
 * @author Peter Niederwieser
 */
public class FixtureMethod extends Method {
  public FixtureMethod(Spec parent, MethodNode code) {
    super(parent, code);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/HelperMethod.java000066400000000000000000000015511202022523300330000ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

import org.codehaus.groovy.ast.MethodNode;

/**
 *
 * @author Peter Niederwieser
 */
public class HelperMethod extends Method {
  public HelperMethod(Spec parent, MethodNode code) {
    super(parent, code);
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/ISpecVisitor.java000077500000000000000000000027321202022523300330100ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

/**
 * @author Peter Niederwieser
 */
public interface ISpecVisitor {
  void visitSpec(Spec spec) throws Exception;
  void visitSpecAgain(Spec spec) throws Exception;
  void visitField(Field field) throws Exception;
  void visitMethod(Method method) throws Exception;
  void visitMethodAgain(Method method) throws Exception;
  void visitAnyBlock(Block block) throws Exception;
  void visitAnonymousBlock(AnonymousBlock block) throws Exception;
  void visitSetupBlock(SetupBlock block) throws Exception;
  void visitExpectBlock(ExpectBlock block) throws Exception;
  void visitWhenBlock(WhenBlock block) throws Exception;
  void visitThenBlock(ThenBlock block) throws Exception;
  void visitCleanupBlock(CleanupBlock block) throws Exception;
  void visitWhereBlock(WhereBlock block) throws Exception;
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/Method.java000077500000000000000000000051351202022523300316450ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

import java.util.*;

import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.stmt.Statement;

import org.spockframework.compiler.AstUtil;

/**
 * AST node representing a Spec method (one of fixture method, feature method, helper method).
 * 
 * @author Peter Niederwieser
 */
public abstract class Method extends Node {
  private Block firstBlock;
  private Block lastBlock;

  public Method(Spec parent, MethodNode code) {
    super(parent, code);
    setName(code.getName());
  }

  public Block getFirstBlock() {
    return firstBlock;
  }

  public Block getLastBlock() {
    return lastBlock;
  }

  public List getStatements() {
    return AstUtil.getStatements(getAst());
  }

  public Iterable getBlocks() {
    return new BlockIterable(firstBlock);
  }

  public Block addBlock(Block block) {
    if (firstBlock == null)
      firstBlock = lastBlock = block;
    else {
      lastBlock.setNext(block);
      block.setPrevious(lastBlock);
      lastBlock = block;
    }
    return block;
  }

  @Override
  public void accept(ISpecVisitor visitor) throws Exception {
    visitor.visitMethod(this);
    for (Block b: getBlocks()) b.accept(visitor);
    visitor.visitMethodAgain(this);
  }
}

class BlockIterable implements Iterable {
  private final Block first;

  BlockIterable(Block first) {
    this.first = first;
  }

  public Iterator iterator() {
    return new Iterator() {
      Block block = first;

      public boolean hasNext() {
        return block != null;
      }

      public Block next() {
        if (hasNext()) {
          Block result = block;
          block = block.getNext();
          return result;
        } else
          throw new NoSuchElementException();
      }

      public void remove() {
        throw new UnsupportedOperationException("remove");
      }
    };
  }
}
spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/Node.java000077500000000000000000000031441202022523300313100ustar00rootroot00000000000000/*
 * Copyright 2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.spockframework.compiler.model;

/**
 * Base class for all SpecL AST nodes.
 * 
 * @author Peter Niederwieser
 */
public abstract class Node

{ private final P parent; private A ast; private String name; public Node(P parent, A ast) { this.parent = parent; this.ast = ast; } /** * The parent of this node. * @return the parent of this node */ public P getParent() { return parent; } /** * The Groovy AST representation of this node. * @return the Groovy AST representation of this node */ public A getAst() { return ast; } public void setAst(A ast) { this.ast = ast; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return getClass().getSimpleName() + ": " + name; } public abstract void accept(ISpecVisitor visitor) throws Exception; } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/SetupBlock.java000077500000000000000000000021511202022523300324730ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.compiler.model; /** * AST node representing a setup-block in a feature method. * * @author Peter Niederwieser */ public class SetupBlock extends Block { public SetupBlock(Method parent) { super(parent); } @Override public void accept(ISpecVisitor visitor) throws Exception { visitor.visitAnyBlock(this); visitor.visitSetupBlock(this); } public BlockParseInfo getParseInfo() { return BlockParseInfo.SETUP; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/Spec.java000077500000000000000000000057121202022523300313200ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.compiler.model; import java.util.ArrayList; import java.util.List; import org.codehaus.groovy.ast.ClassNode; /** * AST node representing a Spock specification. In source * code, a Spec corresponds to one class definition extends from class Specification. * * @author Peter Niederwieser */ public class Spec extends Node { private final List fields = new ArrayList(); private final List methods = new ArrayList(); private FixtureMethod initializerMethod; private FixtureMethod sharedInitializerMethod; private FixtureMethod setupMethod; private FixtureMethod cleanupMethod; private FixtureMethod setupSpecMethod; private FixtureMethod cleanupSpecMethod; public Spec(ClassNode code) { super(null, code); setName(code.getName()); } public List getFields() { return fields; } public List getMethods() { return methods; } public FixtureMethod getInitializerMethod() { return initializerMethod; } public void setInitializerMethod(FixtureMethod method) { initializerMethod = method; methods.add(method); } public FixtureMethod getSharedInitializerMethod() { return sharedInitializerMethod; } public void setSharedInitializerMethod(FixtureMethod method) { sharedInitializerMethod = method; methods.add(method); } public FixtureMethod getSetupMethod() { return setupMethod; } public void setSetupMethod(FixtureMethod method) { setupMethod = method; methods.add(method); } public FixtureMethod getCleanupMethod() { return cleanupMethod; } public void setCleanupMethod(FixtureMethod method) { cleanupMethod = method; methods.add(method); } public FixtureMethod getSetupSpecMethod() { return setupSpecMethod; } public void setSetupSpecMethod(FixtureMethod method) { setupSpecMethod = method; methods.add(method); } public FixtureMethod getCleanupSpecMethod() { return cleanupSpecMethod; } public void setCleanupSpecMethod(FixtureMethod method) { cleanupSpecMethod = method; methods.add(method); } @Override public void accept(ISpecVisitor visitor) throws Exception { visitor.visitSpec(this); for (Field f : fields) f.accept(visitor); for (Method m : methods) m.accept(visitor); visitor.visitSpecAgain(this); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/ThenBlock.java000077500000000000000000000021431202022523300322720ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.compiler.model; /** * AST node representing a then-block in a feature method. * * @author Peter Niederwieser */ public class ThenBlock extends Block { public ThenBlock(Method parent) { super(parent); } @Override public void accept(ISpecVisitor visitor) throws Exception { visitor.visitAnyBlock(this); visitor.visitThenBlock(this); } public BlockParseInfo getParseInfo() { return BlockParseInfo.THEN; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/WhenBlock.java000077500000000000000000000022761202022523300323040ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.compiler.model; /** * AST node representing a when-block in a feature method. * * @author Peter Niederwieser */ public class WhenBlock extends Block { public WhenBlock(Method parent) { super(parent); } @Override public void accept(ISpecVisitor visitor) throws Exception { visitor.visitAnyBlock(this); visitor.visitWhenBlock(this); } @Override public ThenBlock getNext() { return (ThenBlock)super.getNext(); } public BlockParseInfo getParseInfo() { return BlockParseInfo.WHEN; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/compiler/model/WhereBlock.java000077500000000000000000000017731202022523300324560ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.compiler.model; public class WhereBlock extends Block { public WhereBlock(Method parent) { super(parent); } @Override public void accept(ISpecVisitor visitor) throws Exception { visitor.visitAnyBlock(this); visitor.visitWhereBlock(this); } public BlockParseInfo getParseInfo() { return BlockParseInfo.WHERE; } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/gentyref/000077500000000000000000000000001202022523300264645ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/gentyref/CaptureType.java000066400000000000000000000021501202022523300315720ustar00rootroot00000000000000package org.spockframework.gentyref; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; /** * CaptureType represents a wildcard that has gone through capture conversion. * It is a custom subinterface of Type, not part of the java builtin Type hierarchy. * * @author Wouter Coekaerts */ public interface CaptureType extends Type { /** * Returns an array of Type objects representing the upper * bound(s) of this capture. This includes both the upper bound of a ? extends wildcard, * and the bounds declared with the type variable. * References to other (or the same) type variables in bounds coming from the type variable are * replaced by their matching capture. */ Type[] getUpperBounds(); /** * Returns an array of Type objects representing the * lower bound(s) of this type variable. This is the bound of a ? super wildcard. * This normally contains only one or no types; it is an array for consistency with {@link WildcardType#getLowerBounds()}. */ Type[] getLowerBounds(); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/gentyref/CaptureTypeImpl.java000066400000000000000000000037741202022523300324310ustar00rootroot00000000000000package org.spockframework.gentyref; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.Arrays; import java.util.List; class CaptureTypeImpl implements CaptureType { private final WildcardType wildcard; private final TypeVariable variable; private final Type[] lowerBounds; private Type[] upperBounds; /** * Creates an uninitialized CaptureTypeImpl. Before using this type, {@link #init(VarMap)} must be called. * @param wildcard The wildcard this is a capture of * @param variable The type variable where the wildcard is a parameter for. */ public CaptureTypeImpl(WildcardType wildcard, TypeVariable variable) { this.wildcard = wildcard; this.variable = variable; this.lowerBounds = wildcard.getLowerBounds(); } /** * Initialize this CaptureTypeImpl. * This is needed for type variable bounds referring to each other: we need the capture of the argument. */ void init(VarMap varMap) { ArrayList upperBoundsList = new ArrayList(); upperBoundsList.addAll(Arrays.asList(varMap.map(variable.getBounds()))); List wildcardUpperBounds = Arrays.asList(wildcard.getUpperBounds()); if (wildcardUpperBounds.size() > 0 && wildcardUpperBounds.get(0) == Object.class) { // skip the Object bound, we already have a first upper bound from 'variable' upperBoundsList.addAll(wildcardUpperBounds.subList(1, wildcardUpperBounds.size())); } else { upperBoundsList.addAll(wildcardUpperBounds); } upperBounds = new Type[upperBoundsList.size()]; upperBoundsList.toArray(upperBounds); } /* * @see com.googlecode.gentyref.CaptureType#getLowerBounds() */ public Type[] getLowerBounds() { return lowerBounds.clone(); } /* * @see com.googlecode.gentyref.CaptureType#getUpperBounds() */ public Type[] getUpperBounds() { assert upperBounds != null; return upperBounds.clone(); } @Override public String toString() { return "capture of " + wildcard; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/gentyref/GenericArrayTypeImpl.java000066400000000000000000000022351202022523300333700ustar00rootroot00000000000000package org.spockframework.gentyref; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Type; class GenericArrayTypeImpl implements GenericArrayType { private Type componentType; static Class createArrayType(Class componentType) { // there's no (clean) other way to create a array class, then create an instance of it return Array.newInstance(componentType, 0).getClass(); } static Type createArrayType(Type componentType) { if (componentType instanceof Class) { return createArrayType((Class)componentType); } else { return new GenericArrayTypeImpl(componentType); } } private GenericArrayTypeImpl(Type componentType) { super(); this.componentType = componentType; } public Type getGenericComponentType() { return componentType; } @Override public boolean equals(Object obj) { if (!(obj instanceof GenericArrayType)) return false; return componentType.equals(((GenericArrayType)obj).getGenericComponentType()); } @Override public int hashCode() { return componentType.hashCode() * 7; } @Override public String toString() { return componentType + "[]"; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/gentyref/GenericTypeReflector.java000066400000000000000000000420121202022523300334120ustar00rootroot00000000000000package org.spockframework.gentyref; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; /** * Utility class for doing reflection on types. * * @author Wouter Coekaerts */ public class GenericTypeReflector { private static final Type UNBOUND_WILDCARD = new WildcardTypeImpl(new Type[]{Object.class}, new Type[]{}); /** * Returns the erasure of the given type. */ public static Class erase(Type type) { if (type instanceof Class) { return (Class)type; } else if (type instanceof ParameterizedType) { return (Class)((ParameterizedType) type).getRawType(); } else if (type instanceof TypeVariable) { TypeVariable tv = (TypeVariable)type; if (tv.getBounds().length == 0) return Object.class; else return erase(tv.getBounds()[0]); } else if (type instanceof GenericArrayType) { GenericArrayType aType = (GenericArrayType) type; return GenericArrayTypeImpl.createArrayType(erase(aType.getGenericComponentType())); } else { // TODO at least support CaptureType here throw new RuntimeException("not supported: " + type.getClass()); } } /** * Maps type parameters in a type to their values. * @param toMapType Type possibly containing type arguments * @param typeAndParams must be either ParameterizedType, or (in case there are no type arguments, or it's a raw type) Class * @return toMapType, but with type parameters from typeAndParams replaced. */ private static Type mapTypeParameters(Type toMapType, Type typeAndParams) { if (isMissingTypeParameters(typeAndParams)) { return erase(toMapType); } else { VarMap varMap = new VarMap(); Type handlingTypeAndParams = typeAndParams; while(handlingTypeAndParams instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType)handlingTypeAndParams; Class clazz = (Class)pType.getRawType(); // getRawType should always be Class varMap.addAll(clazz.getTypeParameters(), pType.getActualTypeArguments()); handlingTypeAndParams = pType.getOwnerType(); } return varMap.map(toMapType); } } /** * Checks if the given type is a class that is supposed to have type parameters, but doesn't. * In other words, if it's a really raw type. */ private static boolean isMissingTypeParameters(Type type) { if (type instanceof Class) { for (Class clazz = (Class) type; clazz != null; clazz = clazz.getEnclosingClass()) { if (clazz.getTypeParameters().length != 0) return true; } return false; } else if (type instanceof ParameterizedType) { return false; } else { throw new AssertionError("Unexpected type " + type.getClass()); } } /** * Returns a type representing the class, with all type parameters the unbound wildcard ("?"). * For example, addWildcardParameters(Map.class) returns a type representing Map<?,?>. * @return

    *
  • If clazz is a class or interface without type parameters, clazz itself is returned.
  • *
  • If clazz is a class or interface with type parameters, an instance of ParameterizedType is returned.
  • *
  • if clazz is an array type, an array type is returned with unbound wildcard parameters added in the the component type. *
*/ public static Type addWildcardParameters(Class clazz) { if (clazz.isArray()) { return GenericArrayTypeImpl.createArrayType(addWildcardParameters(clazz.getComponentType())); } else if (isMissingTypeParameters(clazz)) { TypeVariable[] vars = clazz.getTypeParameters(); Type[] arguments = new Type[vars.length]; Arrays.fill(arguments, UNBOUND_WILDCARD); Type owner = clazz.getDeclaringClass() == null ? null : addWildcardParameters(clazz.getDeclaringClass()); return new ParameterizedTypeImpl(clazz, arguments, owner); } else { return clazz; } } /** * With type a supertype of searchClass, returns the exact supertype of the given class, including type parameters. * For example, with class StringList implements List<String>, getExactSuperType(StringList.class, Collection.class) * returns a {@link ParameterizedType} representing Collection<String>. *
    *
  • Returns null if searchClass is not a superclass of type.
  • *
  • Returns an instance of {@link Class} if type if it is a raw type, or has no type parameters
  • *
  • Returns an instance of {@link ParameterizedType} if the type does have parameters
  • *
  • Returns an instance of {@link GenericArrayType} if searchClass is an array type, and the actual type has type parameters
  • *
*/ public static Type getExactSuperType(Type type, Class searchClass) { if (type instanceof ParameterizedType || type instanceof Class || type instanceof GenericArrayType) { Class clazz = erase(type); if (searchClass == clazz) { return type; } if (! searchClass.isAssignableFrom(clazz)) return null; } for (Type superType: getExactDirectSuperTypes(type)) { Type result = getExactSuperType(superType, searchClass); if (result != null) return result; } return null; } /** * Gets the type parameter for a given type that is the value for a given type variable. * For example, with class StringList implements List<String>, * getTypeParameter(StringList.class, Collection.class.getTypeParameters()[0]) * returns String. * * @param type The type to inspect. * @param variable The type variable to find the value for. * @return The type parameter for the given variable. Or null if type is not a subtype of the * type that declares the variable, or if the variable isn't known (because of raw types). */ public static Type getTypeParameter(Type type, TypeVariable> variable) { Class clazz = variable.getGenericDeclaration(); Type superType = getExactSuperType(type, clazz); if (superType instanceof ParameterizedType) { int index = Arrays.asList(clazz.getTypeParameters()).indexOf(variable); return ((ParameterizedType)superType).getActualTypeArguments()[index]; } else { return null; } } /** * Checks if the capture of subType is a subtype of superType */ public static boolean isSuperType(Type superType, Type subType) { if (superType instanceof ParameterizedType || superType instanceof Class || superType instanceof GenericArrayType) { Class superClass = erase(superType); Type mappedSubType = getExactSuperType(capture(subType), superClass); if (mappedSubType == null) { return false; } else if (superType instanceof Class) { return true; } else if (mappedSubType instanceof Class) { // TODO treat supertype by being raw type differently ("supertype, but with warnings") return true; // class has no parameters, or it's a raw type } else if (mappedSubType instanceof GenericArrayType) { Type superComponentType = getArrayComponentType(superType); assert superComponentType != null; Type mappedSubComponentType = getArrayComponentType(mappedSubType); assert mappedSubComponentType != null; return isSuperType(superComponentType, mappedSubComponentType); } else { assert mappedSubType instanceof ParameterizedType; ParameterizedType pMappedSubType = (ParameterizedType) mappedSubType; assert pMappedSubType.getRawType() == superClass; ParameterizedType pSuperType = (ParameterizedType)superType; Type[] superTypeArgs = pSuperType.getActualTypeArguments(); Type[] subTypeArgs = pMappedSubType.getActualTypeArguments(); assert superTypeArgs.length == subTypeArgs.length; for (int i = 0; i < superTypeArgs.length; i++) { if (! contains(superTypeArgs[i], subTypeArgs[i])) { return false; } } // params of the class itself match, so if the owner types are supertypes too, it's a supertype. return pSuperType.getOwnerType() == null || isSuperType(pSuperType.getOwnerType(), pMappedSubType.getOwnerType()); } } else if (superType instanceof CaptureType) { if (superType.equals(subType)) return true; for (Type lowerBound : ((CaptureType) superType).getLowerBounds()) { if (isSuperType(lowerBound, subType)) { return true; } } return false; } else if (superType instanceof GenericArrayType) { return isArraySupertype(superType, subType); } else { throw new RuntimeException("not implemented: " + superType.getClass()); } } private static boolean isArraySupertype(Type arraySuperType, Type subType) { Type superTypeComponent = getArrayComponentType(arraySuperType); assert superTypeComponent != null; Type subTypeComponent = getArrayComponentType(subType); if (subTypeComponent == null) { // subType is not an array type return false; } else { return isSuperType(superTypeComponent, subTypeComponent); } } /** * If type is an array type, returns the type of the component of the array. * Otherwise, returns null. */ public static Type getArrayComponentType(Type type) { if (type instanceof Class) { Class clazz = (Class)type; return clazz.getComponentType(); } else if (type instanceof GenericArrayType) { GenericArrayType aType = (GenericArrayType) type; return aType.getGenericComponentType(); } else { return null; } } private static boolean contains(Type containingType, Type containedType) { if (containingType instanceof WildcardType) { WildcardType wContainingType = (WildcardType)containingType; for (Type upperBound : wContainingType.getUpperBounds()) { if (! isSuperType(upperBound, containedType)) { return false; } } for (Type lowerBound : wContainingType.getLowerBounds()) { if (! isSuperType(containedType, lowerBound)) { return false; } } return true; } else { return containingType.equals(containedType); } } /** * Returns the direct supertypes of the given type. Resolves type parameters. */ private static Type[] getExactDirectSuperTypes(Type type) { if (type instanceof ParameterizedType || type instanceof Class) { Class clazz; if (type instanceof ParameterizedType) { clazz = (Class)((ParameterizedType)type).getRawType(); } else { // TODO primitive types? clazz = (Class)type; if (clazz.isArray()) return getArrayExactDirectSuperTypes(clazz); } Type[] superInterfaces = clazz.getGenericInterfaces(); Type superClass = clazz.getGenericSuperclass(); Type[] result; int resultIndex; if (superClass == null) { result = new Type[superInterfaces.length]; resultIndex = 0; } else { result = new Type[superInterfaces.length + 1]; resultIndex = 1; result[0] = mapTypeParameters(superClass, type); } for (Type superInterface : superInterfaces) { result[resultIndex++] = mapTypeParameters(superInterface, type); } return result; } else if (type instanceof TypeVariable) { TypeVariable tv = (TypeVariable) type; return tv.getBounds(); } else if (type instanceof WildcardType) { // This should be a rare case: normally this wildcard is already captured. // But it does happen if the upper bound of a type variable contains a wildcard // TODO shouldn't upper bound of type variable have been captured too? (making this case impossible?) return ((WildcardType) type).getUpperBounds(); } else if (type instanceof CaptureType) { return ((CaptureType)type).getUpperBounds(); } else if (type instanceof GenericArrayType) { return getArrayExactDirectSuperTypes(type); } else { throw new RuntimeException("not implemented type: " + type); } } private static Type[] getArrayExactDirectSuperTypes(Type arrayType) { // see http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.10.3 Type typeComponent = getArrayComponentType(arrayType); Type[] result; int resultIndex; if (typeComponent instanceof Class && ((Class)typeComponent).isPrimitive()) { resultIndex = 0; result = new Type[3]; } else { Type[] componentSupertypes = getExactDirectSuperTypes(typeComponent); result = new Type[componentSupertypes.length + 3]; for (resultIndex = 0; resultIndex < componentSupertypes.length; resultIndex++) { result[resultIndex] = GenericArrayTypeImpl.createArrayType(componentSupertypes[resultIndex]); } } result[resultIndex++] = Object.class; result[resultIndex++] = Cloneable.class; result[resultIndex++] = Serializable.class; return result; } public static Type[] getExactParameterTypes(Method m, Type type) { Type[] parameterTypes = m.getGenericParameterTypes(); Type exactDeclaringType = getExactSuperType(capture(type), m.getDeclaringClass()); Type[] result = new Type[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { result[i] = mapTypeParameters(parameterTypes[i], exactDeclaringType); } return result; } /** * Returns the exact return type of the given method in the given type. * This may be different from m.getGenericReturnType() when the method was declared in a superclass, * of type is a raw type. */ public static Type getExactReturnType(Method m, Type type) { Type returnType = m.getGenericReturnType(); Type exactDeclaringType = getExactSuperType(capture(type), m.getDeclaringClass()); return mapTypeParameters(returnType, exactDeclaringType); } /** * Returns the exact type of the given field in the given type. * This may be different from f.getGenericType() when the field was declared in a superclass, * of type is a raw type. */ public static Type getExactFieldType(Field f, Type type) { Type returnType = f.getGenericType(); Type exactDeclaringType = getExactSuperType(capture(type), f.getDeclaringClass()); return mapTypeParameters(returnType, exactDeclaringType); } /** * Applies capture conversion to the given type. */ public static Type capture(Type type) { VarMap varMap = new VarMap(); List toInit = new ArrayList(); if (type instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType)type; Class clazz = (Class)pType.getRawType(); Type[] arguments = pType.getActualTypeArguments(); TypeVariable[] vars = clazz.getTypeParameters(); Type[] capturedArguments = new Type[arguments.length]; assert arguments.length == vars.length; for (int i = 0; i < arguments.length; i++) { Type argument = arguments[i]; if (argument instanceof WildcardType) { CaptureTypeImpl captured = new CaptureTypeImpl((WildcardType)argument, vars[i]); argument = captured; toInit.add(captured); } capturedArguments[i] = argument; varMap.add(vars[i], argument); } for (CaptureTypeImpl captured : toInit) { captured.init(varMap); } Type ownerType = (pType.getOwnerType() == null) ? null : capture(pType.getOwnerType()); return new ParameterizedTypeImpl(clazz, capturedArguments, ownerType); } else { return type; } } /** * Returns the display name of a Type. */ public static String getTypeName(Type type) { if(type instanceof Class) { Class clazz = (Class) type; return clazz.isArray() ? (getTypeName(clazz.getComponentType()) + "[]") : clazz.getName(); } else { return type.toString(); } } /** * Returns list of classes and interfaces that are supertypes of the given type. * For example given this class: * class Foo<A extends Number & Iterable<A>, B extends A>
* calling this method on type parameters B (Foo.class.getTypeParameters()[1]) * returns a list containing Number and Iterable. *

* This is mostly useful if you get a type from one of the other methods in GenericTypeReflector, * but you don't want to deal with all the different sorts of types, * and you are only really interested in concrete classes and interfaces. *

* * @return A List of classes, each of them a supertype of the given type. * If the given type is a class or interface itself, returns a List with just the given type. * The list contains no duplicates, and is ordered in the order the upper bounds are defined on the type. */ public static List> getUpperBoundClassAndInterfaces(Type type) { LinkedHashSet> result = new LinkedHashSet>(); buildUpperBoundClassAndInterfaces(type, result); return new ArrayList>(result); } /** * Helper method for getUpperBoundClassAndInterfaces, adding the result to the given set. */ private static void buildUpperBoundClassAndInterfaces(Type type, Set> result) { if (type instanceof ParameterizedType || type instanceof Class) { result.add(erase(type)); return; } for (Type superType: getExactDirectSuperTypes(type)) { buildUpperBoundClassAndInterfaces(superType, result); } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/gentyref/ParameterizedTypeImpl.java000066400000000000000000000040471202022523300336140ustar00rootroot00000000000000package org.spockframework.gentyref; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Arrays; class ParameterizedTypeImpl implements ParameterizedType { private final Class rawType; private final Type[] actualTypeArguments; private final Type ownerType; public ParameterizedTypeImpl(Class rawType, Type[] actualTypeArguments, Type ownerType) { this.rawType = rawType; this.actualTypeArguments = actualTypeArguments; this.ownerType = ownerType; } public Type getRawType() { return rawType; } public Type[] getActualTypeArguments() { return actualTypeArguments; } public Type getOwnerType() { return ownerType; } @Override public boolean equals(Object obj) { if (!(obj instanceof ParameterizedType)) return false; ParameterizedType other = (ParameterizedType) obj; return rawType.equals(other.getRawType()) && Arrays.equals(actualTypeArguments, other.getActualTypeArguments()) && (ownerType == null ? other.getOwnerType() == null : ownerType.equals(other.getOwnerType())); } @Override public int hashCode() { int result = rawType.hashCode() ^ Arrays.hashCode(actualTypeArguments); if (ownerType != null) result ^= ownerType.hashCode(); return result; } @Override public String toString() { StringBuilder sb = new StringBuilder(); String clazz = rawType.getName(); if (ownerType != null) { sb.append(GenericTypeReflector.getTypeName(ownerType)).append('.'); String prefix = (ownerType instanceof ParameterizedType) ? ((Class)((ParameterizedType)ownerType).getRawType()).getName() + '$' : ((Class)ownerType).getName() + '$'; if (clazz.startsWith(prefix)) clazz = clazz.substring(prefix.length()); } sb.append(clazz); if(actualTypeArguments.length != 0) { sb.append('<'); for (int i = 0; i < actualTypeArguments.length; i++) { Type arg = actualTypeArguments[i]; if (i != 0) sb.append(", "); sb.append(GenericTypeReflector.getTypeName(arg)); } sb.append('>'); } return sb.toString(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/gentyref/TypeToken.java000066400000000000000000000035171202022523300312570ustar00rootroot00000000000000package org.spockframework.gentyref; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * Wrapper around {@link Type}. * * You can use this to create instances of Type for a type known at compile * time. * * For example, to get the Type that represents List<String>: * Type listOfString = new TypeToken<List<String>>(){}.getType(); * * @author Wouter Coekaerts * * @param * The type represented by this TypeToken. */ public abstract class TypeToken { private final Type type; /** * Constructs a type token. */ protected TypeToken() { this.type = extractType(); } private TypeToken(Type type) { this.type = type; } public Type getType() { return type; } private Type extractType() { Type t = getClass().getGenericSuperclass(); if (!(t instanceof ParameterizedType)) { throw new RuntimeException("Invalid TypeToken; must specify type parameters"); } ParameterizedType pt = (ParameterizedType) t; if (pt.getRawType() != TypeToken.class) { throw new RuntimeException("Invalid TypeToken; must directly extend TypeToken"); } return pt.getActualTypeArguments()[0]; } /** * Gets type token for the given {@code Class} instance. */ public static TypeToken get(Class type) { return new SimpleTypeToken(type); } /** * Gets type token for the given {@code Type} instance. */ public static TypeToken get(Type type) { return new SimpleTypeToken(type); } private static class SimpleTypeToken extends TypeToken { public SimpleTypeToken(Type type) { super(type); } } @Override public boolean equals(Object obj) { return (obj instanceof TypeToken) && type.equals(((TypeToken) obj).type); } @Override public int hashCode() { return type.hashCode(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/gentyref/VarMap.java000066400000000000000000000037461202022523300305270ustar00rootroot00000000000000/** * */ package org.spockframework.gentyref; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.HashMap; import java.util.Map; /** * Mapping between type variables and actual parameters. * * @author Wouter Coekaerts */ class VarMap { private final Map, Type> map = new HashMap, Type>(); /** * Creates an empty VarMap */ VarMap() { } void add(TypeVariable variable, Type value) { map.put(variable, value); } void addAll(TypeVariable[] variables, Type[] values) { assert variables.length == values.length; for (int i = 0; i < variables.length; i++) { map.put(variables[i], values[i]); } } VarMap(TypeVariable[] variables, Type[] values) { addAll(variables, values); } Type map(Type type) { if (type instanceof Class) { return type; } else if (type instanceof TypeVariable) { assert map.containsKey(type); return map.get(type); } else if (type instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) type; return new ParameterizedTypeImpl((Class)pType.getRawType(), map(pType.getActualTypeArguments()), pType.getOwnerType() == null ? pType.getOwnerType() : map(pType.getOwnerType())); } else if (type instanceof WildcardType) { WildcardType wType = (WildcardType) type; return new WildcardTypeImpl(map(wType.getUpperBounds()), map(wType.getLowerBounds())); } else if (type instanceof GenericArrayType) { return GenericArrayTypeImpl.createArrayType(map(((GenericArrayType)type).getGenericComponentType())); } else { throw new RuntimeException("not implemented: mapping " + type.getClass() + " (" + type + ")"); } } Type[] map(Type[] types) { Type[] result = new Type[types.length]; for (int i = 0; i < types.length; i++) { result[i] = map(types[i]); } return result; } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/gentyref/WildcardTypeImpl.java000066400000000000000000000025641202022523300325530ustar00rootroot00000000000000/** * */ package org.spockframework.gentyref; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; import java.util.Arrays; class WildcardTypeImpl implements WildcardType { private final Type[] upperBounds; private final Type[] lowerBounds; public WildcardTypeImpl(Type[] upperBounds, Type[] lowerBounds) { if (upperBounds.length == 0) throw new IllegalArgumentException("There must be at least one upper bound. For an unbound wildcard, the upper bound must be Object"); this.upperBounds = upperBounds; this.lowerBounds = lowerBounds; } public Type[] getUpperBounds() { return upperBounds.clone(); } public Type[] getLowerBounds() { return lowerBounds.clone(); } @Override public boolean equals(Object obj) { if (! (obj instanceof WildcardType)) return false; WildcardType other = (WildcardType)obj; return Arrays.equals(lowerBounds, other.getLowerBounds()) && Arrays.equals(upperBounds, other.getUpperBounds()); } @Override public int hashCode() { return Arrays.hashCode(lowerBounds) ^ Arrays.hashCode(upperBounds); } @Override public String toString() { if (lowerBounds.length > 0) { return "? super " + GenericTypeReflector.getTypeName(lowerBounds[0]); } else if (upperBounds[0] == Object.class) { return "?"; } else { return "? extends " + GenericTypeReflector.getTypeName(upperBounds[0]); } } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/lang/000077500000000000000000000000001202022523300255625ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/lang/SpreadWildcard.java000066400000000000000000000015071202022523300313200ustar00rootroot00000000000000/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.lang; public class SpreadWildcard { public static final SpreadWildcard INSTANCE = new SpreadWildcard(); private SpreadWildcard() {} @Override public String toString() { return "*_"; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/lang/Wildcard.java000066400000000000000000000024201202022523300301540ustar00rootroot00000000000000/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.lang; import java.util.AbstractList; // make it List rather than List // because IDE type inference might like this better public class Wildcard extends AbstractList { public static final Wildcard INSTANCE = new Wildcard(); private Wildcard() {} @Override public Object get(int index) { if (index != 0) throw new IndexOutOfBoundsException("Wildcard.INSTANCE only has a single element"); return SpreadWildcard.INSTANCE; } @Override public int size() { return 1; } @Override public String toString() { return "_"; // both compiler and runtime sometimes need String representation } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/000077500000000000000000000000001202022523300255725ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/CannotCreateMockException.java000077500000000000000000000023121202022523300334750ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * Thrown when an attempt to create a mock object fails. * * @author Peter Niederwieser */ // IDEA: filter stack trace so that the top entry is the point of mock declaration public class CannotCreateMockException extends RuntimeException { public CannotCreateMockException(Class mockType, String msg) { super(String.format("Cannot create mock for %s because %s", mockType.getName(), msg)); } public CannotCreateMockException(Class mockType, Throwable cause) { super(String.format("Cannot create mock for %s.", mockType.getName()), cause); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/CodeArgumentConstraint.java000077500000000000000000000021561202022523300330660ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.util.GroovyRuntimeUtil; import groovy.lang.Closure; /** * * @author Peter Niederwieser */ // IDEA: reify instead of separate matcher? public class CodeArgumentConstraint implements IArgumentConstraint { private final Closure code; public CodeArgumentConstraint(Closure code) { this.code = code; } public boolean isSatisfiedBy(Object argument) { return GroovyRuntimeUtil.isTruthy(GroovyRuntimeUtil.invokeClosure(code, argument)); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/CodeResultGenerator.java000077500000000000000000000031701202022523300323610ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.util.GroovyRuntimeUtil; import groovy.lang.Closure; /** * * @author Peter Niederwieser */ public class CodeResultGenerator extends SingleResultGenerator { private final Closure code; private final boolean provideExtendedInfo; public CodeResultGenerator(Closure code) { this.code = code; Class[] paramTypes = code.getParameterTypes(); provideExtendedInfo = paramTypes.length == 1 && paramTypes[0] == IMockInvocation.class; } public Object generateSingle(IMockInvocation invocation) { Object result = GroovyRuntimeUtil.invokeClosure(code, provideExtendedInfo ? invocation : invocation.getArguments()); Class returnType = invocation.getMethod().getReturnType(); // don't attempt cast for void methods (closure could be an action that accidentally returns a value) if (returnType == void.class || returnType == Void.class) return null; return GroovyRuntimeUtil.coerce(result, invocation.getMethod().getReturnType()); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/ConstantResultGenerator.java000077500000000000000000000020761202022523300333040ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.util.GroovyRuntimeUtil; /** * * @author Peter Niederwieser */ public class ConstantResultGenerator extends SingleResultGenerator { private final Object constant; public ConstantResultGenerator(Object constant) { this.constant = constant; } public Object generateSingle(IMockInvocation invocation) { return GroovyRuntimeUtil.coerce(constant, invocation.getMethod().getReturnType()); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/DefaultEqualsInteraction.java000066400000000000000000000025201202022523300333730ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.lang.reflect.Method; public class DefaultEqualsInteraction extends DefaultInteraction { public static final DefaultEqualsInteraction INSTANCE = new DefaultEqualsInteraction(); private DefaultEqualsInteraction() {} public String getText() { return "default equals() interaction"; } public boolean matches(IMockInvocation invocation) { Method method = invocation.getMethod(); return method.getName().equals("equals") && method.getParameterTypes().length == 1 && method.getParameterTypes()[0] == Object.class; } public Object accept(IMockInvocation invocation) { return invocation.getMockObject().getInstance() == invocation.getArguments().get(0); } } DefaultHashCodeInteraction.java000066400000000000000000000023471202022523300335470ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; public class DefaultHashCodeInteraction extends DefaultInteraction { public static final DefaultHashCodeInteraction INSTANCE = new DefaultHashCodeInteraction(); private DefaultHashCodeInteraction() {} public String getText() { return "default hashCode() interaction"; } public boolean matches(IMockInvocation invocation) { return invocation.getMethod().getName().equals("hashCode") && invocation.getMethod().getParameterTypes().length == 0; } public Object accept(IMockInvocation invocation) { return System.identityHashCode(invocation.getMockObject().getInstance()); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/DefaultInteraction.java000066400000000000000000000016261202022523300322260ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; public abstract class DefaultInteraction implements IMockInteraction { public int getLine() { return -1; } public int getColumn() { return -1; } public boolean isSatisfied() { return true; } public boolean isExhausted() { return false; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/DefaultInteractionScope.java000066400000000000000000000032551202022523300332200ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.Arrays; import java.util.List; import org.spockframework.util.UnreachableCodeError; public class DefaultInteractionScope implements IInteractionScope { public static final DefaultInteractionScope INSTANCE = new DefaultInteractionScope(); private DefaultInteractionScope() {} private final List interactions = Arrays.asList( DefaultEqualsInteraction.INSTANCE, DefaultHashCodeInteraction.INSTANCE, DefaultToStringInteraction.INSTANCE, DefaultStubbedInteraction.INSTANCE); public void addInteraction(IMockInteraction interaction) { throw new UnreachableCodeError("addInteraction"); } public void addOrderingBarrier() { throw new UnreachableCodeError("addOrderingBarrier()"); } public IMockInteraction match(IMockInvocation invocation) { for (IMockInteraction interaction : interactions) if (interaction.matches(invocation)) return interaction; return null; } public void verifyInteractions() { throw new UnreachableCodeError("verifyInteractions"); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/DefaultMockFactory.java000066400000000000000000000117751202022523300321760ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.lang.reflect.InvocationHandler; import java.lang.reflect.*; import java.lang.reflect.Proxy; import java.util.*; import org.objenesis.*; import net.sf.cglib.proxy.*; import groovy.lang.*; import org.spockframework.util.*; /** * * Some implementation details of this class are stolen from Spring, EasyMock * Class Extensions, and this thread: * http://www.nabble.com/Callbacks%2C-classes-and-instances-to4092596.html * * @author Peter Niederwieser */ public class DefaultMockFactory implements IMockFactory { public static final String INSTANCE_FIELD = "INSTANCE"; public static final DefaultMockFactory INSTANCE = new DefaultMockFactory(); private static final boolean cglibAvailable = ReflectionUtil.isClassAvailable("net.sf.cglib.proxy.Enhancer"); private static final boolean objenesisAvailable = ReflectionUtil.isClassAvailable("org.objenesis.Objenesis"); public Object create(String mockName, Class mockType, IInvocationDispatcher dispatcher) { if (Modifier.isFinal(mockType.getModifiers())) throw new CannotCreateMockException(mockType, "mocking final classes is not supported."); if (mockType.isInterface()) return createDynamicProxyMock(mockName, mockType, dispatcher); if (cglibAvailable) return CglibMockFactory.create(mockName, mockType, dispatcher); throw new CannotCreateMockException(mockType, "by default, only mocking of interfaces is supported; to allow mocking of classes, put cglib-nodep-2.2 or higher on the classpath." ); } private Object createDynamicProxyMock(final String mockName, final Class mockType, final IInvocationDispatcher dispatcher) { return Proxy.newProxyInstance( mockType.getClassLoader(), new Class[] {mockType}, new InvocationHandler() { public Object invoke(Object mockInstance, Method method, Object[] args) { IMockObject mockObject = new MockObject(mockName, mockType, mockInstance); IMockInvocation invocation = new MockInvocation(mockObject, method, normalizeArgs(args)); return dispatcher.dispatch(invocation); } } ); } private static List normalizeArgs(Object[] args) { return args == null ? Collections.emptyList() : Arrays.asList(args); } private static class CglibMockFactory { static Object create(final String mockName, final Class mockType, final IInvocationDispatcher dispatcher) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(mockType); final boolean isGroovyObject = GroovyObject.class.isAssignableFrom(mockType); MethodInterceptor interceptor = new MethodInterceptor() { public Object intercept(Object mockInstance, Method method, Object[] args, MethodProxy proxy) { if (isGroovyObject) { if (isMethod(method, "getMetaClass", 0)) return GroovySystem.getMetaClassRegistry().getMetaClass(mockInstance.getClass()); } IMockObject mockObject = new MockObject(mockName, mockType, mockInstance); IMockInvocation invocation = new MockInvocation(mockObject, method, normalizeArgs(args)); return dispatcher.dispatch(invocation); } }; if (objenesisAvailable) { enhancer.setCallbackType(interceptor.getClass()); Object instance = ObjenesisInstantiator.instantiate(enhancer.createClass()); ((Factory)instance).setCallback(0, interceptor); return instance; } try { enhancer.setCallback(interceptor); return enhancer.create(); // throws what if no parameterless superclass constructor available? } catch (Exception e) { throw new CannotCreateMockException(mockType, "the latter has no parameterless constructor; to allow mocking of classes without parameterless constructor, put objenesis-1.2 or higher on the classpath." ); } } private static boolean isMethod(Method method, String name, int parameterCount) { return method.getName().equals(name) && method.getParameterTypes().length == parameterCount; } private static class ObjenesisInstantiator { static final Objenesis objenesis = new ObjenesisStd(); static Object instantiate(Class mockType) { try { return objenesis.newInstance(mockType); } catch (ObjenesisException e) { throw new CannotCreateMockException(mockType, e); } } } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/DefaultResultGenerator.java000077500000000000000000000020011202022523300330630ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.util.ReflectionUtil; /** * Returns the default value for the invoked method's return type. * * @author Peter Niederwieser */ public class DefaultResultGenerator extends SingleResultGenerator { public Object generateSingle(IMockInvocation invocation) { return ReflectionUtil.getDefaultValue(invocation.getMethod().getReturnType()); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/DefaultStubbedInteraction.java000066400000000000000000000022441202022523300335340ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.util.ReflectionUtil; public class DefaultStubbedInteraction extends DefaultInteraction { public static final DefaultStubbedInteraction INSTANCE = new DefaultStubbedInteraction(); private DefaultStubbedInteraction() {} public String getText() { return "default stubbed interaction"; } public boolean matches(IMockInvocation invocation) { return true; } public Object accept(IMockInvocation invocation) { return ReflectionUtil.getDefaultValue(invocation.getMethod().getReturnType()); } }DefaultToStringInteraction.java000066400000000000000000000030471202022523300336400ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; public class DefaultToStringInteraction extends DefaultInteraction { public static final DefaultToStringInteraction INSTANCE = new DefaultToStringInteraction(); private DefaultToStringInteraction() {} public String getText() { return "default toString() interaction"; } public boolean matches(IMockInvocation invocation) { return invocation.getMethod().getName().equals("toString") && invocation.getMethod().getParameterTypes().length == 0; } public Object accept(IMockInvocation invocation) { StringBuilder builder = new StringBuilder(); builder.append("Mock for type '"); builder.append(invocation.getMockObject().getType().getSimpleName()); builder.append("'"); String name = invocation.getMockObject().getName(); if (name != null) { builder.append(" named '"); builder.append(name); builder.append("'"); } return builder.toString(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/EqualArgumentConstraint.java000077500000000000000000000022531202022523300332610ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.runtime.HamcrestFacade; import org.spockframework.util.GroovyRuntimeUtil; /** * * @author Peter Niederwieser */ public class EqualArgumentConstraint implements IArgumentConstraint { private final Object expected; public EqualArgumentConstraint(Object expected) { this.expected = expected; } public boolean isSatisfiedBy(Object arg) { if (HamcrestFacade.isMatcher(expected)) { return HamcrestFacade.matches(expected, arg); } return GroovyRuntimeUtil.equals(arg, expected); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/EqualMethodNameConstraint.java000077500000000000000000000020031202022523300335110ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * * @author Peter Niederwieser */ public class EqualMethodNameConstraint implements IInvocationConstraint { private final String methodName; public EqualMethodNameConstraint(String methodName) { this.methodName = methodName; } public boolean isSatisfiedBy(IMockInvocation invocation) { return invocation.getMethod().getName().equals(methodName); } } EqualPropertyNameConstraint.java000077500000000000000000000021371202022523300340460ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.util.ReflectionUtil; /** * * @author Peter Niederwieser */ public class EqualPropertyNameConstraint implements IInvocationConstraint { private final String propertyName; public EqualPropertyNameConstraint(String propertyName) { this.propertyName = propertyName; } public boolean isSatisfiedBy(IMockInvocation invocation) { return propertyName.equals(ReflectionUtil.getPropertyNameForGetterMethod(invocation.getMethod())); } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IArgumentConstraint.java000077500000000000000000000014541202022523300324040ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * A constraint on an invocation argument. * * @author Peter Niederwieser */ public interface IArgumentConstraint { boolean isSatisfiedBy(Object arg); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IInteractionScope.java000066400000000000000000000017741202022523300320300ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * An interaction scope holds a group of interactions that will be verified, * and thereafter removed, at the same time. * * @author Peter Niederwieser */ public interface IInteractionScope { void addInteraction(IMockInteraction interaction); void addOrderingBarrier(); IMockInteraction match(IMockInvocation invocation); void verifyInteractions(); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IInvocationConstraint.java000077500000000000000000000014231202022523300327270ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * * @author Peter Niederwieser */ public interface IInvocationConstraint { boolean isSatisfiedBy(IMockInvocation invocation); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IInvocationDispatcher.java000077500000000000000000000014151202022523300326720ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * * @author Peter Niederwieser */ public interface IInvocationDispatcher { Object dispatch(IMockInvocation invocation); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IMockFactory.java000077500000000000000000000015151202022523300307740ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * * @author Peter Niederwieser */ public interface IMockFactory { Object create(String mockName, Class mockType, IInvocationDispatcher dispatcher) throws CannotCreateMockException; } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IMockInteraction.java000077500000000000000000000017611202022523300316470ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * An anticipated interaction between the SUT and one or more mock objects. * * @author Peter Niederwieser */ public interface IMockInteraction { int getLine(); int getColumn(); String getText(); boolean matches(IMockInvocation invocation); Object accept(IMockInvocation invocation); boolean isSatisfied(); boolean isExhausted(); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IMockInvocation.java000077500000000000000000000024521202022523300314770ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.lang.reflect.Method; import java.util.List; /** * A method invocation on a mock object. * * @author Peter Niederwieser */ // IDEA: add method "MockType mockType" that tells which interface or class was mocked, // the kind of mock involved (dynamic proxy, cglib, etc.), etc. public interface IMockInvocation { /** * The mock object that received the invocation. */ IMockObject getMockObject(); /** * The invoked method. */ // IDEA: replace with our own Method abstraction so that we can also // represent dynamic Groovy calls Method getMethod(); /** * The arguments for the invocation. */ List getArguments(); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IMockObject.java000066400000000000000000000013471202022523300305730ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; public interface IMockObject { String getName(); Class getType(); Object getInstance(); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IResultGenerator.java000077500000000000000000000015351202022523300317020ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * Generates return values for invocations on mock objects. * * @author Peter Niederwieser */ public interface IResultGenerator { boolean isExhausted(); Object generate(IMockInvocation invocation); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IdenticalTargetConstraint.java000077500000000000000000000020401202022523300335440ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * * @author Peter Niederwieser */ // IDEA: check that target actually is a mock public class IdenticalTargetConstraint implements IInvocationConstraint { private final Object target; public IdenticalTargetConstraint(Object target) { this.target = target; } public boolean isSatisfiedBy(IMockInvocation invocation) { return invocation.getMockObject().getInstance() == target; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/InteractionBuilder.java000077500000000000000000000154121202022523300322310ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.ArrayList; import java.util.List; import groovy.lang.Closure; import org.spockframework.lang.SpreadWildcard; import org.spockframework.lang.Wildcard; import org.spockframework.runtime.InvalidSpecException; /** * * @author Peter Niederwieser */ public class InteractionBuilder { private final int line; private final int column; private final String text; private int minCount = 0; private int maxCount = Integer.MAX_VALUE; private List invConstraints = new ArrayList(); private List argNames; private List argConstraints; private ResultGeneratorChain resultGenerators = new ResultGeneratorChain(); public InteractionBuilder(int line, int column, String text) { this.line = line; this.column = column; this.text = text; } public static final String SET_FIXED_COUNT = "setFixedCount"; public InteractionBuilder setFixedCount(Object count) { if (count instanceof Wildcard) { minCount = 0; maxCount = Integer.MAX_VALUE; } else minCount = maxCount = convertCount(count, true); return this; } public static final String SET_RANGE_COUNT = "setRangeCount"; public InteractionBuilder setRangeCount(Object minCount, Object maxCount, boolean inclusive) { this.minCount = minCount instanceof Wildcard ? 0 : convertCount(minCount, true); this.maxCount = maxCount instanceof Wildcard ? Integer.MAX_VALUE : convertCount(maxCount, inclusive); if (this.minCount > this.maxCount) throw new InvalidSpecException("lower bound of invocation count must come before upper bound"); return this; } public static final String ADD_EQUAL_TARGET = "addEqualTarget"; public InteractionBuilder addEqualTarget(Object target) { if (!(target instanceof Wildcard)) invConstraints.add(new IdenticalTargetConstraint(target)); return this; } public static final String ADD_EQUAL_PROPERTY_NAME = "addEqualPropertyName"; public InteractionBuilder addEqualPropertyName(String name) { if (name.equals(Wildcard.INSTANCE.toString())) invConstraints.add(WildcardMethodNameConstraint.INSTANCE); else invConstraints.add(new EqualPropertyNameConstraint(name)); return this; } public static final String ADD_REGEX_PROPERTY_NAME = "addRegexPropertyName"; public InteractionBuilder addRegexPropertyName(String regex) { invConstraints.add(new RegexPropertyNameConstraint(regex)); return this; } public static final String ADD_EQUAL_METHOD_NAME = "addEqualMethodName"; public InteractionBuilder addEqualMethodName(String name) { if (name.equals(Wildcard.INSTANCE.toString())) invConstraints.add(WildcardMethodNameConstraint.INSTANCE); else invConstraints.add(new EqualMethodNameConstraint(name)); return this; } public static final String ADD_REGEX_METHOD_NAME = "addRegexMethodName"; public InteractionBuilder addRegexMethodName(String regex) { invConstraints.add(new RegexMethodNameConstraint(regex)); return this; } public static final String SET_ARG_LIST_KIND = "setArgListKind"; public InteractionBuilder setArgListKind(boolean isPositional) { argConstraints = new ArrayList(); if (isPositional) invConstraints.add(new PositionalArgumentListConstraint(argConstraints)); else { argNames = new ArrayList(); invConstraints.add(new NamedArgumentListConstraint(argNames, argConstraints)); } return this; } public static final String ADD_ARG_NAME= "addArgName"; public InteractionBuilder addArgName(String name) { argNames.add(name); return this; } public static final String ADD_CODE_ARG = "addCodeArg"; public InteractionBuilder addCodeArg(Closure closure) { argConstraints.add(new CodeArgumentConstraint(closure)); return this; } public static final String ADD_EQUAL_ARG = "addEqualArg"; public InteractionBuilder addEqualArg(Object arg) { argConstraints.add(arg instanceof Wildcard ? WildcardArgumentConstraint.INSTANCE : arg instanceof SpreadWildcard ? SpreadWildcardArgumentConstraint.INSTANCE : new EqualArgumentConstraint(arg)); return this; } public static final String TYPE_LAST_ARG = "typeLastArg"; public InteractionBuilder typeLastArg(Class type) { IArgumentConstraint last = argConstraints.get(argConstraints.size() - 1); argConstraints.set(argConstraints.size() - 1, new TypeArgumentConstraint(type, last)); return this; } public static final String NEGATE_LAST_ARG = "negateLastArg"; public InteractionBuilder negateLastArg() { IArgumentConstraint last = argConstraints.get(argConstraints.size() - 1); argConstraints.set(argConstraints.size() - 1, new NegatingArgumentConstraint(last)); return this; } public static final String ADD_CONSTANT_RESULT = "setConstantResult"; public InteractionBuilder setConstantResult(Object constant) { resultGenerators.addFirst(constant instanceof Wildcard ? new DefaultResultGenerator() : new ConstantResultGenerator(constant)); return this; } public static final String ADD_CODE_RESULT = "setCodeResult"; public InteractionBuilder setCodeResult(Closure closure) { resultGenerators.addFirst(new CodeResultGenerator(closure)); return this; } public static final String ADD_ITERABLE_RESULT = "setIterableResult"; public InteractionBuilder setIterableResult(Object iterable) { resultGenerators.addFirst(new IterableResultGenerator(iterable)); return this; } public static final String BUILD = "build"; public IMockInteraction build() { if (resultGenerators.isEmpty()) resultGenerators.addFirst(new DefaultResultGenerator()); return new MockInteraction(line, column, text, minCount, maxCount, invConstraints, resultGenerators); } private static int convertCount(Object count, boolean inclusive) { if (!(count instanceof Number)) throw new InvalidSpecException("invocation count must be a number"); int intCount = ((Number)count).intValue(); if (!inclusive) intCount--; if (intCount < 0) throw new InvalidSpecException("invocation count must be >= 0"); return intCount; } } InteractionNotSatisfiedError.java000066400000000000000000000017171202022523300341720ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.runtime.SpockAssertionError; /** * Base class for exceptions indicating that one or more interactions * have not been satisfied (i.e. have seen to few or too many invocations). * * @author Peter Niederwieser */ public abstract class InteractionNotSatisfiedError extends SpockAssertionError {} spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/InteractionScope.java000066400000000000000000000041471202022523300317140ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.ArrayList; import java.util.List; /** * A scope for interactions defined outside a then-block * * @author Peter Niederwieser */ public class InteractionScope implements IInteractionScope { private final List interactions = new ArrayList(); private int currentRegistrationZone = 0; private int currentExecutionZone = 0; public void addInteraction(IMockInteraction interaction) { interactions.add(new MockInteractionDecorator(interaction) { final int myRegistrationZone = currentRegistrationZone; @Override public Object accept(IMockInvocation invocation) { Object result = super.accept(invocation); if (currentExecutionZone > myRegistrationZone) throw new WrongInvocationOrderError(decorated, invocation); currentExecutionZone = myRegistrationZone; return result; } }); } public void addOrderingBarrier() { currentRegistrationZone++; } public IMockInteraction match(IMockInvocation invocation) { for (IMockInteraction interaction : interactions) if (interaction.matches(invocation)) return interaction; return null; } public void verifyInteractions() { List unsatisfieds = new ArrayList(); for (IMockInteraction i : interactions) if (!i.isSatisfied()) unsatisfieds.add(i); if (!unsatisfieds.isEmpty()) throw new TooFewInvocationsError(unsatisfieds); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/IterableResultGenerator.java000066400000000000000000000026141202022523300332350ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.Iterator; import org.spockframework.util.GroovyRuntimeUtil; /** * Generates result values from an iterable object. If the iterator has no more * values left, the previous value is returned. * * @author Peter Niederwieser */ public class IterableResultGenerator implements IResultGenerator { private final Iterator iterator; private Object nextValue; public IterableResultGenerator(Object iterable) { iterator = GroovyRuntimeUtil.asIterator(iterable); } public boolean isExhausted() { return !iterator.hasNext(); } public Object generate(IMockInvocation invocation) { if (iterator.hasNext()) nextValue = iterator.next(); return GroovyRuntimeUtil.coerce(nextValue, invocation.getMethod().getReturnType()); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/MockController.java000077500000000000000000000052061202022523300314000ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.*; import org.spockframework.util.InternalSpockError; /** * @author Peter Niederwieser */ public class MockController implements IInvocationDispatcher { private final IMockFactory factory; private final LinkedList scopes = new LinkedList(); private final List errors = new ArrayList(); public MockController(IMockFactory factory) { this.factory = factory; scopes.addFirst(DefaultInteractionScope.INSTANCE); scopes.addFirst(new InteractionScope()); } public synchronized Object dispatch(IMockInvocation invocation) { for (IInteractionScope scope : scopes) { IMockInteraction interaction = scope.match(invocation); if (interaction != null) try { return interaction.accept(invocation); } catch (InteractionNotSatisfiedError e) { errors.add(e); throw e; } } throw new InternalSpockError("No interaction matched invocation: %s").withArgs(invocation); } public static final String ADD_INTERACTION = "addInteraction"; public synchronized void addInteraction(IMockInteraction interaction) { scopes.getFirst().addInteraction(interaction); } public static final String ADD_BARRIER = "addBarrier"; public synchronized void addBarrier() { scopes.getFirst().addOrderingBarrier(); } public static final String ENTER_SCOPE = "enterScope"; public synchronized void enterScope() { throwAnyPreviousError(); scopes.addFirst(new InteractionScope()); } public static final String LEAVE_SCOPE = "leaveScope"; public synchronized void leaveScope() { throwAnyPreviousError(); IInteractionScope scope = scopes.removeFirst(); scope.verifyInteractions(); } public synchronized Object create(String mockName, Class mockType) { return factory.create(mockName, mockType, this); } private void throwAnyPreviousError() { if (!errors.isEmpty()) throw errors.get(0); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/MockInteraction.java000077500000000000000000000045041202022523300315340ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.List; /** * An anticipated interaction between the SUT and one or more mock objects. * * @author Peter Niederwieser */ public class MockInteraction implements IMockInteraction { private final int line; private final int column; private final String text; private final int minCount; private final int maxCount; private final List matchers; private final IResultGenerator resultGenerator; private int acceptedCount; public MockInteraction(int line, int column, String text, int minCount, int maxCount, List matchers, IResultGenerator resultGenerator) { this.line = line; this.column = column; this.text = text; this.minCount = minCount; this.maxCount = maxCount; this.matchers = matchers; this.resultGenerator = resultGenerator; } public boolean matches(IMockInvocation invocation) { for (IInvocationConstraint matcher : matchers) if (!matcher.isSatisfiedBy(invocation)) return false; return true; } public Object accept(IMockInvocation invocation) { acceptedCount++; if (acceptedCount > maxCount) throw new TooManyInvocationsError(this, invocation); return resultGenerator.generate(invocation); } public boolean isSatisfied() { return acceptedCount >= minCount; } public boolean isExhausted() { return acceptedCount >= maxCount; } public int getLine() { return line; } public int getColumn() { return column; } public String getText() { return text; } public String toString() { return String.format("%s (%d %s)", text, acceptedCount, acceptedCount == 1 ? "invocation" : "invocations"); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/MockInteractionDecorator.java000066400000000000000000000027231202022523300333750ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; public abstract class MockInteractionDecorator implements IMockInteraction { protected final IMockInteraction decorated; public MockInteractionDecorator(IMockInteraction decorated) { this.decorated = decorated; } public int getLine() { return decorated.getLine(); } public int getColumn() { return decorated.getColumn(); } public String getText() { return decorated.getText(); } public boolean matches(IMockInvocation invocation) { return decorated.matches(invocation); } public Object accept(IMockInvocation invocation) { return decorated.accept(invocation); } public boolean isSatisfied() { return decorated.isSatisfied(); } public boolean isExhausted() { return decorated.isExhausted(); } @Override public String toString() { return decorated.toString(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/MockInvocation.java000077500000000000000000000035431202022523300313700ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.lang.reflect.Method; import java.util.*; import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.spockframework.util.TextUtil; /** * * @author Peter Niederwieser */ public class MockInvocation implements IMockInvocation { private final IMockObject mockObject; private final Method method; private final List arguments; public MockInvocation(IMockObject mockObject, Method method, List arguments) { this.mockObject = mockObject; this.method = method; this.arguments = arguments; } public IMockObject getMockObject() { return mockObject; } public Method getMethod() { return method; } public List getArguments() { return arguments; } @Override public String toString() { String mockName = mockObject.getName(); if (mockName == null) mockName = String.format("<%s>", mockObject.getType().getSimpleName()); return String.format("%s.%s(%s)", mockName, method.getName(), render(arguments)); } private String render(List arguments) { List strings = new ArrayList(); for (Object arg : arguments) strings.add(DefaultGroovyMethods.inspect(arg)); return TextUtil.join(", ", strings); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/MockObject.java000066400000000000000000000021061202022523300304540ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; public class MockObject implements IMockObject { private final String name; private final Class type; private final Object instance; public MockObject(String name, Class type, Object instance) { this.name = name; this.type = type; this.instance = instance; } public String getName() { return name; } public Class getType() { return type; } public Object getInstance() { return instance; } } NamedArgumentListConstraint.java000077500000000000000000000060471202022523300340200ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.*; import org.spockframework.util.Assert; /** * * @author Peter Niederwieser */ public class NamedArgumentListConstraint implements IInvocationConstraint { // NOTE: why not use List here? private final List argNames; // name == "_" -> unnamed matcher (considered matching if it matches any arg) private final List argConstraints; public NamedArgumentListConstraint(List argNames, List argConstraints) { Assert.that(argNames.size() == argConstraints.size()); this.argNames = argNames; this.argConstraints = argConstraints; } @SuppressWarnings("unchecked") public boolean isSatisfiedBy(IMockInvocation invocation) { List args = invocation.getArguments(); if (args.size() == 1 && args.get(0) instanceof Map) return matchesArgMap(new HashMap((Map)args.get(0))); return matchesArgList(new ArrayList(args)); } private boolean matchesArgList(List args) { nextMatcher: for (int i = 0; i < argConstraints.size(); i++) { Object name = argNames.get(i); if (!name.equals("_")) return false; // cannot possibly match because we have unnamed args IArgumentConstraint matcher = argConstraints.get(i); Iterator argIter = args.iterator(); while (argIter.hasNext()) if (matcher.isSatisfiedBy(argIter.next())) { argIter.remove(); continue nextMatcher; } return false; } return true; } private boolean matchesArgMap(Map argMap) { // first pass: named matchers for (int i = 0; i < argConstraints.size(); i++) { Object name = argNames.get(i); if (name.equals("_")) continue; IArgumentConstraint matcher = argConstraints.get(i); if (!argMap.containsKey(name) || !matcher.isSatisfiedBy(argMap.remove(name))) return false; } // second pass: unnamed matchers nextMatcher: for (int i = 0; i < argConstraints.size(); i++) { Object name = argNames.get(i); if (!name.equals("_")) continue; IArgumentConstraint matcher = argConstraints.get(i); @SuppressWarnings("unchecked") Iterator argIter = argMap.values().iterator(); while (argIter.hasNext()) if (matcher.isSatisfiedBy(argIter.next())) { argIter.remove(); continue nextMatcher; } return false; } return true; } }NegatingArgumentConstraint.java000066400000000000000000000017701202022523300336670ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * * @author Peter Niederwieser */ public class NegatingArgumentConstraint implements IArgumentConstraint { private final IArgumentConstraint constraint; public NegatingArgumentConstraint(IArgumentConstraint constraint) { this.constraint = constraint; } public boolean isSatisfiedBy(Object arg) { return !constraint.isSatisfiedBy(arg); } } PositionalArgumentListConstraint.java000077500000000000000000000052021202022523300351050ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.spockframework.util.*; /** * * @author Peter Niederwieser */ public class PositionalArgumentListConstraint implements IInvocationConstraint { private final List argConstraints; public PositionalArgumentListConstraint(List argConstraints) { this.argConstraints = argConstraints; } public boolean isSatisfiedBy(IMockInvocation invocation) { List args = invocation.getArguments(); if (areConstraintsSatisfiedBy(args)) return true; if (!canBeCalledWithVarArgSyntax(invocation.getMethod())) return false; return areConstraintsSatisfiedBy(expandVarArgs(args)); } /** * Tells if the given method can be called with vararg syntax from Groovy(!). * If yes, we also support vararg syntax in the interaction definition. */ private boolean canBeCalledWithVarArgSyntax(Method method) { Class[] paramTypes = method.getParameterTypes(); return paramTypes.length > 0 && paramTypes[paramTypes.length - 1].isArray(); } private List expandVarArgs(List args) { List expanded = new ArrayList(); expanded.addAll(args.subList(0, args.size() - 1)); expanded.addAll(Arrays.asList((Object[]) CollectionUtil.getLastElement(args))); return expanded; } private boolean areConstraintsSatisfiedBy(List args) { if (argConstraints.isEmpty()) return args.isEmpty(); if (argConstraints.size() - args.size() > 1) return false; for (int i = 0; i < argConstraints.size() - 1; i++) { if (!argConstraints.get(i).isSatisfiedBy(args.get(i))) return false; } IArgumentConstraint lastConstraint = CollectionUtil.getLastElement(argConstraints); if (lastConstraint instanceof SpreadWildcardArgumentConstraint) return true; return argConstraints.size() == args.size() && lastConstraint.isSatisfiedBy(CollectionUtil.getLastElement(args)); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/RegexMethodNameConstraint.java000077500000000000000000000020511202022523300335170ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.regex.Pattern; /** * * @author Peter Niederwieser */ public class RegexMethodNameConstraint implements IInvocationConstraint { private final Pattern pattern; public RegexMethodNameConstraint(String regex) { pattern = Pattern.compile(regex); } public boolean isSatisfiedBy(IMockInvocation invocation) { return pattern.matcher(invocation.getMethod().getName()).matches(); } } RegexPropertyNameConstraint.java000077500000000000000000000022731202022523300340520ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.regex.Pattern; import org.spockframework.util.ReflectionUtil; /** * * @author Peter Niederwieser */ public class RegexPropertyNameConstraint implements IInvocationConstraint { private final Pattern pattern; public RegexPropertyNameConstraint(String regex) { pattern = Pattern.compile(regex); } public boolean isSatisfiedBy(IMockInvocation invocation) { String propertyName = ReflectionUtil.getPropertyNameForGetterMethod(invocation.getMethod()); return propertyName != null && pattern.matcher(propertyName).matches(); } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/ResultGeneratorChain.java000066400000000000000000000030401202022523300325220ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.util.InternalSpockError; import java.util.LinkedList; public class ResultGeneratorChain implements IResultGenerator { private IResultGenerator current; private final LinkedList remaining = new LinkedList(); public void addFirst(IResultGenerator generator) { if (current != null) remaining.addFirst(current); current = generator; } public boolean isEmpty() { return current == null; } public boolean isExhausted() { throw new InternalSpockError("isExhausted() isn't implemented for ResultGeneratorChain"); } public Object generate(IMockInvocation invocation) { if (isEmpty()) throw new InternalSpockError("ResultGeneratorChain should never be empty"); while (current.isExhausted() && !remaining.isEmpty()) { current = remaining.removeFirst(); } return current.generate(invocation); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/SingleResultGenerator.java000066400000000000000000000017761202022523300327370ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; public abstract class SingleResultGenerator implements IResultGenerator { private boolean exhausted = false; public boolean isExhausted() { return exhausted; } public final Object generate(IMockInvocation invocation) { exhausted = true; return generateSingle(invocation); } public abstract Object generateSingle(IMockInvocation invocation); } SpreadWildcardArgumentConstraint.java000066400000000000000000000022221202022523300350140ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import org.spockframework.lang.SpreadWildcard; import org.spockframework.runtime.InvalidSpecException; /** * * @author Peter Niederwieser */ public class SpreadWildcardArgumentConstraint implements IArgumentConstraint { public static final SpreadWildcardArgumentConstraint INSTANCE = new SpreadWildcardArgumentConstraint(); private SpreadWildcardArgumentConstraint() {} public boolean isSatisfiedBy(Object arg) { throw new InvalidSpecException("*_ may only appear at the end of an argument list"); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/TooFewInvocationsError.java000077500000000000000000000045271202022523300331020ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; import java.util.List; import org.spockframework.util.Assert; /** * Indicates that one or more required interactions have matched too few invocations. * * @author Peter Niederwieser */ public class TooFewInvocationsError extends InteractionNotSatisfiedError { private final List interactions; public TooFewInvocationsError(List interactions) { Assert.notNull(interactions); Assert.that(interactions.size() > 0); this.interactions = interactions; fixupStackTrace(); } @Override public String getMessage() { StringBuilder builder = new StringBuilder(); builder.append("Too few invocations for:\n\n"); for (IMockInteraction interaction : interactions) { builder.append(interaction); builder.append("\n"); } return builder.toString(); } // To facilitate navigation to the unsatisfied interactions, the line number // of the (synthetic) MockController.leaveScope() call is replaced by the line // number of the first unsatisfied interaction private void fixupStackTrace() { StackTraceElement[] trace = getStackTrace(); for (int i = 0; i < trace.length; i++) if (isLeaveScopeCall(trace[i])) { StackTraceElement elem = trace[i]; trace[i] = new StackTraceElement(elem.getClassName(), elem.getMethodName(), elem.getFileName(), interactions.get(0).getLine()); setStackTrace(trace); return; } Assert.fail("MockController.leaveScope() not found in stacktrace"); } private boolean isLeaveScopeCall(StackTraceElement elem) { return elem.getClassName().equals(MockController.class.getName()) && elem.getMethodName().equals(MockController.LEAVE_SCOPE); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/TooManyInvocationsError.java000077500000000000000000000031211202022523300332520ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * Indicates that a required interaction has matched too many invocations. * * @author Peter Niederwieser */ public class TooManyInvocationsError extends InteractionNotSatisfiedError { private final IMockInteraction interaction; private final IMockInvocation lastInvocation; public TooManyInvocationsError(IMockInteraction interaction, IMockInvocation lastInvocation) { this.interaction = interaction; this.lastInvocation = lastInvocation; } public IMockInteraction getInteraction() { return interaction; } public IMockInvocation getLastInvocation() { return lastInvocation; } @Override public String getMessage() { StringBuilder builder = new StringBuilder(); builder.append("Too many invocations for:\n\n"); builder.append(interaction); builder.append("\n\n"); builder.append("Last invocation: "); builder.append(lastInvocation); builder.append("\n"); return builder.toString(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/TypeArgumentConstraint.java000077500000000000000000000021321202022523300331270ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * * @author Peter Niederwieser */ public class TypeArgumentConstraint implements IArgumentConstraint { private final Class type; private final IArgumentConstraint constraint; public TypeArgumentConstraint(Class type, IArgumentConstraint constraint) { this.type = type; this.constraint = constraint; } public boolean isSatisfiedBy(Object argument) { return type.isInstance(argument) && constraint.isSatisfiedBy(argument); } } WildcardArgumentConstraint.java000066400000000000000000000017141202022523300336620ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * * @author Peter Niederwieser */ public class WildcardArgumentConstraint implements IArgumentConstraint { public static final WildcardArgumentConstraint INSTANCE = new WildcardArgumentConstraint(); private WildcardArgumentConstraint() {} public boolean isSatisfiedBy(Object arg) { return true; } } WildcardMethodNameConstraint.java000077500000000000000000000023101202022523300341150ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * @author Peter Niederwieser */ public class WildcardMethodNameConstraint implements IInvocationConstraint { public static final WildcardMethodNameConstraint INSTANCE = new WildcardMethodNameConstraint(); private WildcardMethodNameConstraint() {} public boolean isSatisfiedBy(IMockInvocation invocation) { if (DefaultEqualsInteraction.INSTANCE.matches(invocation)) return false; if (DefaultHashCodeInteraction.INSTANCE.matches(invocation)) return false; if (DefaultToStringInteraction.INSTANCE.matches(invocation)) return false; return true; } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/mock/WrongInvocationOrderError.java000066400000000000000000000036751202022523300336040ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock; /** * Thrown if an invocation on a mock object occurs too late. Example: * *
 * when:
 * ...
 *
 * then:
 * 1 * foo.me()
 * 1 * bar.me()
 *
 * then: // indicates that subsequent interactions must take place after previous interactions
 * 1 * baz.me()
 * 
* * Assuming the following invocation order: * *
    *
  1. bar.me()
  2. *
  3. baz.me()
  4. *
  5. foo.me()
  6. *
* * A WrongInvocationOrderError will be thrown on the third call. */ public class WrongInvocationOrderError extends InteractionNotSatisfiedError { private final IMockInteraction interaction; private final IMockInvocation lastInvocation; public WrongInvocationOrderError(IMockInteraction interaction, IMockInvocation lastInvocation) { this.interaction = interaction; this.lastInvocation = lastInvocation; } public IMockInteraction getInteraction() { return interaction; } public IMockInvocation getLastInvocation() { return lastInvocation; } @Override public String getMessage() { StringBuilder builder = new StringBuilder(); builder.append("Wrong invocation order for:\n\n"); builder.append(interaction); builder.append("\n\n"); builder.append("Last invocation: "); builder.append(lastInvocation); builder.append("\n"); return builder.toString(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/000077500000000000000000000000001202022523300263245ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/AbstractRunListener.java000066400000000000000000000022501202022523300331240ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.spockframework.runtime.model.*; public class AbstractRunListener implements IRunListener { public void beforeSpec(SpecInfo spec) {} public void beforeFeature(FeatureInfo feature) {} public void beforeIteration(IterationInfo iteration) {} public void afterIteration(IterationInfo iteration) {} public void afterFeature(FeatureInfo feature) {} public void afterSpec(SpecInfo spec) {} public void error(ErrorInfo error) {} public void specSkipped(SpecInfo spec) {} public void featureSkipped(FeatureInfo feature) {} } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/BaseSpecRunner.java000077500000000000000000000237061202022523300320610ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.lang.reflect.Method; import org.junit.runner.Description; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.runtime.extension.MethodInvocation; import org.spockframework.runtime.model.*; import org.spockframework.util.InternalSpockError; import org.spockframework.util.ReflectionUtil; import static org.spockframework.runtime.RunStatus.*; /** * Executes a single Spec. Notifies its supervisor about overall execution * progress and every invocation of Spec code. * Supervisor also determines the error strategy. * * @author Peter Niederwieser */ public class BaseSpecRunner { private static final Method DO_RUN_SPEC; private static final Method DO_RUN_FEATURE; private static final Method DO_RUN_ITERATION; protected static final Object[] EMPTY_ARGS = new Object[0]; protected final SpecInfo spec; protected final IRunSupervisor supervisor; protected FeatureInfo currentFeature; protected IterationInfo currentIteration; protected Object sharedInstance; protected Object currentInstance; protected int runStatus = OK; static { try { DO_RUN_SPEC = BaseSpecRunner.class.getMethod("doRunSpec"); DO_RUN_FEATURE = BaseSpecRunner.class.getMethod("doRunFeature"); DO_RUN_ITERATION = BaseSpecRunner.class.getMethod("doRunIteration"); } catch (NoSuchMethodException e) { throw new InternalSpockError(e); } } public BaseSpecRunner(SpecInfo spec, IRunSupervisor supervisor) { this.spec = spec; this.supervisor = supervisor; } public int run() { // Sometimes a spec run is requested even though the spec has been excluded // (e.g. if JUnit is in control). In such a case, the best thing we can do // is to treat the spec as skipped. if (spec.isExcluded() || spec.isSkipped()) { supervisor.specSkipped(spec); return OK; } createSpecInstance(true); invokeSharedInitializer(); runSpec(); return resetStatus(SPEC); } private void runSpec() { if (runStatus != OK) return; supervisor.beforeSpec(spec); invoke(this, createMethodInfoForDoRunSpec()); supervisor.afterSpec(spec); } private MethodInfo createMethodInfoForDoRunSpec() { MethodInfo result = new MethodInfo(); result.setParent(spec); result.setKind(MethodKind.SPEC_EXECUTION); result.setReflection(DO_RUN_SPEC); result.setDescription(spec.getDescription()); for (IMethodInterceptor interceptor : spec.getInterceptors()) result.addInterceptor(interceptor); return result; } /** * Only called via reflection. */ @SuppressWarnings("unused") public void doRunSpec() { invokeSetupSpec(); runFeatures(); invokeCleanupSpec(); } private void createSpecInstance(boolean shared) { if (runStatus != OK) return; try { if (shared) { sharedInstance = spec.getReflection().newInstance(); // make sure that x.getOrSetSomeSharedField() also works for x == sharedInstance // (important for setupSpec/cleanupSpec) spec.getSharedInstanceField().getReflection().set(sharedInstance, sharedInstance); } else { currentInstance = spec.getReflection().newInstance(); spec.getSharedInstanceField().getReflection().set(currentInstance, sharedInstance); } } catch (Throwable t) { throw new InternalSpockError("Failed to instantiate spec '%s'", t).withArgs(spec.getName()); } } private void invokeSharedInitializer() { for (SpecInfo curr : spec.getSpecsTopToBottom()) { if (runStatus != OK) return; invoke(sharedInstance, curr.getSharedInitializerMethod()); } } private void invokeSetupSpec() { for (SpecInfo curr : spec.getSpecsTopToBottom()) { if (runStatus != OK) return; invoke(sharedInstance, curr.getSetupSpecMethod()); } } private void runFeatures() { for (FeatureInfo feature : spec.getAllFeaturesInExecutionOrder()) { if (resetStatus(FEATURE) != OK) return; currentFeature = feature; runFeature(); currentFeature = null; } } private void invokeCleanupSpec() { for (SpecInfo curr : spec.getSpecsBottomToTop()) { if (action(runStatus) == ABORT) return; invoke(sharedInstance, curr.getCleanupSpecMethod()); } } private void runFeature() { if (runStatus != OK) return; if (currentFeature.isExcluded()) return; if (currentFeature.isSkipped()) { supervisor.featureSkipped(currentFeature); return; } supervisor.beforeFeature(currentFeature); invoke(this, createMethodInfoForDoRunFeature()); supervisor.afterFeature(currentFeature); } private MethodInfo createMethodInfoForDoRunFeature() { MethodInfo result = new MethodInfo(); result.setParent(currentFeature.getParent()); result.setKind(MethodKind.FEATURE_EXECUTION); result.setReflection(DO_RUN_FEATURE); result.setFeature(currentFeature); result.setDescription(currentFeature.getDescription()); for (IMethodInterceptor interceptor : currentFeature.getInterceptors()) result.addInterceptor(interceptor); return result; } /** * Only called via reflection. */ @SuppressWarnings("unused") public void doRunFeature() { currentFeature.setIterationNameProvider(new SafeIterationNameProvider(currentFeature.getIterationNameProvider())); if (currentFeature.isParameterized()) runParameterizedFeature(); else runSimpleFeature(); } private void runSimpleFeature() { if (runStatus != OK) return; initializeAndRunIteration(EMPTY_ARGS, 1); resetStatus(ITERATION); } protected void initializeAndRunIteration(Object[] dataValues, int estimatedNumIterations) { if (runStatus != OK) return; createSpecInstance(false); invokeInitializer(); // TODO: must not invoke cleanup() methods if initializer fails runIteration(dataValues, estimatedNumIterations); } private void runIteration(Object[] dataValues, int estimatedNumIterations) { if (runStatus != OK) return; currentIteration = createIterationInfo(dataValues, estimatedNumIterations); supervisor.beforeIteration(currentIteration); invoke(this, createMethodInfoForDoRunIteration()); supervisor.afterIteration(currentIteration); currentIteration = null; } private IterationInfo createIterationInfo(Object[] dataValues, int estimatedNumIterations) { currentIteration = new IterationInfo(currentFeature, dataValues, estimatedNumIterations); String iterationName = currentFeature.getIterationNameProvider().getName(currentIteration); currentIteration.setName(iterationName); Description description = Description.createTestDescription(spec.getReflection(), iterationName, currentFeature.getFeatureMethod().getReflection().getAnnotations()); currentIteration.setDescription(description); return currentIteration; } private MethodInfo createMethodInfoForDoRunIteration() { MethodInfo result = new MethodInfo(); result.setParent(currentFeature.getParent()); result.setKind(MethodKind.ITERATION_EXECUTION); result.setReflection(DO_RUN_ITERATION); result.setFeature(currentFeature); result.setDescription(currentFeature.getDescription()); for (IMethodInterceptor interceptor : currentFeature.getIterationInterceptors()) result.addInterceptor(interceptor); return result; } /** * Only called via reflection. */ @SuppressWarnings("unused") public void doRunIteration() { invokeSetup(); invokeFeatureMethod(); invokeCleanup(); } protected int resetStatus(int scope) { if (scope(runStatus) <= scope) runStatus = OK; return runStatus; } protected void runParameterizedFeature() { throw new UnsupportedOperationException("This runner cannot run parameterized features"); } private void invokeInitializer() { for (SpecInfo curr : spec.getSpecsTopToBottom()) { if (runStatus != OK) return; invoke(currentInstance, curr.getInitializerMethod()); } } private void invokeSetup() { for (SpecInfo curr : spec.getSpecsTopToBottom()) { if (runStatus != OK) return; invoke(currentInstance, curr.getSetupMethod()); } } private void invokeFeatureMethod() { if (runStatus != OK) return; invoke(currentInstance, currentFeature.getFeatureMethod(), currentIteration.getDataValues()); } private void invokeCleanup() { for (SpecInfo curr : spec.getSpecsBottomToTop()) { if (action(runStatus) == ABORT) return; invoke(currentInstance, curr.getCleanupMethod()); } } private void invoke(Object target, MethodInfo method, Object... arguments) { // fast lane if (method.getInterceptors().isEmpty()) { invokeRaw(target, method, arguments); return; } // slow lane MethodInvocation invocation = new MethodInvocation(currentFeature, currentIteration, sharedInstance, currentInstance, target, method, arguments); try { invocation.proceed(); } catch (Throwable t) { ErrorInfo error = new ErrorInfo(method, t); runStatus = supervisor.error(error); } } protected Object invokeRaw(Object target, MethodInfo method, Object... arguments) { if (method.isStub()) return null; try { return ReflectionUtil.invokeMethod(target, method.getReflection(), arguments); } catch (Throwable t) { runStatus = supervisor.error(new ErrorInfo(method, t)); return null; } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/Condition.java000066400000000000000000000055201202022523300311170ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.regex.Pattern; import org.spockframework.runtime.model.ExpressionInfo; import org.spockframework.runtime.model.TextPosition; import org.spockframework.util.Nullable; /** * Runtime representation of an evaluated condition. * * @author Peter Niederwieser */ public class Condition { private static final Pattern pattern = Pattern.compile("\\s*\n\\s*"); private final Iterable values; private final String text; private final TextPosition position; private final String message; private volatile ExpressionInfo expression; private volatile String rendering; public Condition(@Nullable Iterable values, @Nullable String text, TextPosition position, @Nullable String message) { this.text = text; this.position = position; this.values = values; this.message = message; } @Nullable public Iterable getValues() { return values; } @Nullable public String getText() { return text; } public TextPosition getPosition() { return position; } @Nullable public String getMessage() { return message; } @Nullable public ExpressionInfo getExpression() { if (expression == null) { createExpression(); } return expression; } public String getRendering() { if (rendering == null) { createRendering(); } return rendering; } private void createExpression() { if (text == null || values == null) return; expression = new ExpressionInfoBuilder(flatten(text), TextPosition.create(1, 1), values).build(); } private void createRendering() { StringBuilder builder = new StringBuilder(); if (getExpression() != null) { ExpressionInfoValueRenderer.render(expression); builder.append(ExpressionInfoRenderer.render(expression)); } else if (text != null) { builder.append(flatten(text)); builder.append("\n"); } else { builder.append("(Source code not available)\n"); } if (message != null) { builder.append("\n"); builder.append(message); builder.append("\n"); } rendering = builder.toString(); } private String flatten(String text) { return pattern.matcher(text).replaceAll(" "); } } ConditionNotSatisfiedError.java000077500000000000000000000020651202022523300343730ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; /** * @author Peter Niederwieser */ public class ConditionNotSatisfiedError extends SpockAssertionError { private final Condition condition; public ConditionNotSatisfiedError(Condition condition) { this.condition = condition; } public Condition getCondition() { return condition; } @Override public String getMessage() { return "Condition not satisfied:\n\n" + condition.getRendering(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/ConfigurationBuilder.java000066400000000000000000000024161202022523300333100ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.Arrays; import java.util.List; import org.spockframework.builder.*; public class ConfigurationBuilder { private final GestaltBuilder gestaltBuilder = new GestaltBuilder(); private final List slotFactories = Arrays.asList(new SetterSlotFactory(), new AddSlotFactory(), new CollectionSlotFactory()); public void build(List configurations, DelegatingScript configScript) { IBlueprint blueprint = new DelegatingScriptBlueprint(configScript); IGestalt configGestalt = new SpockConfigurationGestalt(configurations, blueprint, slotFactories); gestaltBuilder.build(configGestalt); } } ConfigurationScriptLoader.java000066400000000000000000000117201202022523300342340ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.io.File; import java.io.IOException; import java.net.URL; import java.security.AccessControlException; import org.codehaus.groovy.control.CompilationFailedException; import org.codehaus.groovy.control.CompilerConfiguration; import org.spockframework.builder.DelegatingScript; import org.spockframework.util.GroovyRuntimeUtil; import org.spockframework.util.Nullable; import spock.config.ConfigurationException; import groovy.lang.*; public class ConfigurationScriptLoader { private static final String DEFAULT_CONFIG_PROPERTY_KEY = "spock.configuration"; private static final String DEFAULT_CLASS_PATH_LOCATION = "SpockConfig.groovy"; private static final String DEFAULT_FILE_SYSTEM_LOCATION = System.getProperty("user.home") + File.separator + ".spock" + File.separator + "SpockConfig.groovy"; private final String configPropertyKey; private final String classPathLocation; private final String fileSystemLocation; public ConfigurationScriptLoader() { this(DEFAULT_CONFIG_PROPERTY_KEY, DEFAULT_CLASS_PATH_LOCATION, DEFAULT_FILE_SYSTEM_LOCATION); } /** * For testing purposes. Do not use directly. */ ConfigurationScriptLoader(String configPropertyKey, String classPathLocation, String fileSystemLocation) { this.configPropertyKey = configPropertyKey; this.classPathLocation = classPathLocation; this.fileSystemLocation = fileSystemLocation; } public @Nullable DelegatingScript loadAutoDetectedScript() { DelegatingScript script = loadScriptFromSystemPropertyInducedLocation(configPropertyKey); if (script != null) return script; script = loadScriptFromClassPathLocation(classPathLocation); if (script != null) return script; script = loadScriptFromFileSystemLocation(fileSystemLocation); if (script != null) return script; return null; } public DelegatingScript loadClosureBasedScript(final Closure closure) { return new DelegatingScript() { @Override public Object run() { GroovyRuntimeUtil.invokeClosure(closure); return null; } @Override public void $setDelegate(Object delegate) { closure.setResolveStrategy(Closure.DELEGATE_FIRST); closure.setDelegate(delegate); } }; } private @Nullable DelegatingScript loadScriptFromSystemPropertyInducedLocation(String propertyKey) { String location = System.getProperty(propertyKey); if (location == null || location.length() == 0) return null; DelegatingScript script = loadScriptFromClassPathLocation(location); if (script != null) return script; script = loadScriptFromFileSystemLocation(location); if (script != null) return script; throw new ConfigurationException("Cannot find configuration script '%s'", location); } private @Nullable DelegatingScript loadScriptFromFileSystemLocation(String location) { File file = new File(location); try { if (!file.exists()) return null; } catch (AccessControlException e) { // no permission to check for existence of file (e.g. on Spock Web Console), // so let's just assume it's not there and continue return null; } GroovyShell shell = createShell(); try { return (DelegatingScript) shell.parse(file); } catch (IOException e) { throw new ConfigurationException("Error reading configuration script '%s'", location); } catch (CompilationFailedException e) { throw new ConfigurationException("Error compiling configuration script '%s'", location); } } private @Nullable DelegatingScript loadScriptFromClassPathLocation(String location) { URL url = this.getClass().getClassLoader().getResource(location); if (url == null) return null; GroovyShell shell = createShell(); try { return (DelegatingScript) shell.parse(new GroovyCodeSource(url)); } catch (IOException e) { throw new ConfigurationException("Error reading configuration script '%s'", location); } catch (CompilationFailedException e) { throw new ConfigurationException("Error compiling configuration script '%s'", location); } } private GroovyShell createShell() { CompilerConfiguration compilerSettings = new CompilerConfiguration(); compilerSettings.setScriptBaseClass(DelegatingScript.class.getName()); return new GroovyShell(getClass().getClassLoader(), new Binding(), compilerSettings); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/DummyStackTraceFilter.java000066400000000000000000000014061202022523300333760ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; public class DummyStackTraceFilter implements IStackTraceFilter { public void filter(Throwable throwable) {} // do nothing } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/ExpressionInfoBuilder.java000077500000000000000000000064611202022523300334630ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.Iterator; import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.stmt.*; import org.codehaus.groovy.control.SourceUnit; import org.spockframework.runtime.model.*; import org.spockframework.util.Assert; import org.spockframework.util.TextUtil; /** * * @author Peter Niederwieser */ public class ExpressionInfoBuilder { private final String text; private final String adjustedText; private final TextPosition startPos; private final Iterable values; private final String[] lines; public ExpressionInfoBuilder(String text, TextPosition startPos, Iterable values) { this.text = text; this.startPos = startPos; this.values = values; adjustedText = TextUtil.repeatChar(' ', startPos.getColumnIndex()) + text; lines = adjustedText.split("\n"); } public ExpressionInfo build() { SourceUnit unit = SourceUnit.create("Spec expression", adjustedText); unit.parse(); unit.completePhase(); unit.convert(); BlockStatement blockStat = unit.getAST().getStatementBlock(); Assert.that(blockStat != null && blockStat.getStatements().size() == 1); Statement stat = blockStat.getStatements().get(0); Assert.that(stat instanceof ExpressionStatement); Expression expr = ((ExpressionStatement)stat).getExpression(); ExpressionInfo exprInfo = new ExpressionInfoConverter(lines).convert(expr); // IDEA: rest of this method could be moved to ExpressionInfoConverter (but: might make EIC less testable) // IDEA: could make ExpressionInfo immutable Iterator iter = values.iterator(); for (ExpressionInfo info : exprInfo.inPostfixOrder(false)) { info.setText(findText(info.getRegion())); if (!iter.hasNext()) Assert.fail("Missing value for expression '%s' in condition '%s'", info.getText(), text); info.setValue(iter.next()); if (startPos.getLineIndex() > 0) info.shiftVertically(startPos.getLineIndex()); } return exprInfo; } private String findText(TextRegion region) { if (region == TextRegion.NOT_AVAILABLE) return ExpressionInfo.TEXT_NOT_AVAILABLE; try { String text = ""; for (int i = 0; i <= region.getEnd().getLineIndex(); i++) { String line = lines[i]; if (i == region.getEnd().getLineIndex()) line = line.substring(0, region.getEnd().getColumnIndex()); if (i == region.getStart().getLineIndex()) line = line.substring(region.getStart().getColumnIndex()); text += line; if (i != region.getEnd().getLineIndex()) text += '\n'; } return text; } catch (IndexOutOfBoundsException e) { return ExpressionInfo.TEXT_NOT_AVAILABLE; } } } ExpressionInfoConverter.java000077500000000000000000000273511202022523300337660ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.*; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.expr.*; import org.codehaus.groovy.classgen.BytecodeExpression; import org.codehaus.groovy.syntax.Types; import org.spockframework.runtime.model.*; import org.spockframework.util.AbstractExpressionConverter; // NOTE: expressions which don't produce a value are handled as follows: // - exactly one child: don't create ExpressionInfo (replace with child's ExpressionInfo) // - no child or more than one child: create ExpressionInfo and set hasValue to false // NOTE: because Expression's followed by a token often have incorrect column number, we always // search for the token backwards from the subsequent expression // IDEA: combine with value population because values might provide some additional // hints about the real nature of a node (as we are only in phase CONVERSION) public class ExpressionInfoConverter extends AbstractExpressionConverter { private final String[] lines; public ExpressionInfoConverter(String[] lines) { this.lines = lines; } public void visitMethodCallExpression(MethodCallExpression expr) { TextPosition anchor = TextPosition.startOf(expr.getMethod()); List children = new ArrayList(); if (!expr.isImplicitThis()) children.add(convert(expr.getObjectExpression())); children.add(convert(expr.getMethod())); children.add(convert(expr.getArguments())); result = new ExpressionInfo( TextRegion.of(expr), anchor, expr.getMethodAsString(), children); } public void visitBytecodeExpression(BytecodeExpression expr) { unsupported(); } public void visitStaticMethodCallExpression(StaticMethodCallExpression expr) { unsupported(); // still a MethodCallExpression in phase conversion } public void visitConstructorCallExpression(ConstructorCallExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "", convert(expr.getArguments())); } @SuppressWarnings("unchecked") public void visitArgumentlistExpression(ArgumentListExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), null, convertAll(expr.getExpressions()) ).setRelevant(false); } public void visitPropertyExpression(PropertyExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr.getProperty()), expr.getPropertyAsString(), expr.isImplicitThis() ? Collections.emptyList() : Collections.singletonList(convert(expr.getObjectExpression()))); } public void visitAttributeExpression(AttributeExpression expr) { visitPropertyExpression(expr); } public void visitFieldExpression(FieldExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), expr.getFieldName() ); } public void visitMethodPointerExpression(MethodPointerExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr.getMethodName()), expr.getMethodName().getText(), convert(expr.getExpression()), convert(expr.getMethodName()) ).setRelevant(false); } public void visitVariableExpression(VariableExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), expr.getName() ).setRelevant(expr != VariableExpression.THIS_EXPRESSION && expr != VariableExpression.SUPER_EXPRESSION); } public void visitDeclarationExpression(DeclarationExpression expression) { unsupported(); } public void visitConstantExpression(ConstantExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), expr.getConstantName() ).setRelevant(false); } public void visitClassExpression(ClassExpression expr) { // also used in phase conversion, e.g. in instanceof expression result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), null ).setRelevant(false); } public void visitBinaryExpression(BinaryExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), expr.getOperation().getType() == Types.LEFT_SQUARE_BRACKET ? startOf("[", expr.getRightExpression()) : // workaround for the fact that Token.startLine == 0 for token [ TextPosition.startOf(expr.getOperation()), expr.getOperation().getText(), convert(expr.getLeftExpression()), convert(expr.getRightExpression()) ); } public void visitUnaryMinusExpression(UnaryMinusExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "-", convert(expr.getExpression())); } public void visitUnaryPlusExpression(UnaryPlusExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "+", convert(expr.getExpression())); } public void visitNotExpression(NotExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "!", convert(expr.getExpression())); } public void visitBitwiseNegationExpression(BitwiseNegationExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "^", convert(expr.getExpression())); } @SuppressWarnings("unchecked") public void visitListExpression(ListExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "[]", convertAll(expr.getExpressions()) ).setRelevant(false); } public void visitRangeExpression(RangeExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), startOf("..", expr.getTo()), "..", convert(expr.getFrom()), convert(expr.getTo()) ).setRelevant(false); } @SuppressWarnings("unchecked") public void visitMapExpression(MapExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "[:]", convertAll(expr.getMapEntryExpressions()) ).setRelevant(false); } public void visitMapEntryExpression(MapEntryExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), startOf(":", expr.getValueExpression()), null, convert(expr.getKeyExpression()), convert(expr.getValueExpression()) ); } @SuppressWarnings("unchecked") public void visitGStringExpression(GStringExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "\"\"", convertAll(expr.getValues()) ).setRelevant(false); } public void visitTernaryExpression(TernaryExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), startOf("?", expr.getTrueExpression()), "?:", convertAll( Arrays.asList( expr.getBooleanExpression(), expr.getTrueExpression(), expr.getFalseExpression())) ).setRelevant(false); } public void visitShortTernaryExpression(ElvisOperatorExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), startOf("?", expr.getFalseExpression()), "?:", convert(expr.getTrueExpression()), convert(expr.getFalseExpression()) ).setRelevant(false); } public void visitPrefixExpression(PrefixExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), expr.getOperation().getText(), convert(expr.getExpression())); } public void visitPostfixExpression(PostfixExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), expr.getOperation().getText(), convert(expr.getExpression())); } public void visitBooleanExpression(BooleanExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), null, convert(expr.getExpression()) ).setRelevant(false); } public void visitClosureExpression(ClosureExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "{->}" ).setRelevant(false); } @SuppressWarnings("unchecked") public void visitTupleExpression(TupleExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), null, convertAll(expr.getExpressions()) ).setRelevant(false); } public void visitCastExpression(CastExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "as", convert(expr.getExpression()) ).setRelevant(false); } public void visitClosureListExpression(ClosureListExpression expr) { unsupported(); // cannot occur in assertion } @SuppressWarnings("unchecked") public void visitArrayExpression(ArrayExpression expr) { List children = convertAll(expr.getExpressions()); children.addAll(convertAll(expr.getSizeExpression())); result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), null, children ).setRelevant(false); } public void visitSpreadExpression(SpreadExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "*", convert(expr.getExpression()) ).setRelevant(false); } public void visitSpreadMapExpression(SpreadMapExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr), "*:" ); } // searches for token backwards from beginning of node (exclusive) // IDEA: move to class TextPosition? private TextPosition startOf(String token, ASTNode node) { // try to compensate for the fact that getLastLineNumber() is sometimes wrong int lastLineIndex = Math.max(node.getLineNumber(), node.getLastLineNumber()) - 1; for (int lineIndex = lastLineIndex; lineIndex >= 0; lineIndex--) { int columnIndex = lineIndex == lastLineIndex ? lines[lineIndex].lastIndexOf(token, node.getColumnNumber() - 1) : lines[lineIndex].lastIndexOf(token); if (columnIndex != -1) return TextPosition.create(lineIndex + 1, columnIndex + 1); } throw new IllegalArgumentException(String.format("token %s not found in expression", token)); } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/ExpressionInfoRenderer.java000066400000000000000000000100561202022523300336330ustar00rootroot00000000000000/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.*; import org.spockframework.runtime.model.ExpressionInfo; import org.spockframework.runtime.model.TextPosition; /** * Creates a string representation of an assertion and its recorded values. * * @author Peter Niederwieser */ public class ExpressionInfoRenderer { private final ExpressionInfo expr; private final List lines = new ArrayList(); // startColumns.get(i) is the first non-empty column of lines.get(i) private final List startColumns = new ArrayList(); private ExpressionInfoRenderer(ExpressionInfo expr) { TextPosition start = expr.getRegion().getStart(); if (start.getLine() != 1 || start.getColumn() != 1) throw new IllegalArgumentException("can only print expressions starting at 1,1"); if (expr.getRegion().getEnd().getLine() != 1) throw new IllegalArgumentException("can only print expressions ending on line 1"); this.expr = expr; } public static String render(ExpressionInfo expr) { return new ExpressionInfoRenderer(expr).render(); } private String render() { placeText(); placeValues(); return linesToString(); } private void placeText() { lines.add(new StringBuilder(expr.getText())); startColumns.add(0); } private void placeValues() { Comparator comparator = new Comparator() { public int compare(ExpressionInfo expr1, ExpressionInfo expr2) { return expr2.getAnchor().getColumn() - expr1.getAnchor().getColumn(); } }; for (ExpressionInfo expr : this.expr.inCustomOrder(true, comparator)) placeValue(expr); } private void placeValue(ExpressionInfo expr) { String str = expr.getRenderedValue(); if (str == null) return; int startColumn = expr.getAnchor().getColumn(); if (startColumn < 1) return; // node with invalid source position String[] strs = str.split("\r\n|\r|\n"); int endColumn = strs.length == 1 ? expr.getAnchor().getColumn() + str.length() : // exclusive Integer.MAX_VALUE; // multi-line strings are always placed on new lines if (lines.size() == 1) { // we have never placed a value yet // let's add an empty line between text and values lines.add(new StringBuilder()); startColumns.add(0); } for (int i = 1; i < lines.size(); i++) if (endColumn < startColumns.get(i)) { placeString(lines.get(i), str, startColumn); startColumns.set(i, startColumn); return; } else { placeString(lines.get(i), "|", startColumn); if (i > 1) // i == 1 is the empty line between text and values, which should stay empty startColumns.set(i, startColumn + 1); // + 1: no whitespace required between end of value and "|" } // value could not be placed on existing lines, so place it on new line(s) for (String s : strs) { StringBuilder newLine = new StringBuilder(); lines.add(newLine); placeString(newLine, s, startColumn); startColumns.add(startColumn); } } private String linesToString() { StringBuilder result = new StringBuilder(); for (StringBuilder line : lines) result.append(line).append('\n'); return result.toString(); } private static void placeString(StringBuilder line, String str, int column) { while (line.length() < column) line.append(' '); line.replace(column - 1, column - 1 + str.length(), str); } } ExpressionInfoValueRenderer.java000066400000000000000000000105621202022523300345530ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import groovy.lang.GString; import org.spockframework.runtime.condition.EditDistance; import org.spockframework.runtime.condition.EditPathRenderer; import org.spockframework.runtime.model.ExpressionInfo; import org.spockframework.util.GroovyRuntimeUtil; import org.spockframework.util.ObjectUtil; import org.spockframework.util.Nullable; public class ExpressionInfoValueRenderer { private final ExpressionInfo expr; private ExpressionInfoValueRenderer(ExpressionInfo expr) { this.expr = expr; } public static void render(ExpressionInfo expr) { new ExpressionInfoValueRenderer(expr).render(); } private void render() { for (ExpressionInfo expr : this.expr.inPostfixOrder(true)) { expr.setRenderedValue(renderValue(expr)); } } /** * Returns a string representation of a value, or null if * the value should not be shown (because it does not add any valuable * information). Note that the method may also change rendered values * of child expression. * * @param expr the expression whose value is to be rendered * @return a string representation of the value */ @Nullable private String renderValue(ExpressionInfo expr) { Object value = expr.getValue(); if (value == null) return "null"; if ("".equals(value)) return "\"\""; // value.equals() might throw exception, so we use "".equals() instead String str; try { str = doRenderValue(expr); } catch (Exception e) { return String.format("%s (renderer threw %s)", javaLangObjectToString(value), e.getClass().getSimpleName()); } if (str == null || str.equals("")) { return javaLangObjectToString(value); } // only print enum values that add valuable information if (value instanceof Enum) { String text = expr.getText().trim(); int index = text.lastIndexOf('.'); String potentialEnumConstantNameInText = text.substring(index + 1); if (str.equals(potentialEnumConstantNameInText)) return null; } return str; } private String javaLangObjectToString(Object value) { String hash = Integer.toHexString(System.identityHashCode(value)); return value.getClass().getName() + "@" + hash; } private String doRenderValue(ExpressionInfo expr) { String result = renderAsStringComparison(expr); if (result != null) return result; result = renderAsEqualityComparison(expr); if (result != null) return result; return GroovyRuntimeUtil.toString(expr.getValue()); } private String renderAsStringComparison(ExpressionInfo expr) { if (!expr.isEqualityComparison(String.class, GString.class)) return null; // values can't be null here String str1 = expr.getChildren().get(0).getValue().toString(); String str2 = expr.getChildren().get(1).getValue().toString(); EditDistance dist = new EditDistance(str1, str2); return String.format("false\n%d difference%s (%d%% similarity)\n%s", dist.getDistance(), dist.getDistance() == 1 ? "" : "s", dist.getSimilarityInPercent(), new EditPathRenderer().render(str1, str2, dist.calculatePath())); } private String renderAsEqualityComparison(ExpressionInfo expr) { if (!expr.isEqualityComparison()) return null; ExpressionInfo expr1 = expr.getChildren().get(0); ExpressionInfo expr2 = expr.getChildren().get(1); if (expr1.getEffectiveRenderedValue().equals(expr2.getEffectiveRenderedValue())) { addTypeHint(expr1); addTypeHint(expr2); } return "false"; } private void addTypeHint(ExpressionInfo expr) { if (expr.getRenderedValue() == null) return; Class exprType = ObjectUtil.voidAwareGetClass(expr.getValue()); expr.setRenderedValue(expr.getRenderedValue() + " (" + exprType.getName() + ")"); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/ExtensionClassesLoader.java000066400000000000000000000053211202022523300336110ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.io.*; import java.net.URL; import java.util.*; import org.spockframework.runtime.extension.ExtensionException; import org.spockframework.runtime.extension.IGlobalExtension; import org.spockframework.util.IoUtil; /** * Scans class path for extension descriptors and loads the extension classes specified therein. */ public class ExtensionClassesLoader { public static final String EXTENSION_DESCRIPTOR_PATH = "META-INF/services/" + IGlobalExtension.class.getName(); public List> loadClassesFromDefaultLocation() { return loadClasses(EXTENSION_DESCRIPTOR_PATH); } public List> loadClasses(String descriptorPath) { List> extClasses = new ArrayList>(); for (URL url : locateDescriptors(descriptorPath)) for (String className : readDescriptor(url)) extClasses.add(loadExtensionClass(className)); return extClasses; } private List locateDescriptors(String descriptorPath) { try { return Collections.list(RunContext.class.getClassLoader().getResources(descriptorPath)); } catch (Exception e) { throw new ExtensionException("Failed to locate extension descriptors", e); } } private List readDescriptor(URL url) { BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(url.openStream())); List lines = new ArrayList(); String line = reader.readLine(); while (line != null) { line = line.trim(); if (line.length() > 0 && !line.startsWith("#")) lines.add(line); line = reader.readLine(); } return lines; } catch (IOException e) { throw new ExtensionException("Failed to read extension descriptor '%s'", e).withArgs(url); } finally { IoUtil.closeQuietly(reader); } } private Class loadExtensionClass(String className) { try { return RunContext.class.getClassLoader().loadClass(className); } catch (Exception e) { throw new ExtensionException("Failed to load extension class '%s'", e).withArgs(className); } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/ExtensionRegistry.java000066400000000000000000000066541202022523300327070ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.lang.reflect.Field; import java.util.*; import org.spockframework.runtime.extension.ExtensionException; import org.spockframework.runtime.extension.IGlobalExtension; import org.spockframework.util.UnreachableCodeError; /** * Collects all Spock extensions found on the class path (via their descriptor). * * @author Peter Niederwieser */ public class ExtensionRegistry { private final List> extensionClasses; private final List configurations; private final List extensions = new ArrayList(); ExtensionRegistry(List> extensionClasses, List configurations) { this.extensionClasses = extensionClasses; this.configurations = configurations; } public void loadExtensions() { for (Class clazz : extensionClasses) extensions.add(configureExtension(instantiateExtension(verifyExtensionClass(clazz)))); } public List getExtensions() { return extensions; } private Class verifyExtensionClass(Class clazz) { if (!IGlobalExtension.class.isAssignableFrom(clazz)) throw new ExtensionException( "Class '%s' is not a valid global extension because it is not derived from '%s'" ).withArgs(clazz.getName(), IGlobalExtension.class.getName()); return clazz; } private IGlobalExtension instantiateExtension(Class clazz) { try { return (IGlobalExtension)clazz.newInstance(); } catch (Exception e) { throw new ExtensionException("Failed to instantiate extension '%s'", e).withArgs(clazz.getName()); } } private IGlobalExtension configureExtension(IGlobalExtension extension) { for (Field field : extension.getClass().getDeclaredFields()) if (field.getType().getSimpleName().endsWith("Configuration")) injectConfiguration(field, extension); return extension; } private void injectConfiguration(Field field, Object extension) { Object config = getOrCreateConfiguration(field.getType()); field.setAccessible(true); try { field.set(extension, config); } catch (IllegalAccessException e) { throw new UnreachableCodeError(); } } private Object getOrCreateConfiguration(Class type) { for (Object config : configurations) if (config.getClass() == type) return config; Object config = createConfiguration(type); configurations.add(config); return config; } private Object createConfiguration(Class type) { try { return type.newInstance(); } catch (InstantiationException e) { throw new ExtensionException("Cannot instantiate configuration class %s").withArgs(type); } catch (IllegalAccessException e) { throw new ExtensionException("Configuration class '%s' has no public no-arg constructor").withArgs(type); } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/ExtensionRunner.java000066400000000000000000000075331202022523300323450ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.lang.annotation.Annotation; import java.util.*; import org.spockframework.runtime.extension.*; import org.spockframework.runtime.model.*; /** * Runs global and local extensions for a spec. */ public class ExtensionRunner { private final SpecInfo spec; private final List globalExtensions; private final Map, IAnnotationDrivenExtension> localExtensions = new HashMap, IAnnotationDrivenExtension>(); public ExtensionRunner(SpecInfo spec, List globalExtensions) { this.spec = spec; this.globalExtensions = globalExtensions; } public void run() { runGlobalExtensions(); runAnnotationDrivenExtensions(); } private void runGlobalExtensions() { for (IGlobalExtension extension : globalExtensions) extension.visitSpec(spec); } public void runAnnotationDrivenExtensions() { runAnnotationDrivenExtensions(spec); for (IAnnotationDrivenExtension extension : localExtensions.values()) extension.visitSpec(spec); } public void runAnnotationDrivenExtensions(SpecInfo spec) { if (spec == null) return; runAnnotationDrivenExtensions(spec.getSuperSpec()); doRunAnnotationDrivenExtensions(spec); for (FieldInfo field : spec.getFields()) doRunAnnotationDrivenExtensions(field); doRunAnnotationDrivenExtensions(spec.getSetupSpecMethod()); doRunAnnotationDrivenExtensions(spec.getSetupMethod()); doRunAnnotationDrivenExtensions(spec.getCleanupMethod()); doRunAnnotationDrivenExtensions(spec.getCleanupSpecMethod()); for (FeatureInfo feature : spec.getFeatures()) doRunAnnotationDrivenExtensions(feature.getFeatureMethod()); } @SuppressWarnings("unchecked") private void doRunAnnotationDrivenExtensions(NodeInfo node) { if (node.isStub()) return; for (Annotation ann : node.getReflection().getAnnotations()) { ExtensionAnnotation extAnn = ann.annotationType().getAnnotation(ExtensionAnnotation.class); if (extAnn == null) continue; IAnnotationDrivenExtension extension = getOrCreateExtension(extAnn.value()); if (node instanceof SpecInfo) extension.visitSpecAnnotation(ann, (SpecInfo) node); else if (node instanceof MethodInfo) { MethodInfo method = (MethodInfo) node; if (method.getKind() == MethodKind.FEATURE) extension.visitFeatureAnnotation(ann, method.getFeature()); else extension.visitFixtureAnnotation(ann, method); } else extension.visitFieldAnnotation(ann, (FieldInfo) node); } } private IAnnotationDrivenExtension getOrCreateExtension(Class clazz) { IAnnotationDrivenExtension result = localExtensions.get(clazz); if (result == null) { try { result = clazz.newInstance(); } catch (InstantiationException e) { throw new ExtensionException("Failed to instantiate extension '%s'", e).withArgs(clazz); } catch (IllegalAccessException e) { throw new ExtensionException("No-arg constructor of extension '%s' is not public", e).withArgs(clazz); } localExtensions.put(clazz, result); } return result; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/HamcrestFacade.java000066400000000000000000000054311202022523300320240ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.lang.reflect.Method; import org.hamcrest.*; import org.spockframework.util.Nullable; import org.spockframework.util.ReflectionUtil; /** * Facade around Hamcrest API that works both with Hamcrest 1.1 and 1.2, * providing better failure descriptions if the latter is available. * HamcrestFacade.isMatcher() can safely be called no matter if Hamcrest * classes are available on the class path. The remaining methods assume * that Hamcrest classes are available. * * @author Peter Niederwieser */ public abstract class HamcrestFacade { private static final boolean hamcrestAvailable = ReflectionUtil.isClassAvailable("org.hamcrest.Matcher"); public static boolean isMatcher(Object obj) { return hamcrestAvailable && HamcrestFacadeImpl.isMatcher(obj); } public static boolean matches(Object matcher, Object value) { return HamcrestFacadeImpl.matches(matcher, value); } public static String getFailureDescription(Object matcher, Object value, @Nullable String message) { return HamcrestFacadeImpl.getFailureDescription(matcher, value, message); } private static abstract class HamcrestFacadeImpl { static final Method describeMismatchMethod = ReflectionUtil.getMethodByName(Matcher.class, "describeMismatch"); static boolean isMatcher(Object obj) { return obj instanceof Matcher; } static boolean matches(Object matcher, Object value) { return ((Matcher) matcher).matches(value); } static String getFailureDescription(Object matcher, Object value, @Nullable String message) { Description description = new StringDescription(); if (message != null) { description.appendText(message); description.appendText("\n\n"); } description.appendText("Expected: ") .appendDescriptionOf((Matcher) matcher); if (describeMismatchMethod == null) { // 1.1 description.appendText("\n got: ") .appendValue(value); } else { // 1.2 description.appendText("\n but: "); ReflectionUtil.invokeMethod(matcher, describeMismatchMethod, value, description); } return description.toString(); } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/IFeatureFilter.java000066400000000000000000000014701202022523300320430ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.spockframework.runtime.model.FeatureInfo; /** * * @author Peter Niederwieser */ public interface IFeatureFilter { boolean matches(FeatureInfo feature); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/IFeatureSortOrder.java000066400000000000000000000015151202022523300325410ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.Comparator; import org.spockframework.runtime.model.FeatureInfo; /** * @author Peter Niederwieser */ public interface IFeatureSortOrder extends Comparator {} spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/IMethodNameMapper.java000066400000000000000000000016621202022523300324730ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; /** * Maps method names in bytecode to their logical names. Typically used for feature methods. * * @author Peter Niederwieser */ public interface IMethodNameMapper { boolean isInitializerOrFixtureMethod(String className, String methodName); String toFeatureName(String methodName); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/IRunListener.java000066400000000000000000000050161202022523300315540ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.spockframework.runtime.extension.builtin.StepwiseExtension; import org.spockframework.runtime.model.*; /** * Listens to a spec run. Currently, only extensions can register listeners. * They do so by invoking SpecInfo.addListener(). See * {@link StepwiseExtension} for an example of how to use a listener. * * @author Peter Niederwieser */ public interface IRunListener { /** * Called before a spec. */ void beforeSpec(SpecInfo spec); /** * Called before each feature of a spec. */ void beforeFeature(FeatureInfo feature); /** * Called before each iteration of a data-driven feature. * All data values have been computed successfully * at this point. * Not called for features that aren't data-driven (i.e. * don't have a where-block). */ void beforeIteration(IterationInfo iteration); /** * Called after each iteration of a data-driven feature. * Not called for features that aren't data-driven (i.e. * don't have a where-block). */ void afterIteration(IterationInfo iteration); /** * Called after each feature of a spec. */ void afterFeature(FeatureInfo feature); /** * Called after a spec. */ void afterSpec(SpecInfo spec); /** * Called for every error that occurs during a spec run. * May be called multiple times for the same method, for example if both * the expect-block and the cleanup-block of a feature method fail. */ void error(ErrorInfo error); // IDEA: might be able to remove remaining two methods and // call before/after instead, since skip flag should be set on // SpecInfo/FeatureInfo anyway /** * Called if a spec is skipped, for example because it is marked * with @Ignore. */ void specSkipped(SpecInfo spec); /** * Called if a feature is skipped, for example because it is marked * with @Ignore. */ void featureSkipped(FeatureInfo feature); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/IRunSupervisor.java000077500000000000000000000025041202022523300321520ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.spockframework.runtime.model.*; /** * * @author Peter Niederwieser */ public interface IRunSupervisor { void beforeSpec(SpecInfo spec); void beforeFeature(FeatureInfo feature); /* * Called before the next iteration of a parameterized feature is * run. All parameterization values have been computed successfully * at this point. Not called for non-parameterized features. */ void beforeIteration(IterationInfo iteration); void afterIteration(IterationInfo iteration); void afterFeature(FeatureInfo feature); void afterSpec(SpecInfo spec); int error(ErrorInfo error); void specSkipped(SpecInfo spec); void featureSkipped(FeatureInfo feature); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/IStackTraceFilter.java000066400000000000000000000013301202022523300324670ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; public interface IStackTraceFilter { void filter(Throwable throwable); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/InvalidSpecException.java000066400000000000000000000023611202022523300332510ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; /** * Indicates that a Spec has done something it is not supposed to do. It is up * to the Spec author to correct the problem. * * @author Peter Niederwieser */ public class InvalidSpecException extends RuntimeException { private String msg; public InvalidSpecException(String msg) { this(msg, null); } public InvalidSpecException(String msg, Throwable throwable) { super(throwable); this.msg = msg; } public InvalidSpecException withArgs(Object... args) { msg = String.format(msg, args); return this; } @Override public String getMessage() { return msg; } } JUnitDescriptionGenerator.java000066400000000000000000000052641202022523300342230ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.lang.annotation.Annotation; import org.junit.runner.Description; import org.spockframework.runtime.model.*; /** * Generates and attaches JUnit Description's to a SpecInfo's nodes. * * @author Peter Niederwieser */ public class JUnitDescriptionGenerator { private final SpecInfo spec; public JUnitDescriptionGenerator(SpecInfo spec) { this.spec = spec; } public void attach() { Description desc = Description.createSuiteDescription(spec.getReflection()); spec.setDescription(desc); for (FeatureInfo feature : spec.getAllFeatures()) describeFeature(feature); for (MethodInfo fixtureMethod : spec.getAllFixtureMethods()) describeMethod(fixtureMethod); } public Description aggregate() { Description desc = spec.getDescription(); // important for JUnit compatibility: Descriptions of specs that are reported // as "ignored" to JUnit must not have any children if (spec.isExcluded() || spec.isSkipped()) return desc; for (FeatureInfo feature : spec.getAllFeaturesInExecutionOrder()) { if (feature.isExcluded()) continue; if (feature.isReportIterations()) continue; // don't report up-front because IDEs don't handle this well desc.addChild(feature.getFeatureMethod().getDescription()); } return desc; } private Description describeFeature(FeatureInfo feature) { Description desc = describeMethod(feature.getFeatureMethod()); feature.setDescription(desc); if (feature.getDataProcessorMethod() != null) feature.getDataProcessorMethod().setDescription(desc); for (DataProviderInfo prov : feature.getDataProviders()) prov.getDataProviderMethod().setDescription(desc); return desc; } private Description describeMethod(MethodInfo method) { Annotation[] anns = method.getReflection() == null ? new Annotation[0] : method.getReflection().getAnnotations(); Description desc = Description.createTestDescription(spec.getReflection(), method.getName(), anns); method.setDescription(desc); return desc; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/JUnitFilterAdapter.java000066400000000000000000000022341202022523300326700ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.junit.runner.Description; import org.junit.runner.manipulation.Filter; import org.spockframework.runtime.model.FeatureInfo; /** * Adapts an org.junit.runner.manipulation.Filter to an IMethodInfoFilter. * * @author Peter Niederwieser */ public class JUnitFilterAdapter implements IFeatureFilter { private final Filter filter; public JUnitFilterAdapter(Filter filter) { this.filter = filter; } public boolean matches(FeatureInfo method) { return filter.shouldRun(method.getDescription()); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/JUnitSorterAdapter.java000066400000000000000000000022621202022523300327220ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.junit.runner.Description; import org.junit.runner.manipulation.Sorter; import org.spockframework.runtime.model.FeatureInfo; /** * Adapts an org.junit.runner.manipulation.Sorter to a IMethodInfoSorter. * @author Peter Niederwieser */ public class JUnitSorterAdapter implements IFeatureSortOrder { private final Sorter sorter; public JUnitSorterAdapter(Sorter sorter) { this.sorter = sorter; } public int compare(FeatureInfo m1, FeatureInfo m2) { return sorter.compare(m1.getDescription(), m2.getDescription()); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/JUnitSupervisor.java000077500000000000000000000157241202022523300323360ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.junit.ComparisonFailure; import org.junit.internal.AssumptionViolatedException; import org.junit.internal.runners.model.MultipleFailureException; import org.junit.runner.Description; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; import org.spockframework.runtime.condition.IObjectRenderer; import org.spockframework.runtime.model.*; import org.spockframework.util.InternalSpockError; import org.spockframework.util.TextUtil; import static org.spockframework.runtime.RunStatus.*; public class JUnitSupervisor implements IRunSupervisor { private final SpecInfo spec; private final RunNotifier notifier; private final IStackTraceFilter filter; private final IRunListener masterListener; private final IObjectRenderer diffedObjectRenderer; private FeatureInfo currentFeature; private IterationInfo currentIteration; private int iterationCount; private boolean errorSinceLastReset; public JUnitSupervisor(SpecInfo spec, RunNotifier notifier, IStackTraceFilter filter, IObjectRenderer diffedObjectRenderer) { this.spec = spec; this.notifier = notifier; this.filter = filter; this.masterListener = new MasterRunListener(spec); this.diffedObjectRenderer = diffedObjectRenderer; } public void beforeSpec(SpecInfo spec) { masterListener.beforeSpec(spec); } public void beforeFeature(FeatureInfo feature) { masterListener.beforeFeature(feature); currentFeature = feature; if (!feature.isReportIterations()) notifier.fireTestStarted(feature.getDescription()); if (feature.isParameterized()) { iterationCount = 0; errorSinceLastReset = false; } } public void beforeIteration(IterationInfo iteration) { masterListener.beforeIteration(iteration); currentIteration = iteration; iterationCount++; if (currentFeature.isReportIterations()) notifier.fireTestStarted(iteration.getDescription()); } public int error(ErrorInfo error) { Throwable exception = error.getException(); if (exception instanceof MultipleFailureException) return handleMultipleFailures(error); if (isFailedEqualityComparison(exception)) exception = convertToComparisonFailure(exception); filter.filter(exception); Failure failure = new Failure(getCurrentDescription(), exception); if (exception instanceof AssumptionViolatedException) { // Spock has no concept of "violated assumption", so we don't notify Spock listeners // do notify JUnit listeners unless it's a data-driven iteration that's reported as one feature if (currentIteration == null || !currentFeature.isParameterized() || currentFeature.isReportIterations()) { notifier.fireTestAssumptionFailed(failure); } } else { masterListener.error(error); notifier.fireTestFailure(failure); } errorSinceLastReset = true; return statusFor(error); } // for better JUnit compatibility, e.g when a @Rule is used private int handleMultipleFailures(ErrorInfo error) { MultipleFailureException multiFailure = (MultipleFailureException) error.getException(); int runStatus = OK; for (Throwable failure : multiFailure.getFailures()) runStatus = error(new ErrorInfo(error.getMethod(), failure)); return runStatus; } private boolean isFailedEqualityComparison(Throwable exception) { if (!(exception instanceof ConditionNotSatisfiedError)) return false; Condition condition = ((ConditionNotSatisfiedError) exception).getCondition(); ExpressionInfo expr = condition.getExpression(); return expr != null && expr.isEqualityComparison(); } // enables IDE support (diff dialog) private Throwable convertToComparisonFailure(Throwable exception) { assert isFailedEqualityComparison(exception); Condition condition = ((ConditionNotSatisfiedError) exception).getCondition(); ExpressionInfo expr = condition.getExpression(); String actual = renderValue(expr.getChildren().get(0).getValue()); String expected = renderValue(expr.getChildren().get(1).getValue()); ComparisonFailure failure = new SpockComparisonFailure(condition, expected, actual); failure.setStackTrace(exception.getStackTrace()); return failure; } private String renderValue(Object value) { try { return diffedObjectRenderer.render(value); } catch (Throwable t) { return "Failed to render value due to:\n\n" + TextUtil.printStackTrace(t); } } private int statusFor(ErrorInfo error) { switch (error.getMethod().getKind()) { case DATA_PROCESSOR: case INITIALIZER: case ITERATION_EXECUTION: case SETUP: case CLEANUP: case FEATURE: return END_ITERATION; case FEATURE_EXECUTION: case DATA_PROVIDER: return END_FEATURE; case SHARED_INITIALIZER: case SETUP_SPEC: case CLEANUP_SPEC: case SPEC_EXECUTION: return END_SPEC; default: throw new InternalSpockError("unknown method kind"); } } public void afterIteration(IterationInfo iteration) { masterListener.afterIteration(iteration); if (currentFeature.isReportIterations()) notifier.fireTestFinished(iteration.getDescription()); currentIteration = null; } public void afterFeature(FeatureInfo feature) { if (feature.isParameterized()) { if (iterationCount == 0 && !errorSinceLastReset) notifier.fireTestFailure(new Failure(feature.getDescription(), new SpockExecutionException("Data provider has no data"))); } masterListener.afterFeature(feature); if (!feature.isReportIterations()) notifier.fireTestFinished(feature.getDescription()); currentFeature = null; } public void afterSpec(SpecInfo spec) { masterListener.afterSpec(spec); } public void specSkipped(SpecInfo spec) { masterListener.specSkipped(spec); notifier.fireTestIgnored(spec.getDescription()); } public void featureSkipped(FeatureInfo feature) { masterListener.featureSkipped(feature); notifier.fireTestIgnored(feature.getDescription()); } private Description getCurrentDescription() { if (currentIteration != null && currentFeature.isReportIterations()) return currentIteration.getDescription(); if (currentFeature != null) return currentFeature.getDescription(); return spec.getDescription(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/MasterRunListener.java000066400000000000000000000042501202022523300326160ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.spockframework.runtime.model.*; public class MasterRunListener implements IRunListener { private final SpecInfo spec; public MasterRunListener(SpecInfo spec) { this.spec = spec; } public void beforeSpec(SpecInfo spec) { for (IRunListener listener : spec.getListeners()) { listener.beforeSpec(spec); } } public void beforeFeature(FeatureInfo feature) { for (IRunListener listener : spec.getListeners()) { listener.beforeFeature(feature); } } public void beforeIteration(IterationInfo iteration) { for (IRunListener listener : spec.getListeners()) { listener.beforeIteration(iteration); } } public void afterIteration(IterationInfo iteration) { for (IRunListener listener : spec.getListeners()) { listener.afterIteration(iteration); } } public void afterFeature(FeatureInfo feature) { for (IRunListener listener : spec.getListeners()) { listener.afterFeature(feature); } } public void afterSpec(SpecInfo spec) { for (IRunListener listener : spec.getListeners()) { listener.afterSpec(spec); } } public void error(ErrorInfo error) { for (IRunListener listener : spec.getListeners()) { listener.error(error); } } public void specSkipped(SpecInfo spec) { for (IRunListener listener : spec.getListeners()) { listener.specSkipped(spec); } } public void featureSkipped(FeatureInfo feature) { for (IRunListener listener : spec.getListeners()) { listener.featureSkipped(feature); } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/OptimizeRunOrderSuite.java000066400000000000000000000045211202022523300334640ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.ArrayList; import java.util.List; import org.junit.runner.*; import org.junit.runners.Suite; import org.junit.runners.model.InitializationError; import org.junit.runners.model.RunnerBuilder; @RunWith(OptimizeRunOrderSuite.class) public class OptimizeRunOrderSuite extends Suite { public static final String CLASSES_TO_RUN_KEY = OptimizeRunOrderSuite.class.getName() + ".classesToRun"; public OptimizeRunOrderSuite(Class clazz, RunnerBuilder builder) throws InitializationError { super(builder, clazz, loadAndReorderClassesToRun()); } private static Class[] loadAndReorderClassesToRun() throws InitializationError { List classNames = getClassesToRun(); SpecUtil.optimizeRunOrder(classNames); List> classes = loadClasses(classNames); return classes.toArray(new Class[classes.size()]); } private static List getClassesToRun() throws InitializationError { String property = System.getProperty(CLASSES_TO_RUN_KEY); if (property == null) throw new InitializationError(String.format("system property '%s' is not set", CLASSES_TO_RUN_KEY)); List classNames = new ArrayList(); for (String name : property.split(",")) classNames.add(name.trim()); return classNames; } private static List> loadClasses(List classNames) throws InitializationError { List> classes = new ArrayList>(); ClassLoader classLoader = OptimizeRunOrderSuite.class.getClassLoader(); try { for (String name : classNames) classes.add(classLoader.loadClass(name)); } catch (ClassNotFoundException e) { throw new InitializationError(e); } return classes; } } ParameterizedSpecRunner.java000077500000000000000000000152441202022523300337220ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.Iterator; import java.util.List; import static org.spockframework.runtime.RunStatus.*; import org.spockframework.runtime.model.*; import org.spockframework.util.GroovyRuntimeUtil; /** * Adds the ability to run parameterized features. * * @author Peter Niederwieser */ public class ParameterizedSpecRunner extends BaseSpecRunner { public ParameterizedSpecRunner(SpecInfo spec, IRunSupervisor supervisor) { super(spec, supervisor); } @Override protected void runParameterizedFeature() { if (runStatus != OK) return; Object[] dataProviders = createDataProviders(); int numIterations = estimateNumIterations(dataProviders); Iterator[] iterators = createIterators(dataProviders); runIterations(iterators, numIterations); closeDataProviders(dataProviders); } private Object[] createDataProviders() { if (runStatus != OK) return null; List dataProviderInfos = currentFeature.getDataProviders(); Object[] dataProviders = new Object[dataProviderInfos.size()]; for (int i = 0; i < dataProviderInfos.size(); i++) { MethodInfo method = dataProviderInfos.get(i).getDataProviderMethod(); Object provider = invokeRaw(sharedInstance, method, EMPTY_ARGS); if (runStatus != OK) return null; if (provider == null) { runStatus = supervisor.error( new ErrorInfo(method, new SpockExecutionException("Data provider is null"))); return null; } dataProviders[i] = provider; } return dataProviders; } private Iterator[] createIterators(Object[] dataProviders) { if (runStatus != OK) return null; Iterator[] iterators = new Iterator[dataProviders.length]; for (int i = 0; i < dataProviders.length; i++) try { Iterator iter = GroovyRuntimeUtil.asIterator(dataProviders[i]); if (iter == null) { runStatus = supervisor.error( new ErrorInfo(currentFeature.getDataProviders().get(i).getDataProviderMethod(), new SpockExecutionException("Data provider's iterator() method returned null"))); return null; } iterators[i] = iter; } catch (Throwable t) { runStatus = supervisor.error( new ErrorInfo(currentFeature.getDataProviders().get(i).getDataProviderMethod(), t)); return null; } return iterators; } // -1 => unknown private int estimateNumIterations(Object[] dataProviders) { if (runStatus != OK) return -1; if (dataProviders.length == 0) return 1; int result = Integer.MAX_VALUE; for (Object prov : dataProviders) { if (prov instanceof Iterator) // unbelievably, DGM provides a size() method for Iterators, // although it is of course destructive (i.e. it exhausts the Iterator) continue; Object rawSize = GroovyRuntimeUtil.invokeMethodQuietly(prov, "size"); if (!(rawSize instanceof Number)) continue; int size = ((Number) rawSize).intValue(); if (size < 0 || size >= result) continue; result = size; } return result == Integer.MAX_VALUE ? -1 : result; } private void runIterations(Iterator[] iterators, int estimatedNumIterations) { if (runStatus != OK) return; while (haveNext(iterators)) { initializeAndRunIteration(nextArgs(iterators), estimatedNumIterations); if (resetStatus(ITERATION) != OK) break; // no iterators => no data providers => only derived parameterizations => limit to one iteration if(iterators.length == 0) break; } } private void closeDataProviders(Object[] dataProviders) { if (action(runStatus) == ABORT) return; if (dataProviders == null) return; // there was an error creating the providers for (Object provider : dataProviders) { GroovyRuntimeUtil.invokeMethodQuietly(provider, "close"); } } private boolean haveNext(Iterator[] iterators) { if (runStatus != OK) return false; boolean haveNext = true; for (int i = 0; i < iterators.length; i++) try { boolean hasNext = iterators[i].hasNext(); if (i == 0) haveNext = hasNext; else if (haveNext != hasNext) { DataProviderInfo provider = currentFeature.getDataProviders().get(i); runStatus = supervisor.error(new ErrorInfo(provider.getDataProviderMethod(), createDifferentNumberOfDataValuesException(provider, hasNext))); return false; } } catch (Throwable t) { runStatus = supervisor.error( new ErrorInfo(currentFeature.getDataProviders().get(i).getDataProviderMethod(), t)); return false; } return haveNext; } private SpockExecutionException createDifferentNumberOfDataValuesException(DataProviderInfo provider, boolean hasNext) { String msg = String.format("Data provider for variable '%s' has %s values than previous data provider(s)", provider.getDataVariables().get(0), hasNext ? "more" : "fewer"); SpockExecutionException exception = new SpockExecutionException(msg); FeatureInfo feature = provider.getParent(); SpecInfo spec = feature.getParent(); StackTraceElement elem = new StackTraceElement(spec.getReflection().getName(), feature.getName(), spec.getFilename(), provider.getLine()); exception.setStackTrace(new StackTraceElement[] { elem }); return exception; } // advances iterators and computes args private Object[] nextArgs(Iterator[] iterators) { if (runStatus != OK) return null; Object[] next = new Object[iterators.length]; for (int i = 0; i < iterators.length; i++) try { next[i] = iterators[i].next(); } catch (Throwable t) { runStatus = supervisor.error( new ErrorInfo(currentFeature.getDataProviders().get(i).getDataProviderMethod(), t)); return null; } try { return (Object[])invokeRaw(sharedInstance, currentFeature.getDataProcessorMethod(), next); } catch (Throwable t) { runStatus = supervisor.error( new ErrorInfo(currentFeature.getDataProcessorMethod(), t)); return null; } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/RunContext.java000066400000000000000000000137211202022523300313040ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.*; import org.junit.runner.notification.RunNotifier; import org.spockframework.builder.DelegatingScript; import org.spockframework.runtime.condition.*; import org.spockframework.runtime.model.SpecInfo; import org.spockframework.util.*; import spock.config.RunnerConfiguration; public class RunContext { private static final ThreadLocal> contextStacks = new ThreadLocal>() { protected LinkedList initialValue() { return new LinkedList(); } }; private final List> extensionClasses; private final ExtensionRegistry extensionRegistry; private final List configurations = new ArrayList(); private final RunnerConfiguration runnerConfiguration = new RunnerConfiguration(); private final IObjectRenderer diffedObjectRenderer = createDiffedObjectRenderer(); private RunContext(@Nullable DelegatingScript configurationScript, List> extensionClasses) { this.extensionClasses = extensionClasses; configurations.add(runnerConfiguration); extensionRegistry = new ExtensionRegistry(extensionClasses, configurations); extensionRegistry.loadExtensions(); if (configurationScript != null) { ConfigurationBuilder builder = new ConfigurationBuilder(); builder.build(configurations, configurationScript); } } public ExtensionRunner createExtensionRunner(SpecInfo spec) { return new ExtensionRunner(spec, extensionRegistry.getExtensions()); } public ParameterizedSpecRunner createSpecRunner(SpecInfo spec, RunNotifier notifier) { return new ParameterizedSpecRunner(spec, new JUnitSupervisor(spec, notifier, createStackTraceFilter(spec), diffedObjectRenderer)); } @Nullable public T getConfiguration(Class type) { for (Object config : configurations) if (config.getClass() == type) return type.cast(config); return null; } private IStackTraceFilter createStackTraceFilter(SpecInfo spec) { return runnerConfiguration.filterStackTrace ? new StackTraceFilter(spec) : new DummyStackTraceFilter(); } private IObjectRenderer createDiffedObjectRenderer() { IObjectRendererService service = new ObjectRendererService(); service.addRenderer(Object.class, new DiffedObjectAsBeanRenderer()); DiffedObjectAsStringRenderer asStringRenderer = new DiffedObjectAsStringRenderer(); service.addRenderer(CharSequence.class, asStringRenderer); service.addRenderer(Number.class, asStringRenderer); service.addRenderer(Character.class, asStringRenderer); service.addRenderer(Boolean.class, asStringRenderer); service.addRenderer(Collection.class, new DiffedCollectionRenderer()); service.addRenderer(Set.class, new DiffedSetRenderer(true)); service.addRenderer(SortedSet.class, new DiffedSetRenderer(false)); service.addRenderer(Map.class, new DiffedMapRenderer(true)); service.addRenderer(SortedMap.class, new DiffedMapRenderer(false)); DiffedArrayRenderer arrayRenderer = new DiffedArrayRenderer(); service.addRenderer(Object[].class, arrayRenderer); service.addRenderer(byte[].class, arrayRenderer); service.addRenderer(short[].class, arrayRenderer); service.addRenderer(int[].class, arrayRenderer); service.addRenderer(long[].class, arrayRenderer); service.addRenderer(float[].class, arrayRenderer); service.addRenderer(double[].class, arrayRenderer); service.addRenderer(char[].class, arrayRenderer); service.addRenderer(boolean[].class, arrayRenderer); return service; } public static T withNewContext(@Nullable DelegatingScript configurationScript, List> extensionClasses, boolean inheritParentExtensions, IThrowableFunction command) throws U { List> allExtensionClasses = new ArrayList>(extensionClasses); if (inheritParentExtensions) allExtensionClasses.addAll(getCurrentExtensions()); RunContext context = new RunContext(configurationScript, allExtensionClasses); LinkedList contextStack = contextStacks.get(); contextStack.addFirst(context); try { return command.apply(context); } finally { contextStack.removeFirst(); } } public static RunContext get() { LinkedList contextStack = contextStacks.get(); RunContext context = contextStack.peek(); if (context == null) { context = createBottomContext(); contextStack.addFirst(context); } return context; } private static List> getCurrentExtensions() { RunContext context = contextStacks.get().peek(); if (context == null) return Collections.emptyList(); return context.extensionClasses; } // This context will stay around until the thread dies. // It would be more accurate to remove the context once the test run // has finished, but the JUnit Runner SPI doesn't provide an adequate hook. // That said, since most environments fork a new JVM for each test run, // this shouldn't be much of a problem in practice. private static RunContext createBottomContext() { DelegatingScript script = new ConfigurationScriptLoader().loadAutoDetectedScript(); List> classes = new ExtensionClassesLoader().loadClassesFromDefaultLocation(); return new RunContext(script, classes); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/RunStatus.java000077500000000000000000000036401202022523300311450ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; /** * * @author Peter Niederwieser */ public class RunStatus { // actions public static final int END = 1; public static final int ABORT = 2; // scopes public static final int ITERATION = 4; public static final int FEATURE = 8; public static final int SPEC = 16; public static final int ALL = 32; // run states public static final int OK = 0; public static final int END_ITERATION = END | ITERATION; public static final int END_FEATURE = END | FEATURE; public static final int END_SPEC = END | SPEC; public static final int END_ALL = END | ALL; public static final int ABORT_ITERATION = ABORT | ITERATION; public static final int ABORT_FEATURE = ABORT | FEATURE; public static final int ABORT_SPEC = ABORT | SPEC; public static final int ABORT_ALL = ABORT | ALL; public static int action(int status) { return status & (END | ABORT); } public static int scope(int status) { return status & (ITERATION | FEATURE | SPEC | ALL); } /** * Combines status1 and status2 by individually maximizing action and scope. * Example: combine(END_SPEC, ABORT_FEATURE) == ABORT_SPEC */ public static int combine(int status1, int status2) { return Math.max(action(status1), action(status2)) | Math.max(scope(status1), scope(status2)); } } SafeIterationNameProvider.java000066400000000000000000000027441202022523300341700ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.spockframework.runtime.model.IterationInfo; import org.spockframework.runtime.model.NameProvider; public class SafeIterationNameProvider implements NameProvider { private final NameProvider delegate; private int iterationCount; public SafeIterationNameProvider(NameProvider delegate) { this.delegate = delegate; } public String getName(IterationInfo iteration) { String safeName = iteration.getParent().isReportIterations() ? String.format("%s[%d]", iteration.getParent().getName(), iterationCount++) : iteration.getParent().getName(); if (delegate == null) return safeName; try { String name = delegate.getName(iteration); if (name != null) return name; return safeName; } catch (Exception e) { return safeName; } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/SpecInfoBuilder.java000077500000000000000000000171131202022523300322120ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.*; import org.spockframework.runtime.model.*; import org.spockframework.util.*; import spock.lang.Specification; /** * Builds a SpecInfo from a Class instance. * * @author Peter Niederwieser */ public class SpecInfoBuilder { private final Class clazz; private final SpecInfo spec = new SpecInfo(); public SpecInfoBuilder(Class clazz) { this.clazz = clazz; } public SpecInfo build() { doBuild(); int order = 0; for (SpecInfo curr : spec.getSpecsTopToBottom()) for (FeatureInfo feature : curr.getFeatures()) { feature.setDeclarationOrder(order); // lift declaration order to spec hierarchy feature.setExecutionOrder(order); order++; } return spec; } private SpecInfo doBuild() { buildSuperSpec(); buildSpec(); buildFields(); buildSharedInstanceField(); buildFeatures(); buildInitializerMethods(); buildFixtureMethods(); return spec; } private void buildSuperSpec() { Class superClass = clazz.getSuperclass(); if (superClass == Object.class || superClass == Specification.class) return; SpecInfo superSpec = new SpecInfoBuilder(superClass).doBuild(); spec.setSuperSpec(superSpec); superSpec.setSubSpec(spec); } private void buildSpec() { SpecUtil.checkIsSpec(clazz); SpecMetadata metadata = clazz.getAnnotation(SpecMetadata.class); spec.setParent(null); spec.setName(clazz.getSimpleName()); spec.setLine(metadata.line()); spec.setReflection(clazz); spec.setFilename(metadata.filename()); } private void buildFields() { for (Field field : clazz.getDeclaredFields()) { FieldMetadata metadata = field.getAnnotation(FieldMetadata.class); if (metadata == null) continue; FieldInfo fieldInfo = new FieldInfo(); fieldInfo.setParent(spec); fieldInfo.setReflection(field); fieldInfo.setName(metadata.name()); fieldInfo.setOrdinal(metadata.ordinal()); fieldInfo.setLine(metadata.line()); spec.addField(fieldInfo); } Collections.sort(spec.getFields(), new Comparator() { public int compare(FieldInfo f1, FieldInfo f2) { return f1.getOrdinal() - f2.getOrdinal(); } }); } private void buildSharedInstanceField() { Field field = getSharedInstanceField(); FieldInfo fieldInfo = new FieldInfo(); fieldInfo.setParent(spec); fieldInfo.setName(field.getName()); fieldInfo.setReflection(field); spec.setSharedInstanceField(fieldInfo); } private Field getSharedInstanceField() { try { return clazz.getField(InternalIdentifiers.SHARED_INSTANCE_NAME); } catch (NoSuchFieldException e) { throw new InternalSpockError("cannot find shared instance field"); } } private void buildFeatures() { for (Method method : clazz.getDeclaredMethods()) { FeatureMetadata metadata = method.getAnnotation(FeatureMetadata.class); if (metadata == null) continue; method.setAccessible(true); spec.addFeature(createFeature(method, metadata)); } spec.sortFeatures(new IFeatureSortOrder() { public int compare(FeatureInfo m1, FeatureInfo m2) { return m1.getDeclarationOrder() - m2.getDeclarationOrder(); } }); } private FeatureInfo createFeature(Method method, FeatureMetadata featureMetadata) { FeatureInfo feature = new FeatureInfo(); feature.setParent(spec); feature.setName(featureMetadata.name()); feature.setLine(featureMetadata.line()); feature.setDeclarationOrder(featureMetadata.ordinal()); for (String name : featureMetadata.parameterNames()) feature.addParameterName(name); MethodInfo featureMethod = new MethodInfo(); featureMethod.setParent(spec); featureMethod.setName(featureMetadata.name()); featureMethod.setLine(featureMetadata.line()); featureMethod.setFeature(feature); featureMethod.setReflection(method); featureMethod.setKind(MethodKind.FEATURE); feature.setFeatureMethod(featureMethod); String processorMethodName = InternalIdentifiers.getDataProcessorName(method.getName()); MethodInfo dataProcessorMethod = createMethod(processorMethodName, MethodKind.DATA_PROCESSOR, false); if (dataProcessorMethod != null) { feature.setDataProcessorMethod(dataProcessorMethod); int providerCount = 0; String providerMethodName = InternalIdentifiers.getDataProviderName(method.getName(), providerCount++); MethodInfo providerMethod = createMethod(providerMethodName, MethodKind.DATA_PROVIDER, false); while (providerMethod != null) { feature.addDataProvider(createDataProvider(feature, providerMethod)); providerMethodName = InternalIdentifiers.getDataProviderName(method.getName(), providerCount++); providerMethod = createMethod(providerMethodName, MethodKind.DATA_PROVIDER, false); } } for (BlockMetadata blockMetadata : featureMetadata.blocks()) { BlockInfo block = new BlockInfo(); block.setKind(blockMetadata.kind()); block.setTexts(Arrays.asList(blockMetadata.texts())); feature.addBlock(block); } return feature; } private DataProviderInfo createDataProvider(FeatureInfo feature, MethodInfo method) { DataProviderMetadata metadata = method.getReflection().getAnnotation(DataProviderMetadata.class); DataProviderInfo provider = new DataProviderInfo(); provider.setParent(feature); provider.setLine(metadata.line()); provider.setDataVariables(Arrays.asList(metadata.dataVariables())); provider.setDataProviderMethod(method); return provider; } private MethodInfo createMethod(String name, MethodKind kind, boolean allowStub) { Method reflection = findMethod(name); if (reflection == null && !allowStub) return null; MethodInfo methodInfo = new MethodInfo(); methodInfo.setParent(spec); methodInfo.setName(name); methodInfo.setReflection(reflection); methodInfo.setKind(kind); return methodInfo; } private Method findMethod(String name) { for (Method method : spec.getReflection().getDeclaredMethods()) if (method.getName().equals(name)) { method.setAccessible(true); return method; } return null; } private void buildInitializerMethods() { spec.setInitializerMethod(createMethod(InternalIdentifiers.INITIALIZER_METHOD, MethodKind.INITIALIZER, true)); spec.setSharedInitializerMethod(createMethod(InternalIdentifiers.SHARED_INITIALIZER_METHOD, MethodKind.SHARED_INITIALIZER, true)); } private void buildFixtureMethods() { spec.setSetupMethod(createMethod(Identifiers.SETUP_METHOD, MethodKind.SETUP, true)); spec.setCleanupMethod(createMethod(Identifiers.CLEANUP_METHOD, MethodKind.CLEANUP, true)); spec.setSetupSpecMethod(createMethod(Identifiers.SETUP_SPEC_METHOD, MethodKind.SETUP_SPEC, true)); spec.setCleanupSpecMethod(createMethod(Identifiers.CLEANUP_SPEC_METHOD, MethodKind.CLEANUP_SPEC, true)); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/SpecRunHistory.java000066400000000000000000000117771202022523300321450ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.io.*; import java.math.BigDecimal; import java.math.MathContext; import java.util.*; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.SpecInfo; import org.spockframework.util.IoUtil; import org.spockframework.util.TextUtil; public class SpecRunHistory implements Comparable { private static final int MAX_CONFIDENCE = 5; private final String specName; private Data data = new Data(); public SpecRunHistory(String specName) { this.specName = specName; } public String getSpecName() { return specName; } public void loadFromDisk() throws IOException { ObjectInputStream in = new ObjectInputStream(new FileInputStream(getDataFile())); try { data = (Data) in.readObject(); } catch (ClassNotFoundException e) { // in JDK 1.5, there is no IOException constructor that takes a cause IOException io = new IOException("deserialization error"); io.initCause(e); throw io; } finally { IoUtil.closeQuietly(in); } } public void saveToDisk() throws IOException { File file = getDataFile(); IoUtil.createDirectory(file.getParentFile()); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file)); try { out.writeObject(data); } finally { IoUtil.closeQuietly(out); } } public void sortFeatures(SpecInfo spec) { spec.sortFeatures(new IFeatureSortOrder() { public int compare(FeatureInfo f1, FeatureInfo f2) { Integer confidence1 = data.featureConfidences.get(f1.getName()); if (confidence1 == null) return -1; Integer confidence2 = data.featureConfidences.get(f2.getName()); if (confidence2 == null) return 1; if (!confidence1.equals(confidence2)) return confidence1 - confidence2; long duration1 = data.featureDurations.get(f1.getName()); // never null long duration2 = data.featureDurations.get(f2.getName()); // never null return duration1 < duration2 ? -1 : 1; } }); } public int compareTo(SpecRunHistory other) { int confidenceDiff = data.specConfidence.compareTo(other.data.specConfidence); if (confidenceDiff != 0) return confidenceDiff; return data.specDuration < other.data.specDuration ? -1 : 1; } public void collectFeatureData(FeatureInfo feature, long duration, boolean failed) { data.featureDurations.put(feature.getName(), duration); Integer oldConfidence = data.featureConfidences.get(feature.getName()); if (oldConfidence == null) oldConfidence = 0; int newConfidence = failed ? 0 : Math.min(MAX_CONFIDENCE, oldConfidence + 1); data.featureConfidences.put(feature.getName(), newConfidence); } public void collectSpecData(SpecInfo spec, long duration) { data.specDuration = duration; removeObsoleteFeaturesFromData(spec); computeSpecConfidence(); } private void removeObsoleteFeaturesFromData(SpecInfo spec) { List features = spec.getAllFeatures(); Set featureNames = extractNames(features); data.featureConfidences.keySet().retainAll(featureNames); data.featureDurations.keySet().retainAll(featureNames); } private void computeSpecConfidence() { int totalConfidence = 0; for (int confidence : data.featureConfidences.values()) totalConfidence += confidence; int numFeatures = data.featureConfidences.size(); data.specConfidence = numFeatures == 0 ? new BigDecimal(0) : new BigDecimal(totalConfidence).divide(new BigDecimal(numFeatures), MathContext.DECIMAL32); } private Set extractNames(List features) { Set featureNames = new HashSet(features.size()); for (FeatureInfo feature : features) featureNames.add(feature.getName()); return featureNames; } private File getDataFile() { return new File(TextUtil.join(File.separator, System.getProperty("user.home"), ".spock", "RunHistory", specName)); } private static class Data implements Serializable { // BigDecimal ensures that specs with equal confidence will be ordered // according to their duration, instead of falling prey to some rounding error BigDecimal specConfidence = new BigDecimal(0); long specDuration = 0; Map featureConfidences = new HashMap(); Map featureDurations = new HashMap(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/SpecUtil.java000066400000000000000000000102131202022523300307140ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; import org.spockframework.runtime.model.FeatureMetadata; import org.spockframework.runtime.model.SpecMetadata; import spock.lang.Specification; /** * Utility methods related to specifications. Particularly useful when * integrating Spock with other environments (e.g. Grails). * * @author Peter Niederwieser */ public final class SpecUtil { private SpecUtil() {} /** * Tells if the given class is a Spock specification. Might return false * even though the class implements spock.lang.Specification. This can * happen if the class wasn't compiled properly (i.e. Spock's AST transform wasn't run). */ public static boolean isSpec(Class clazz) { return clazz.isAnnotationPresent(SpecMetadata.class); } /** * Checks if the given class is a Spock specification (according to isSpec()), * and throws an InvalidSpecException with a detailed explanation if it is not. */ public static void checkIsSpec(Class clazz) { if (isSpec(clazz)) return; if (Specification.class.isAssignableFrom(clazz)) throw new InvalidSpecException( "Specification '%s' was not compiled properly (Spock AST transform was not run); try to do a clean build" ).withArgs(clazz.getName()); throw new InvalidSpecException( "Class '%s' is not a Spock specification (does not extend spock.lang.Specification or a subclass thereof)" ).withArgs(clazz.getName()); } public static boolean isRunnableSpec(Class clazz) { return isSpec(clazz) && !Modifier.isAbstract(clazz.getModifiers()); } public static void checkIsRunnableSpec(Class clazz) { checkIsSpec(clazz); if (Modifier.isAbstract(clazz.getModifiers())) throw new InvalidSpecException("Specification '%s' is not runnable because it is declared abstract") .withArgs(clazz.getName()); } /** * Returns the number of features contained in the given specification. * Because Spock allows for the dynamic creation of new features at * specification run time, this number is only an estimate. */ public static int getFeatureCount(Class spec) { checkIsSpec(spec); int count = 0; do { for (Method method : spec.getDeclaredMethods()) if (method.isAnnotationPresent(FeatureMetadata.class)) count++; spec = spec.getSuperclass(); } while (spec != null && isSpec(spec)); return count; } public static List optimizeRunOrder(List specNames) { List histories = loadHistories(specNames); Collections.sort(histories); return extractNames(histories); } public static T getConfiguration(Class type) { return RunContext.get().getConfiguration(type); } private static List loadHistories(List specNames) { List histories = new ArrayList(specNames.size()); for (String name : specNames) { SpecRunHistory history = new SpecRunHistory(name); try { history.loadFromDisk(); } catch (IOException ignored) {} // history stays empty, so spec will be run early on histories.add(history); } return histories; } private static List extractNames(List histories) { List specNames = new ArrayList(histories.size()); for (SpecRunHistory history : histories) specNames.add(history.getSpecName()); return specNames; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/SpockAssertionError.java000077500000000000000000000021341202022523300331530ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; /** * * @author Peter Niederwieser */ public class SpockAssertionError extends AssertionError { public SpockAssertionError() {} public SpockAssertionError(String msg) { super(msg); } public SpockAssertionError(Throwable cause) { initCause(cause); } // We don't want to have the class name printed out for assertion errors, so // we just delegate to getMessage(). @Override public String toString() { return getMessage(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/SpockComparisonFailure.java000066400000000000000000000026571202022523300336230ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.junit.ComparisonFailure; /** * Thrown when a condition of the form 'expr1 == expr2' fails. * Inherits from JUnit's ComparisonFailure (rather than * ConditionNotSatisfiedError) to enable IDE support for * diff'ing actual and expected values. * * @author Peter Niederwieser */ public class SpockComparisonFailure extends ComparisonFailure { private final Condition condition; public SpockComparisonFailure(Condition condition, String expected, String actual) { super(null, expected, actual); this.condition = condition; } public Condition getCondition() { return condition; } @Override public String getMessage() { return "Condition not satisfied:\n\n" + condition.getRendering(); } @Override public String toString() { return getMessage(); } } SpockExecutionException.java000066400000000000000000000023051202022523300337320ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; /** * Indicates that a problem occurred during Spec execution. * * @author Peter Niederwieser */ public class SpockExecutionException extends RuntimeException { private volatile String msg; public SpockExecutionException(String msg) { this(msg, null); } public SpockExecutionException(String msg, Throwable throwable) { super(throwable); this.msg = msg; } public SpockExecutionException withArgs(Object... args) { msg = String.format(msg, args); return this; } @Override public String getMessage() { return msg; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/SpockRuntime.java000077500000000000000000000125341202022523300316220ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.*; import org.spockframework.runtime.model.ExpressionInfo; import org.spockframework.runtime.model.TextPosition; import org.spockframework.util.*; /** * @author Peter Niederwieser */ public abstract class SpockRuntime { public static final String VERIFY_CONDITION = "verifyCondition"; // condition can be null too, but not in the sense of "not available" public static void verifyCondition(@Nullable ValueRecorder recorder, @Nullable String text, int line, int column, @Nullable Object message, @Nullable Object condition) { if (!GroovyRuntimeUtil.isTruthy(condition)) throw new ConditionNotSatisfiedError( new Condition(recorder, text, TextPosition.create(line, column), messageToString(message))); } public static final String VERIFY_METHOD_CONDITION = "verifyMethodCondition"; // method calls with spread-dot operator are not rewritten, hence this method doesn't have to care about spread-dot public static void verifyMethodCondition(@Nullable ValueRecorder recorder, @Nullable String text, int line, int column, @Nullable Object message, Object target, String method, Object[] args, boolean safe, boolean explicit) { MatcherCondition matcherCondition = MatcherCondition.parse(target, method, args, safe); if (matcherCondition != null) { matcherCondition.verify(recorder, text, line, column, messageToString(message)); return; } Object result = safe ? GroovyRuntimeUtil.invokeMethodNullSafe(target, method, args) : GroovyRuntimeUtil.invokeMethod(target, method, args); if (recorder != null) { recorder.replaceLastValue(result); } if (!explicit && result == null && GroovyRuntimeUtil.isVoidMethod(target, method, args)) return; if (!GroovyRuntimeUtil.isTruthy(result)) throw new ConditionNotSatisfiedError( new Condition(recorder, text, TextPosition.create(line, column), messageToString(message))); } public static final String DESPREAD_LIST = "despreadList"; public static Object[] despreadList(Object[] args, Object[] spreads, int[] positions) { return GroovyRuntimeUtil.despreadList(args, spreads, positions); } private static String messageToString(Object message) { if (message == null) return null; // treat as "not available" return GroovyRuntimeUtil.toString(message); } /** * A condition of the form "foo equalTo(bar)" or "that(foo, equalTo(bar)", * where 'equalTo' returns a Hamcrest matcher. */ private static class MatcherCondition { final Object actual; final Object matcher; // true if the "foo equalTo(bar)" syntax is used, // false if the "that(foo, equalTo(bar)" syntax is used final boolean shortSyntax; MatcherCondition(Object actual, Object matcher, boolean shortSyntax) { this.actual = actual; this.matcher = matcher; this.shortSyntax = shortSyntax; } void verify(@Nullable ValueRecorder recorder, @Nullable String text, int line, int column, @Nullable String message) { if (HamcrestFacade.matches(matcher, actual)) return; if (recorder != null) { recorder.replaceLastValue(shortSyntax ? actual : false); replaceMatcherValues(recorder); } String description = HamcrestFacade.getFailureDescription(matcher, actual, message); Condition condition = new Condition(recorder, text, TextPosition.create(line, column), description); throw new ConditionNotSatisfiedError(condition); } void replaceMatcherValues(ValueRecorder recorder) { boolean firstOccurrence = true; List values = recorder.getRecordedValues(); ListIterator iter = values.listIterator(values.size()); while (iter.hasPrevious()) { Object value = iter.previous(); if (!HamcrestFacade.isMatcher(value)) continue; if (firstOccurrence) { // indicate mismatch in condition output iter.set(shortSyntax ? false : ExpressionInfo.VALUE_NOT_AVAILABLE); firstOccurrence = false; } else { // don't show in condition output iter.set(ExpressionInfo.VALUE_NOT_AVAILABLE); } } } @Nullable static MatcherCondition parse(Object target, String method, Object[] args, boolean safe) { if (safe) return null; if (method.equals("call")) { if (args.length != 1 || !HamcrestFacade.isMatcher(args[0])) return null; return new MatcherCondition(target, args[0], true); } if (method.equals("that")) { if (target != spock.util.matcher.HamcrestSupport.class) return null; if (args.length != 2 || !HamcrestFacade.isMatcher(args[1])) return null; return new MatcherCondition(args[0], args[1], false); } return null; } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/SpockTimeoutError.java000066400000000000000000000022351202022523300326310ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.concurrent.TimeUnit; public class SpockTimeoutError extends SpockAssertionError { private final int timeoutValue; private final TimeUnit timeoutUnit; public SpockTimeoutError(int timeoutValue, TimeUnit timeoutUnit, String formatString, Object... args) { super(String.format(formatString, args)); this.timeoutValue = timeoutValue; this.timeoutUnit = timeoutUnit; } public int getTimeoutValue() { return timeoutValue; } public TimeUnit getTimeoutUnit() { return timeoutUnit; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/Sputnik.java000077500000000000000000000064521202022523300306360ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import org.junit.runner.Description; import org.junit.runner.Runner; import org.junit.runner.manipulation.*; import org.junit.runner.notification.RunNotifier; import org.junit.runners.model.InitializationError; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.SpecInfo; import org.spockframework.util.IncompatibleGroovyVersionException; import org.spockframework.util.VersionChecker; /** * A JUnit runner for Spock specifications. There is no need to put * @RunWith(Sputnik) on a specification because the RunWith * annotation is inherited from class spock.lang.Specification. * In case you wondered, Sputnik is a combination of the words "Spock" and "JUnit". * * @author Peter Niederwieser */ // TODO: check if StoppedByUserException thrown in Notifier.fireTestStarted() is handled correctly on our side public class Sputnik extends Runner implements Filterable, Sortable { private final Class clazz; private SpecInfo spec; private boolean extensionsRun = false; private boolean descriptionAggregated = false; public Sputnik(Class clazz) throws InitializationError { try { VersionChecker.checkGroovyVersion("JUnit runner"); } catch (IncompatibleGroovyVersionException e) { throw new InitializationError(e); } this.clazz = clazz; } public Description getDescription() { runExtensionsIfNecessary(); aggregateDescriptionIfNecessary(); return getSpec().getDescription(); } public void run(RunNotifier notifier) { runExtensionsIfNecessary(); aggregateDescriptionIfNecessary(); RunContext.get().createSpecRunner(getSpec(), notifier).run(); } public void filter(Filter filter) throws NoTestsRemainException { getSpec().filterFeatures(new JUnitFilterAdapter(filter)); if (allFeaturesExcluded()) throw new NoTestsRemainException(); } public void sort(Sorter sorter) { getSpec().sortFeatures(new JUnitSorterAdapter(sorter)); } private SpecInfo getSpec() { if (spec == null) { spec = new SpecInfoBuilder(clazz).build(); new JUnitDescriptionGenerator(spec).attach(); } return spec; } private void runExtensionsIfNecessary() { if (extensionsRun) return; RunContext.get().createExtensionRunner(getSpec()).run(); extensionsRun = true; } private void aggregateDescriptionIfNecessary() { if (descriptionAggregated) return; new JUnitDescriptionGenerator(getSpec()).aggregate(); descriptionAggregated = true; } private boolean allFeaturesExcluded() { for (FeatureInfo feature: getSpec().getAllFeatures()) if (!feature.isExcluded()) return false; return true; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/StackTraceFilter.java000066400000000000000000000110021202022523300323530ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.spockframework.util.InternalIdentifiers; /** * Filters an exception's stack trace. Removes internal Groovy and Spock methods, and * restores the original names of feature methods (as specified in source code). * Stack trace elements below a feature/fixture method invocation are truncated. * * @author Peter Niederwieser */ // IDEA: do not filter top-most stack element, unless it's a call to the Spock runtime // IDEA: find entry points into user code by looking for BaseSpecRunner.invoke()/invokeRaw() public class StackTraceFilter implements IStackTraceFilter { private static final Pattern FILTERED_CLASSES = Pattern.compile( "org.codehaus.groovy.runtime\\..*" + "|org.codehaus.groovy.reflection\\..*" + "|org.codehaus.groovy\\..*MetaClass.*" + "|groovy\\..*MetaClass.*" + "|groovy.lang.MetaMethod" + "|java.lang.reflect\\..*" + "|sun.reflect\\..*" + "|org.spockframework.runtime\\.[^\\.]+" // exclude subpackages ); private static final Pattern CLOSURE_CLASS = Pattern.compile("(.+)\\$_(.+)_closure(\\d+)"); private final IMethodNameMapper mapper; public StackTraceFilter(IMethodNameMapper mapper) { this.mapper = mapper; } public void filter(Throwable throwable) { List filteredTrace = new ArrayList(); for (StackTraceElement elem : throwable.getStackTrace()) { if (isInitializerOrFixtureMethod(elem)) { filteredTrace.add(elem); break; } if (checkForAndAddPrettyPrintedFeatureMethod(elem, filteredTrace)) break; if (isFilteredClass(elem)) continue; if (checkForAndAddPrettyPrintedClosureInvocation(elem, filteredTrace)) continue; if (isGeneratedMethod(elem)) continue; filteredTrace.add(elem); } throwable.setStackTrace(filteredTrace.toArray(new StackTraceElement[filteredTrace.size()])); if (throwable.getCause() != null) filter(throwable.getCause()); } private boolean isInitializerOrFixtureMethod(StackTraceElement elem) { return mapper.isInitializerOrFixtureMethod(elem.getClassName(), elem.getMethodName()); } private static boolean isFilteredClass(StackTraceElement elem) { return FILTERED_CLASSES.matcher(elem.getClassName()).matches(); } private boolean checkForAndAddPrettyPrintedFeatureMethod(StackTraceElement elem, List trace) { if (!InternalIdentifiers.isFeatureMethodName(elem.getMethodName())) return false; trace.add(prettyPrintFeatureMethod(elem)); return true; } private StackTraceElement prettyPrintFeatureMethod(StackTraceElement elem) { return new StackTraceElement(elem.getClassName(), mapper.toFeatureName(elem.getMethodName()), elem.getFileName(), elem.getLineNumber()); } private boolean checkForAndAddPrettyPrintedClosureInvocation(StackTraceElement elem, List trace) { if (!elem.getMethodName().equals("doCall")) return false; Matcher matcher = CLOSURE_CLASS.matcher(elem.getClassName()); if (!matcher.matches()) return false; trace.add(prettyPrintClosureInvocation(elem, matcher)); return true; } private StackTraceElement prettyPrintClosureInvocation(StackTraceElement elem, Matcher matcher) { String classContaingClosureDef = matcher.group(1); String methodContainingClosureDef = matcher.group(2); String consecutiveNumberOfClosureDef = matcher.group(3); String prettyClassName = classContaingClosureDef; String prettyMethodName = mapper.toFeatureName(methodContainingClosureDef) + "_closure" + consecutiveNumberOfClosureDef; return new StackTraceElement(prettyClassName, prettyMethodName, elem.getFileName(), elem.getLineNumber()); } private boolean isGeneratedMethod(StackTraceElement elem) { return elem.getLineNumber() < 0; } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/ValueRecorder.java000066400000000000000000000043361202022523300317370ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; import java.util.*; import org.spockframework.runtime.model.ExpressionInfo; import org.spockframework.util.CollectionUtil; /** * Records the values in a condition. * * @author Peter Niederwieser */ public class ValueRecorder implements Iterable { private final ArrayList values = new ArrayList(); public static final String RESET = "reset"; public ValueRecorder reset() { values.clear(); return this; } public static final String RECORD = "record"; /** * Records and returns the specified value. Hence an expression can be replaced * with record(expression) without impacting evaluation of the expression. */ public Object record(int index, Object value) { realizeNas(index, null); values.add(value); return value; } public static final String REALIZE_NAS = "realizeNas"; /** * Materializes N/A values without recording a new value. */ public Object realizeNas(int index, Object value) { for (int i = values.size(); i < index; i++) values.add(ExpressionInfo.VALUE_NOT_AVAILABLE); return value; } /** * Returns an iterator over the recorded values. * @return an iterator over the recorded values */ public Iterator iterator() { return values.iterator(); } /** * Useful for manipulating the last recorded value. */ public void replaceLastValue(Object newValue) { CollectionUtil.setLastElement(values, newValue); } /** * Useful for manipulating values after they have been recorded. */ public List getRecordedValues() { return values; } } WrongExceptionThrownError.java000066400000000000000000000024721202022523300343040ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; public class WrongExceptionThrownError extends SpockAssertionError { private final Class expected; private final Throwable actual; public WrongExceptionThrownError(Class expected, Throwable actual) { super(actual); this.expected = expected; this.actual = actual; } public Class getExpected() { return expected; } public Throwable getActual() { return actual; } @Override public String getMessage() { return String.format("Expected exception %s, but %s", expected.getName(), actual == null ? "no exception was thrown" : ("got " + actual.getClass().getName())); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/000077500000000000000000000000001202022523300303125ustar00rootroot00000000000000DiffedArrayRenderer.java000066400000000000000000000017351202022523300347530ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import java.lang.reflect.Array; public class DiffedArrayRenderer implements IObjectRenderer { public String render(Object array) { LineBuilder builder = new LineBuilder(); for (int i = 0; i < Array.getLength(array); i++) { builder.addLine(Array.get(array, i)); } return builder.toString(); } } DiffedCollectionRenderer.java000066400000000000000000000017201202022523300357620ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import java.util.Collection; public class DiffedCollectionRenderer implements IObjectRenderer { public String render(Collection collection) { LineBuilder builder = new LineBuilder(); for (Object element : collection) { builder.addLine(element); } return builder.toString(); } } DiffedMapRenderer.java000066400000000000000000000024551202022523300344120ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import java.util.Map; import java.util.Set; import org.spockframework.util.GroovyRuntimeUtil; public class DiffedMapRenderer implements IObjectRenderer { private final boolean sort; public DiffedMapRenderer(boolean sort) { this.sort = sort; } @SuppressWarnings("unchecked") public String render(Map map) { LineBuilder builder = new LineBuilder(); for (Map.Entry entry : (Set) map.entrySet()) { String line = GroovyRuntimeUtil.toString(entry.getKey()) + ": " + GroovyRuntimeUtil.toString(entry.getValue()); builder.addLine(line); } if (sort) builder.sort(); return builder.toString(); } } DiffedObjectAsBeanRenderer.java000066400000000000000000000024641202022523300361550ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import java.lang.reflect.Field; import org.spockframework.util.GroovyRuntimeUtil; public class DiffedObjectAsBeanRenderer implements IObjectRenderer { public String render(Object object) { LineBuilder builder = new LineBuilder(); for (Class clazz = object.getClass(); clazz != null; clazz = clazz.getSuperclass()) { for (Field field : clazz.getDeclaredFields()) { if (field.isSynthetic()) continue; String value = GroovyRuntimeUtil.toString(GroovyRuntimeUtil.getAttribute(object, field.getName())); builder.addLine(field.getName() + ": " + value); } } builder.sort(); return builder.toString(); } } DiffedObjectAsStringRenderer.java000066400000000000000000000015661202022523300365600ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import org.spockframework.util.GroovyRuntimeUtil; public class DiffedObjectAsStringRenderer implements IObjectRenderer { public String render(Object object) { return GroovyRuntimeUtil.toString(object) + "\n"; } }DiffedSetRenderer.java000066400000000000000000000020511202022523300344200ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import java.util.Set; public class DiffedSetRenderer implements IObjectRenderer { private final boolean sort; public DiffedSetRenderer(boolean sort) { this.sort = sort; } public String render(Set set) { LineBuilder builder = new LineBuilder(); for (Object element : set) { builder.addLine(element); } if (sort) builder.sort(); return builder.toString(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/EditDistance.java000066400000000000000000000067741202022523300335330ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import java.util.LinkedList; import java.util.List; import static org.spockframework.runtime.condition.EditOperation.Kind.*; /** * Calculates Levenshtein distance and corresponding edit path between two character sequences. * Inspired from: http://etorreborre.blogspot.com/2008/06/edit-distance-in-scala_245.html * * Ideas for improvements: * - Favor fewer EditOperationS when calculating distance and/or path * - Use algorithm with lower time and/or space complexity * * @author Peter Niederwieser */ public class EditDistance { private final CharSequence seq1; private final CharSequence seq2; private final int[][] matrix; public EditDistance(CharSequence seq1, CharSequence seq2) { this.seq1 = seq1; this.seq2 = seq2; matrix = new int[seq1.length() + 1][]; calculateMatrix(); } private void calculateMatrix() { for (int i = 0; i < seq1.length() + 1; i++) { matrix[i] = new int[seq2.length() + 1]; for (int j = 0; j < seq2.length() + 1; j++) { if (i == 0) matrix[i][j] = j; // j insertions else if (j == 0) matrix[i][j] = i; // i deletions else matrix[i][j] = min( matrix[i][j - 1] + 1, // insertion matrix[i - 1][j] + 1, // deletion matrix[i - 1][j - 1] + (seq1.charAt(i - 1) == seq2.charAt(j - 1) ? 0 : 1)); // substitution } } } public int[][] getMatrix() { return matrix; } public int getDistance() { return matrix[seq1.length()][seq2.length()]; } public int getSimilarityInPercent() { int maxDistance = Math.max(seq1.length(), seq2.length()); return (maxDistance - getDistance()) * 100 / maxDistance; } public List calculatePath() { LinkedList ops = new LinkedList(); int i = seq1.length(); int j = seq2.length(); int dist = matrix[i][j]; while (i > 0 && j > 0 && dist > 0) { int ins = matrix[i][j - 1]; int del = matrix[i - 1][j]; int sub = matrix[i - 1][j - 1]; if (dist == ins + 1) { addOrUpdate(ops, INSERT, 1); j--; } else if (dist == del + 1) { addOrUpdate(ops, DELETE, 1); i--; } else { if (dist == sub) addOrUpdate(ops, SKIP, 1); else addOrUpdate(ops, SUBSTITUTE, 1); i--; j--; } dist = matrix[i][j]; } if (i == 0) addOrUpdate(ops, INSERT, j); else if (j == 0) addOrUpdate(ops, DELETE, i); else addOrUpdate(ops, SKIP, i); return ops; } private void addOrUpdate(LinkedList ops, EditOperation.Kind kind, int length) { if (length == 0) return; if (!ops.isEmpty() && ops.getFirst().getKind() == kind) ops.getFirst().incLength(length); else ops.addFirst(new EditOperation(kind, length)); } private static int min(int a, int b, int c) { return Math.min(a, Math.min(b, c)); } } EditOperation.java000066400000000000000000000027341202022523300336520ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; public class EditOperation { public enum Kind { INSERT, DELETE, SUBSTITUTE, SKIP } private final Kind kind; private int length; EditOperation(Kind kind, int length) { this.length = length; this.kind = kind; } public Kind getKind() { return kind; } public int getLength() { return length; } public void incLength(int amount) { length += amount; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; EditOperation that = (EditOperation) o; if (length != that.length) return false; if (kind != that.kind) return false; return true; } @Override public int hashCode() { int result = kind != null ? kind.hashCode() : 0; result = 31 * result + length; return result; } } EditPathRenderer.java000066400000000000000000000047371202022523300343020ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import java.util.List; import org.spockframework.util.TextUtil; import static org.spockframework.runtime.condition.EditOperation.Kind.SKIP; public class EditPathRenderer { public String render(CharSequence seq1, CharSequence seq2, List ops) { int index1 = 0; int index2 = 0; StringBuilder line1 = new StringBuilder(); StringBuilder line2 = new StringBuilder(); EditOperation.Kind prevKind = SKIP; for (EditOperation op : ops) { if (prevKind == SKIP ^ op.getKind() == SKIP) { String delimiter = prevKind == SKIP ? "(" : ")"; line1.append(delimiter); line2.append(delimiter); } switch (op.getKind()) { case DELETE: for (int i = 0; i < op.getLength(); i++) { String part = TextUtil.escape(seq1.charAt(index1++)); line1.append(part); line2.append(part.length() == 1 ? "-" : "-~"); } break; case INSERT: for (int i = 0; i < op.getLength(); i++) { String part = TextUtil.escape(seq2.charAt(index2++)); line1.append(part.length() == 1 ? "-" : "-~"); line2.append(part); } break; case SKIP: case SUBSTITUTE: for (int i = 0; i < op.getLength(); i++) { String part1 = TextUtil.escape(seq1.charAt(index1++)); String part2 = TextUtil.escape(seq2.charAt(index2++)); line1.append(part1); line2.append(part2); if (part1.length() < part2.length()) line1.append('~'); else if (part2.length() < part1.length()) line2.append('~'); } break; } prevKind = op.getKind(); } if (prevKind != SKIP) { line1.append(")"); line2.append(")"); } return line1.toString() + "\n" + line2.toString(); } } IObjectRenderer.java000066400000000000000000000013241202022523300341040ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; public interface IObjectRenderer { String render(T object); } IObjectRendererService.java000066400000000000000000000014511202022523300354260ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; public interface IObjectRendererService extends IObjectRenderer { void addRenderer(Class type, IObjectRenderer renderer); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/LineBuilder.java000066400000000000000000000022521202022523300333540ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import java.util.*; import org.spockframework.util.GroovyRuntimeUtil; public class LineBuilder { private final List lines = new ArrayList(); public void addLine(Object object) { lines.add(GroovyRuntimeUtil.toString(object)); } public void sort() { Collections.sort(lines); } @Override public String toString() { StringBuilder builder = new StringBuilder(); for (String line : lines) { builder.append(line); builder.append("\n"); } return builder.toString(); } } ObjectRendererService.java000066400000000000000000000043471202022523300353240ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import java.util.*; import org.spockframework.util.InternalSpockError; public class ObjectRendererService implements IObjectRendererService { private final HashMap, IObjectRenderer> renderers = new HashMap, IObjectRenderer>(); public void addRenderer(Class type, IObjectRenderer renderer) { renderers.put(type, renderer); } @SuppressWarnings("unchecked") public String render(Object object) { if (object == null) return "null\n"; // explicit parameterization required although IDEA thinks it's redundant Set> types = Collections.>singleton(object.getClass()); while (!types.isEmpty()) { for (Class type : types) { IObjectRenderer renderer = renderers.get(type); if (renderer != null) return renderer.render(object); } types = getParents(types); } // only fall back to renderer for type Object once all other options have been exhausted IObjectRenderer renderer = renderers.get(Object.class); if (renderer != null) return renderer.render(object); throw new InternalSpockError("no renderer for type Object found"); } private Set> getParents(Set> types) { Set> parents = new HashSet>(); for (Class type : types) { Class superclass = type.getSuperclass(); if (superclass != null && superclass != Object.class) { parents.add(superclass); } // cast required to compile with JDK 5 parents.addAll(Arrays.asList((Class[]) type.getInterfaces())); } return parents; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/000077500000000000000000000000001202022523300303405ustar00rootroot00000000000000AbstractAnnotationDrivenExtension.java000077500000000000000000000035371202022523300400020ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; import java.lang.annotation.Annotation; import org.spockframework.runtime.InvalidSpecException; import org.spockframework.runtime.model.*; /** * * @author Peter Niederwieser */ public abstract class AbstractAnnotationDrivenExtension implements IAnnotationDrivenExtension { public void visitSpecAnnotation(T annotation, SpecInfo spec) { throw new InvalidSpecException("@%s may not be applied to Specs") .withArgs(annotation.annotationType().getSimpleName()); } public void visitFeatureAnnotation(T annotation, FeatureInfo feature) { throw new InvalidSpecException("@%s may not be applied to feature methods") .withArgs(annotation.annotationType().getSimpleName()); } public void visitFixtureAnnotation(T annotation, MethodInfo fixtureMethod) { throw new InvalidSpecException("@%s may not be applied to fixture methods") .withArgs(annotation.annotationType().getSimpleName()); } public void visitFieldAnnotation(T annotation, FieldInfo field) { throw new InvalidSpecException("@%s may not be applied to fields") .withArgs(annotation.annotationType().getSimpleName()); } public void visitSpec(SpecInfo spec) {} // do nothing } AbstractMethodInterceptor.java000066400000000000000000000060531202022523300362530ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; import org.spockframework.util.UnreachableCodeError; public abstract class AbstractMethodInterceptor implements IMethodInterceptor { public final void intercept(IMethodInvocation invocation) throws Throwable { switch(invocation.getMethod().getKind()) { case INITIALIZER: interceptInitializerMethod(invocation); break; case SHARED_INITIALIZER: interceptSharedInitializerMethod(invocation); break; case SETUP: interceptSetupMethod(invocation); break; case CLEANUP: interceptCleanupMethod(invocation); break; case SETUP_SPEC: interceptSetupSpecMethod(invocation); break; case CLEANUP_SPEC: interceptCleanupSpecMethod(invocation); break; case FEATURE: interceptFeatureMethod(invocation); break; case DATA_PROVIDER: interceptDataProviderMethod(invocation); break; case DATA_PROCESSOR: interceptDataProcessorMethod(invocation); break; case ITERATION_EXECUTION: interceptIterationExecution(invocation); break; case SPEC_EXECUTION: interceptSpecExecution(invocation); break; case FEATURE_EXECUTION: interceptFeatureExecution(invocation); break; default: throw new UnreachableCodeError(); } } public void interceptInitializerMethod(IMethodInvocation invocation) throws Throwable {} public void interceptSharedInitializerMethod(IMethodInvocation invocation) throws Throwable {} public void interceptSetupMethod(IMethodInvocation invocation) throws Throwable {} public void interceptCleanupMethod(IMethodInvocation invocation) throws Throwable {} public void interceptSetupSpecMethod(IMethodInvocation invocation) throws Throwable {} public void interceptCleanupSpecMethod(IMethodInvocation invocation) throws Throwable {} public void interceptFeatureMethod(IMethodInvocation invocation) throws Throwable {} public void interceptDataProviderMethod(IMethodInvocation invocation) throws Throwable {} public void interceptDataProcessorMethod(IMethodInvocation invocation) throws Throwable {} public void interceptIterationExecution(IMethodInvocation invocation) throws Throwable {} public void interceptSpecExecution(IMethodInvocation invocation) throws Throwable {} public void interceptFeatureExecution(IMethodInvocation invocation) throws Throwable {} } ExtensionAnnotation.java000077500000000000000000000016071202022523300351420ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; import java.lang.annotation.*; /** * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface ExtensionAnnotation { Class value(); } ExtensionException.java000066400000000000000000000021511202022523300347560ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; public class ExtensionException extends RuntimeException { private String message; public ExtensionException(String message) { this(message, null); } public ExtensionException(String message, Throwable cause) { super(cause); this.message = message; } public ExtensionException withArgs(Object... args) { message = String.format(message, args); return this; } @Override public String getMessage() { return message; } } ExtensionUtil.java000066400000000000000000000024561202022523300337450ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; import java.util.ArrayList; import java.util.List; import org.junit.internal.runners.model.MultipleFailureException; public class ExtensionUtil { public static void throwAll(List exceptions) throws Throwable { if (exceptions.isEmpty()) return; if (exceptions.size() == 1) throw exceptions.get(0); List unrolled = new ArrayList(); for (Throwable exception : exceptions) { if (exception instanceof MultipleFailureException) unrolled.addAll(((MultipleFailureException) exception).getFailures()); else unrolled.add(exception); } throw new MultipleFailureException(unrolled); } } IAnnotationDrivenExtension.java000077500000000000000000000021721202022523300364210ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; import java.lang.annotation.Annotation; import org.spockframework.runtime.model.*; /** * * @author Peter Niederwieser */ public interface IAnnotationDrivenExtension { void visitSpecAnnotation(T annotation, SpecInfo spec); void visitFeatureAnnotation(T annotation, FeatureInfo feature); void visitFixtureAnnotation(T annotation, MethodInfo fixtureMethod); void visitFieldAnnotation(T annotation, FieldInfo field); void visitSpec(SpecInfo spec); } IGlobalExtension.java000066400000000000000000000014211202022523300343300ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; import org.spockframework.runtime.model.SpecInfo; public interface IGlobalExtension { void visitSpec(SpecInfo spec); } IMethodInterceptor.java000077500000000000000000000022171202022523300347010ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; /** * * @author Peter Niederwieser */ // IDEA: could separate exceptions thrown by Spec code from exceptions thrown // by an interceptor (although an interceptor might again call into Spec code, // or at least act on behalf of the Spec code, e.g. by connecting to a database) // possibilities for separation: 1. wrap Spec exceptions 2. pass back Spec // exceptions as return value of intercept() public interface IMethodInterceptor { void intercept(IMethodInvocation invocation) throws Throwable; } IMethodInvocation.java000066400000000000000000000056071202022523300345170ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; import org.spockframework.runtime.model.*; import org.spockframework.util.Nullable; /** * @author Peter Niederwieser */ public interface IMethodInvocation { /** * Returns the specification which this method invocation belongs to. * @return the specification which this method invocation belongs to */ SpecInfo getSpec(); /** * Returns the feature which this method invocation belongs to (if any). * Differs from MethodInfo.getFeature() in that it reflects the dynamic * picture. For example, when a setup method is invoked, this method * will return the corresponding feature, whereas MethodInfo.getFeature() * will return null. * @return the feature which this method invocation belongs to */ @Nullable FeatureInfo getFeature(); /** * Return the iteration which this method invocation belongs to (if any). * Executing a feature results in at least one but possibly more iterations * (e.g. for a data-driven feature). * * @return the iteration which this method invocation belongs to */ @Nullable IterationInfo getIteration(); /** * Returns the Specification instance for @Shared fields. * * @return the Specification instance for @Shared fields */ Object getSharedInstance(); /** * Returns the Specification instance for the current iteration. * * @return the Specification instance for the current iteration */ Object getInstance(); /** * Returns the target (receiver) of this method invocation. * In case of a static method call, a Class instance * is returned. * * @return the target (receiver) of this method invocation */ Object getTarget(); /** * Returns the method invoked by this method invocation. * * @return the method invoked by this method invocation */ MethodInfo getMethod(); /** * Returns the arguments for this method invocation. * * @return the arguments for this method invocation */ Object[] getArguments(); /** * Proceeds with the method call. Always call this method * unless you want to suppress the method call. * * @throws Throwable any exception thrown by the method call */ void proceed() throws Throwable; } MethodInvocation.java000077500000000000000000000046461202022523300344130ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension; import java.util.Iterator; import org.spockframework.runtime.model.*; import org.spockframework.util.ReflectionUtil; /** * * @author Peter Niederwieser */ public class MethodInvocation implements IMethodInvocation { private final FeatureInfo feature; private final IterationInfo iteration; private final Object sharedInstance; private final Object instance; private final Object target; private final MethodInfo method; private final Object[] arguments; private final Iterator interceptors; public MethodInvocation(FeatureInfo feature, IterationInfo iteration, Object sharedInstance, Object instance, Object target, MethodInfo method, Object[] arguments) { this.feature = feature; this.iteration = iteration; this.sharedInstance = sharedInstance; this.instance = instance; this.target = target; this.method = method; this.arguments = arguments; interceptors = method.getInterceptors().iterator(); } public SpecInfo getSpec() { return method.getParent(); } public FeatureInfo getFeature() { return feature; } public IterationInfo getIteration() { return iteration; } public Object getSharedInstance() { return sharedInstance; } public Object getInstance() { return instance; } public Object getTarget() { return target; } public MethodInfo getMethod() { return method; } public Object[] getArguments() { return arguments; } public void proceed() throws Throwable { if (interceptors.hasNext()) interceptors.next().intercept(this); else invokeTargetMethod(); } protected void invokeTargetMethod() throws Throwable { if (method.isStub()) return; ReflectionUtil.invokeMethod(target, method.getReflection(), arguments); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/000077500000000000000000000000001202022523300320065ustar00rootroot00000000000000AbstractRuleExtension.java000066400000000000000000000051541202022523300370670ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.lang.annotation.Annotation; import org.spockframework.runtime.InvalidSpecException; import org.spockframework.runtime.extension.IGlobalExtension; import org.spockframework.runtime.model.FieldInfo; import org.spockframework.util.ReflectionUtil; import org.spockframework.util.Nullable; public abstract class AbstractRuleExtension implements IGlobalExtension { @SuppressWarnings("unchecked") protected static Class ruleClass = (Class) ReflectionUtil.loadClassIfAvailable("org.junit.Rule"); @SuppressWarnings("unchecked") protected static Class classRuleClass = (Class) ReflectionUtil.loadClassIfAvailable("org.junit.ClassRule"); @Nullable protected static Class methodRuleClass = ReflectionUtil.loadClassIfAvailable("org.junit.rules.MethodRule"); @Nullable protected static Class testRuleClass = ReflectionUtil.loadClassIfAvailable("org.junit.rules.TestRule"); protected void checkIsInstanceField(FieldInfo field) { if (field.isShared() || field.isStatic()) { throw new InvalidSpecException("@Rule fields cannot be @Shared. Either do not make '%s' @Shared, or use @ClassRule.").withArgs(field.getName()); } } protected void checkIsSharedField(FieldInfo field) { if (!field.isShared()) { throw new InvalidSpecException("@ClassRule fields must be @Shared. Either make '%s' @Shared, or use @Rule.").withArgs(field.getName()); } } protected boolean hasFieldType(FieldInfo field, @Nullable Class ruleClass) { return ruleClass != null && ruleClass.isAssignableFrom(field.getType()); } protected void invalidFieldType(FieldInfo field) { if (field.getType() == Object.class) { throw new InvalidSpecException("@Rule field '%s' does not have a declared type. Please add a type declaration.").withArgs(field.getName()); } throw new InvalidSpecException("The declared type of @Rule field '%s' does not appear to be a rule type.").withArgs(field.getName()); } } AbstractRuleInterceptor.java000066400000000000000000000035501202022523300374070ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.junit.runners.model.Statement; import org.spockframework.runtime.extension.ExtensionException; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.runtime.extension.IMethodInvocation; import org.spockframework.runtime.model.FieldInfo; import java.util.List; public abstract class AbstractRuleInterceptor implements IMethodInterceptor { protected final List ruleFields; public AbstractRuleInterceptor(List ruleFields) { this.ruleFields = ruleFields; } protected Statement createBaseStatement(final IMethodInvocation invocation) { return new Statement() { @Override public void evaluate() throws Throwable { invocation.proceed(); } }; } protected Object getRuleInstance(FieldInfo field, Object fieldTarget) { Object rule = field.readValue(fieldTarget); if (rule == null) { try { rule = field.getType().newInstance(); field.writeValue(fieldTarget, rule); } catch (Exception e) { throw new ExtensionException("Auto-instantiating @Rule field '%s' failed. You may have to instantiate it manually.", e).withArgs(field.getName()); } } return rule; } } AutoCleanupExtension.java000066400000000000000000000032061202022523300367100ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.FieldInfo; import org.spockframework.runtime.model.SpecInfo; import spock.lang.AutoCleanup; /** * @author Peter Niederwieser */ // TODO: adapt to changes regarding field initialization public class AutoCleanupExtension extends AbstractAnnotationDrivenExtension { private final AutoCleanupInterceptor sharedFieldInterceptor = new AutoCleanupInterceptor(); private final AutoCleanupInterceptor instanceFieldInterceptor = new AutoCleanupInterceptor(); @Override public void visitFieldAnnotation(AutoCleanup annotation, FieldInfo field) { if (field.isShared()) sharedFieldInterceptor.add(field); else instanceFieldInterceptor.add(field); } @Override public void visitSpec(SpecInfo spec) { sharedFieldInterceptor.install(spec.getTopSpec().getCleanupSpecMethod()); instanceFieldInterceptor.install(spec.getTopSpec().getCleanupMethod()); } } AutoCleanupInterceptor.java000066400000000000000000000036731202022523300372420ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.util.*; import org.spockframework.runtime.extension.*; import org.spockframework.runtime.model.FieldInfo; import org.spockframework.runtime.model.MethodInfo; import org.spockframework.util.GroovyRuntimeUtil; import spock.lang.AutoCleanup; /** * @author Peter Niederwieser */ public class AutoCleanupInterceptor implements IMethodInterceptor { private final List fields = new ArrayList(); public void add(FieldInfo field) { fields.add(field); } public void install(MethodInfo method) { if (fields.isEmpty()) return; Collections.reverse(fields); method.addInterceptor(this); } public void intercept(IMethodInvocation invocation) throws Throwable { List exceptions = new ArrayList(); try { invocation.proceed(); } catch (Throwable t) { exceptions.add(t); } for (FieldInfo field : fields) { AutoCleanup annotation = field.getAnnotation(AutoCleanup.class); try { Object value = field.readValue(invocation.getTarget()); if (value == null) continue; GroovyRuntimeUtil.invokeMethod(value, annotation.value()); } catch (Throwable t) { if (!annotation.quiet()) exceptions.add(t); } } ExtensionUtil.throwAll(exceptions); } } ClassRuleExtension.java000066400000000000000000000031621202022523300363660ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.util.ArrayList; import java.util.List; import org.spockframework.runtime.model.FieldInfo; import org.spockframework.runtime.model.SpecInfo; @SuppressWarnings("UnusedDeclaration") public class ClassRuleExtension extends AbstractRuleExtension { public void visitSpec(SpecInfo spec) { if (classRuleClass == null) return; List ruleFields = new ArrayList(); for (FieldInfo field : spec.getAllFields()) { if (!field.isAnnotationPresent(classRuleClass)) continue; checkIsSharedField(field); if (hasFieldType(field, testRuleClass)) { ruleFields.add(field); } else { invalidFieldType(field); } } if (!ruleFields.isEmpty()) ClassRuleInterceptorInstaller.install(spec, ruleFields); } private static class ClassRuleInterceptorInstaller { static void install(SpecInfo spec, List ruleFields) { spec.addInterceptor(new ClassRuleInterceptor(ruleFields)); } } } ClassRuleInterceptor.java000066400000000000000000000026521202022523300367130ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.junit.rules.TestRule; import org.junit.runners.model.Statement; import org.spockframework.runtime.extension.IMethodInvocation; import org.spockframework.runtime.model.FieldInfo; import java.util.List; public class ClassRuleInterceptor extends AbstractRuleInterceptor { public ClassRuleInterceptor(List ruleFields) { super(ruleFields); } public void intercept(final IMethodInvocation invocation) throws Throwable { Statement stat = createBaseStatement(invocation); for (FieldInfo field : ruleFields) { TestRule rule = (TestRule) getRuleInstance(field, field.isShared() ? invocation.getSharedInstance() : invocation.getInstance()); stat = rule.apply(stat, invocation.getSpec().getDescription()); } stat.evaluate(); } } ConfineMetaClassChangesExtension.java000066400000000000000000000033041202022523300411360ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.IInterceptable; import org.spockframework.runtime.model.SpecInfo; import org.spockframework.util.CollectionUtil; import spock.util.mop.ConfineMetaClassChanges; /** * @author Luke Daley * @author Peter Niederwieser */ public class ConfineMetaClassChangesExtension extends AbstractAnnotationDrivenExtension { @Override public void visitSpecAnnotation(ConfineMetaClassChanges annotation, SpecInfo spec) { addInterceptor(annotation, spec.getBottomSpec()); } @Override public void visitFeatureAnnotation(ConfineMetaClassChanges annotation, FeatureInfo feature) { addInterceptor(annotation, feature.getFeatureMethod()); } private void addInterceptor(ConfineMetaClassChanges annotation, IInterceptable interceptable) { interceptable.addInterceptor(new ConfineMetaClassChangesInterceptor(CollectionUtil.asSet(annotation.value()))); } }ConfineMetaClassChangesInterceptor.java000066400000000000000000000036271202022523300414700ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import groovy.lang.ExpandoMetaClass; import groovy.lang.GroovySystem; import groovy.lang.MetaClass; import groovy.lang.MetaClassRegistry; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.runtime.extension.IMethodInvocation; import java.util.*; /** * @author Luke Daley * @author Peter Niederwieser */ public class ConfineMetaClassChangesInterceptor implements IMethodInterceptor { private final Collection> classes; private final List originalMetaClasses = new ArrayList(); public ConfineMetaClassChangesInterceptor(Collection> classes) { this.classes = classes; } public void intercept(IMethodInvocation invocation) throws Throwable { MetaClassRegistry registry = GroovySystem.getMetaClassRegistry(); for (Class clazz : classes) { originalMetaClasses.add(registry.getMetaClass(clazz)); MetaClass temporaryMetaClass = new ExpandoMetaClass(clazz, true, true); temporaryMetaClass.initialize(); registry.setMetaClass(clazz, temporaryMetaClass); } try { invocation.proceed(); } finally { for (MetaClass original : originalMetaClasses) registry.setMetaClass(original.getTheClass(), original); } } } FailsWithExtension.java000077500000000000000000000030661202022523300363710ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.*; import spock.lang.FailsWith; /** * @author Peter Niederwieser */ public class FailsWithExtension extends AbstractAnnotationDrivenExtension { public void visitSpecAnnotation(FailsWith failsWith, SpecInfo spec) { for (FeatureInfo feature : spec.getFeatures()) if (!feature.getFeatureMethod().getReflection().isAnnotationPresent(FailsWith.class)) feature.getFeatureMethod().addInterceptor(new FailsWithInterceptor(failsWith)); } public void visitFeatureAnnotation(FailsWith failsWith, FeatureInfo feature) { feature.getFeatureMethod().addInterceptor(new FailsWithInterceptor(failsWith)); } public void visitFixtureAnnotation(FailsWith failsWith, MethodInfo fixtureMethod) { fixtureMethod.addInterceptor(new FailsWithInterceptor(failsWith)); } } FailsWithInterceptor.java000077500000000000000000000026671202022523300367210ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.spockframework.runtime.WrongExceptionThrownError; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.runtime.extension.IMethodInvocation; import spock.lang.FailsWith; /** * * @author Peter Niederwieser */ public class FailsWithInterceptor implements IMethodInterceptor { private final FailsWith failsWith; public FailsWithInterceptor(FailsWith failsWith) { this.failsWith = failsWith; } public void intercept(IMethodInvocation invocation) throws Throwable { try { invocation.proceed(); } catch (Throwable t) { if (failsWith.value().isInstance(t)) return; throw new WrongExceptionThrownError(failsWith.value(), t); } throw new WrongExceptionThrownError(failsWith.value(), null); } } IgnoreExtension.java000066400000000000000000000025461202022523300357210ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.SpecInfo; import spock.lang.Ignore; /** * @author Peter Niederwieser */ // we cannot easily support @Ignore on fixture methods because // setup() and setupSpec() perform initialization of user-defined and internal fields public class IgnoreExtension extends AbstractAnnotationDrivenExtension { public void visitSpecAnnotation(Ignore ignore, SpecInfo spec) { if (spec.isBottomSpec()) spec.setSkipped(true); } public void visitFeatureAnnotation(Ignore ignore, FeatureInfo feature) { feature.setSkipped(true); } }IgnoreIfExtension.java000077500000000000000000000056141202022523300362020ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.math.BigDecimal; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import groovy.lang.Closure; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.extension.ExtensionException; import org.spockframework.runtime.model.*; import org.spockframework.util.GroovyRuntimeUtil; import org.spockframework.util.InternalSpockError; import spock.lang.IgnoreIf; /** * @author Peter Niederwieser */ public class IgnoreIfExtension extends AbstractAnnotationDrivenExtension { private static final Pattern JAVA_VERSION = Pattern.compile("(\\d+\\.\\d+).*"); private static final Object DELEGATE = new Object() { public Map getEnv() { return System.getenv(); } public Properties getProperties() { return System.getProperties(); } public BigDecimal getJavaVersion() { String versionString = System.getProperty("java.version"); Matcher matcher = JAVA_VERSION.matcher(versionString); if (matcher.matches()) return new BigDecimal(matcher.group(1)); throw new InternalSpockError(versionString); } }; @Override public void visitSpecAnnotation(IgnoreIf annotation, SpecInfo spec) { doVisit(annotation, spec); } @Override public void visitFeatureAnnotation(IgnoreIf annotation, FeatureInfo feature) { doVisit(annotation, feature); } private void doVisit(IgnoreIf annotation, ISkippable skippable) { Closure condition = createCondition(annotation.value()); Object result = evaluateCondition(condition); skippable.setSkipped(GroovyRuntimeUtil.isTruthy(result)); } private Closure createCondition(Class clazz) { try { return clazz.getConstructor(Object.class, Object.class).newInstance(null, null); } catch (Exception e) { throw new ExtensionException("Failed to instantiate @IgnoreIf condition", e); } } private Object evaluateCondition(Closure condition) { condition.setDelegate(DELEGATE); condition.setResolveStrategy(Closure.DELEGATE_ONLY); try { return condition.call(); } catch (Exception e) { throw new ExtensionException("Failed to evaluate @IgnoreIf condition", e); } } }IgnoreRestExtension.java000066400000000000000000000026111202022523300365500ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.SpecInfo; import spock.lang.IgnoreRest; /** * @author Peter Niederwieser */ public class IgnoreRestExtension extends AbstractAnnotationDrivenExtension { @Override public void visitFeatureAnnotation(IgnoreRest ignoreRest, FeatureInfo feature) {} // do nothing @Override public void visitSpec(SpecInfo spec) { if (spec.getSuperSpec() != null) visitSpec(spec.getSuperSpec()); for (FeatureInfo feature : spec.getFeatures()) feature.setSkipped(!feature.getFeatureMethod().getReflection().isAnnotationPresent(IgnoreRest.class)); } }IncludeExcludeExtension.java000066400000000000000000000066411202022523300373730ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.lang.annotation.Annotation; import java.util.List; import org.spockframework.runtime.extension.IGlobalExtension; import org.spockframework.runtime.model.*; import spock.config.IncludeExcludeCriteria; import spock.config.RunnerConfiguration; @SuppressWarnings("UnusedDeclaration") public class IncludeExcludeExtension implements IGlobalExtension { private RunnerConfiguration config; public void visitSpec(SpecInfo spec) { handleSpecIncludes(spec, config.include); handleSpecExcludes(spec, config.exclude); if (spec.isExcluded()) excludeAllFeatures(spec); handleFeatureIncludes(spec, config.include); handleFeatureExcludes(spec, config.exclude); if (spec.isExcluded() && !allFeaturesExcluded(spec)) spec.setExcluded(false); } private void handleSpecIncludes(SpecInfo spec, IncludeExcludeCriteria criteria) { if (criteria.isEmpty()) return; if (!hasAnyAnnotation(spec, criteria.annotations) && !hasAnyBaseClass(spec, criteria.baseClasses)) spec.setExcluded(true); } private void handleSpecExcludes(SpecInfo spec, IncludeExcludeCriteria criteria) { if (criteria.isEmpty()) return; if (hasAnyAnnotation(spec, criteria.annotations) || hasAnyBaseClass(spec, criteria.baseClasses)) spec.setExcluded(true); } // in contrast to the three other handleXXX methods, this one includes nodes private void handleFeatureIncludes(SpecInfo spec, IncludeExcludeCriteria criteria) { if (criteria.isEmpty()) return; for (FeatureInfo feature : spec.getAllFeatures()) if (hasAnyAnnotation(feature.getFeatureMethod(), criteria.annotations)) feature.setExcluded(false); } private void handleFeatureExcludes(SpecInfo spec, IncludeExcludeCriteria criteria) { if (criteria.isEmpty()) return; for (FeatureInfo feature : spec.getAllFeatures()) if (hasAnyAnnotation(feature.getFeatureMethod(), criteria.annotations)) feature.setExcluded(true); } private void excludeAllFeatures(SpecInfo spec) { for (FeatureInfo feature : spec.getAllFeatures()) feature.setExcluded(true); } private boolean allFeaturesExcluded(SpecInfo spec) { for (FeatureInfo feature : spec.getAllFeatures()) if (!feature.isExcluded()) return false; return true; } private boolean hasAnyAnnotation(NodeInfo node, List> annotationClasses) { for (Class annClass : annotationClasses) if (node.getReflection().isAnnotationPresent(annClass)) return true; return false; } private boolean hasAnyBaseClass(SpecInfo spec, List> baseClasses) { for (Class clazz : baseClasses) if (clazz.isAssignableFrom(spec.getReflection())) return true; return false; } } JUnitFixtureMethodsExtension.java000066400000000000000000000153141202022523300404170ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.util.List; import java.util.LinkedList; import java.util.Collection; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.annotation.Annotation; import org.junit.*; import org.spockframework.runtime.extension.*; import org.spockframework.runtime.model.*; import org.spockframework.util.ReflectionUtil; import org.spockframework.util.UnreachableCodeError; /** * Adapts the JUnit {@link Before}, {@link After}, {@link BeforeClass} and {@link AfterClass} fixture mechanism to Spock. *

* The method signature requirements that JUnit has for fixture methods apply exactly to Spock as well. That is, fixture methods * must return {@code void}, must take no arguments and must be {@code public}. Moreover, {@link Before} and {@link After} fixture * methods must be instance methods while {@link BeforeClass} and {@link AfterClass} fixture methods must be static. * Any methods that do not meet the requirements will be silently ignored. *

* {@link BeforeClass} fixture methods will be executed once before any feature methods or {@link Before} or {@code setup()} * methods, and before the {@code setupSpec()} method (if present). Inheritance semantics are identical * to {@code setupSpec()}, i.e. methods are executed for each class in the hierarchy in turn from parent to child. *

* {@link Before} fixture methods will be executed before every feature method and before * the {@code setup()} method (if present). Inheritance semantics are identical to {@code setup()}, i.e. methods are * executed for each class in the hierarchy in turn from parent to child. *

* {@link After} fixture methods will be executed after every feature method and after * the {@code cleanup()} method (if present). Inheritance semantics are identical to {@code cleanup()}, i.e. methods are * executed for each class in the hierarchy in turn from child to parent. *

* {@link AfterClass} fixture methods will be executed once after all feature methods and after {@link After} and * {@code cleanup()} methods, and after the {@code cleanupSpec()} method (if present). Inheritance semantics * are identical to {@code cleanupSpec()}, i.e. methods are executed for each class in the hierarchy in turn from child to parent. *

* The execution order of fixture methods of the same type withing the same class is undefined (as it is with JUnit). * * @author Luke Daley */ @SuppressWarnings("UnusedDeclaration") public class JUnitFixtureMethodsExtension implements IGlobalExtension { private static enum FixtureType { BEFORE(Before.class, false, MethodKind.SETUP, true), AFTER(After.class, false, MethodKind.CLEANUP, false), BEFORE_CLASS(BeforeClass.class, true, MethodKind.SETUP_SPEC, true), AFTER_CLASS(AfterClass.class, true, MethodKind.CLEANUP_SPEC, false); public final Class annotationType; public final boolean isStatic; public final MethodKind interceptedMethodKind; public final boolean executeBeforeSpecMethod; FixtureType(Class annotationType, boolean isStatic, MethodKind interceptedMethodKind, boolean executeBeforeSpecMethod) { this.annotationType = annotationType; this.isStatic = isStatic; this.interceptedMethodKind = interceptedMethodKind; this.executeBeforeSpecMethod = executeBeforeSpecMethod; } private void addInterceptor(SpecInfo specInfo, Collection potentialMethods) { List fixtureMethods = new LinkedList(); for (Method method : potentialMethods) { if (isMethod(method)) fixtureMethods.add(method); } if (!fixtureMethods.isEmpty()) { getInterceptedMethod(specInfo).addInterceptor(new FixtureMethodInterceptor(fixtureMethods)); } } private MethodInfo getInterceptedMethod(SpecInfo specInfo) { for (MethodInfo methodInfo : specInfo.getFixtureMethods()) { if (methodInfo.getKind().equals(interceptedMethodKind)) return methodInfo; } throw new UnreachableCodeError("failed to find fixture method of kind " + interceptedMethodKind); } // NOTE - method is assumed to have passed isPotentialMethod private boolean isMethod(Method method) { boolean isMethod = method.getAnnotation(annotationType) != null && Modifier.isStatic(method.getModifiers()) == isStatic; return isMethod; } static public boolean isPotentialMethod(Method method) { boolean isPotential = method.getReturnType().equals(void.class) && method.getParameterTypes().length == 0 && Modifier.isPublic(method.getModifiers()); return isPotential; } static public void addInterceptors(SpecInfo spec) { for (SpecInfo currentSpec : spec.getSpecsBottomToTop()) { List potentialMethods = new LinkedList(); for (Method method : currentSpec.getReflection().getDeclaredMethods()) { if (isPotentialMethod(method)) { potentialMethods.add(method); } } if (!potentialMethods.isEmpty()) { for (FixtureType fixtureType : FixtureType.values()) { fixtureType.addInterceptor(currentSpec, potentialMethods); } } } } private class FixtureMethodInterceptor implements IMethodInterceptor { private final Collection methods; public FixtureMethodInterceptor(Collection methods) { this.methods = methods; } public void intercept(IMethodInvocation invocation) throws Throwable { if (!executeBeforeSpecMethod) invocation.proceed(); for (Method method : methods) { ReflectionUtil.invokeMethod(invocation.getTarget(), method); } if (executeBeforeSpecMethod) invocation.proceed(); } } } public void visitSpec(SpecInfo spec) { FixtureType.addInterceptors(spec); } }MethodRuleInterceptor.java000066400000000000000000000034411202022523300370630ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; import org.spockframework.runtime.extension.IMethodInvocation; import org.spockframework.runtime.model.FieldInfo; import java.util.List; public class MethodRuleInterceptor extends AbstractRuleInterceptor { MethodRuleInterceptor(List ruleFields) { super(ruleFields); } public void intercept(final IMethodInvocation invocation) throws Throwable { Statement statement = createBaseStatement(invocation); FrameworkMethod method = createFrameworkMethod(invocation); for (FieldInfo field : ruleFields) { MethodRule rule = (MethodRule) getRuleInstance(field, invocation.getTarget()); statement = rule.apply(statement, method, invocation.getTarget()); } statement.evaluate(); } private FrameworkMethod createFrameworkMethod(final IMethodInvocation invocation) { return new FrameworkMethod(invocation.getMethod().getReflection()) { @Override public String getName() { return invocation.getIteration().getDescription().getMethodName(); } }; } } OptimizeRunOrderExtension.java000066400000000000000000000047331202022523300377570ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.io.IOException; import org.spockframework.runtime.AbstractRunListener; import org.spockframework.runtime.SpecRunHistory; import org.spockframework.runtime.extension.IGlobalExtension; import org.spockframework.runtime.model.*; import spock.config.RunnerConfiguration; /** * Inspired from JUnit's MaxCore. */ @SuppressWarnings("UnusedDeclaration") public class OptimizeRunOrderExtension implements IGlobalExtension { private RunnerConfiguration configuration; public void visitSpec(SpecInfo spec) { if (!configuration.optimizeRunOrder) return; final SpecRunHistory history = new SpecRunHistory(spec.getReflection().getName()); safeLoadFromDisk(history); history.sortFeatures(spec); spec.addListener(new AbstractRunListener() { long specStarted; long featureStarted; boolean errorOccurred; @Override public void beforeSpec(SpecInfo spec) { specStarted = System.nanoTime(); } @Override public void beforeFeature(FeatureInfo feature) { featureStarted = System.nanoTime(); errorOccurred = false; } @Override public void afterFeature(FeatureInfo feature) { history.collectFeatureData(feature, System.nanoTime() - featureStarted, errorOccurred); } @Override public void error(ErrorInfo error) { errorOccurred = true; } @Override public void afterSpec(SpecInfo spec) { history.collectSpecData(spec, System.nanoTime() - specStarted); safeSaveToDisk(history); } }); } private void safeLoadFromDisk(SpecRunHistory history) { try { history.loadFromDisk(); } catch (IOException ignored) {} } private void safeSaveToDisk(SpecRunHistory history) { try { history.saveToDisk(); } catch (IOException ignored) {} } } RevertMetaClassRunListener.java000066400000000000000000000100061202022523300400260ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.util.*; import java.util.Map.Entry; import org.spockframework.runtime.AbstractRunListener; import org.spockframework.runtime.model.*; import org.spockframework.util.NotThreadSafe; import groovy.lang.*; /** * @author Luke Daley */ @NotThreadSafe // expects beforeFeature and afterFeature to be called in matching pairs public class RevertMetaClassRunListener extends AbstractRunListener { private final Map, MetaClass> specLevelSavedMetaClasses = new HashMap, MetaClass>(); private final Map, MetaClass> methodLevelSavedMetaClasses = new HashMap, MetaClass>(); private final Set> specRestorations; private final Map>> methodRestorations; public RevertMetaClassRunListener(Set> specRestorations, Map>> methodRestorations) { this.specRestorations = specRestorations; this.methodRestorations = methodRestorations; } public void beforeSpec(SpecInfo spec) { if (specRestorations.isEmpty()) return; saveMetaClassesInto(specRestorations, specLevelSavedMetaClasses); } public void beforeFeature(FeatureInfo feature) { if (feature.isParameterized()) return; if (methodRestorations.isEmpty()) return; String methodName = feature.getFeatureMethod().getReflection().getName(); if (!methodRestorations.containsKey(methodName)) return; saveMetaClassesInto(methodRestorations.get(methodName), methodLevelSavedMetaClasses); } public void beforeIteration(IterationInfo iteration) { if (!iteration.getParent().isParameterized()) return; if (methodRestorations.isEmpty()) return; String methodName = iteration.getParent().getFeatureMethod().getReflection().getName(); if (!methodRestorations.containsKey(methodName)) return; saveMetaClassesInto(methodRestorations.get(methodName), methodLevelSavedMetaClasses); } public void afterIteration(IterationInfo iteration) { if (!iteration.getParent().isParameterized()) return; if (methodLevelSavedMetaClasses.isEmpty()) return; revertMetaClassesFromAndClear(methodLevelSavedMetaClasses); } public void afterFeature(FeatureInfo feature) { if (feature.isParameterized()) return; if (methodLevelSavedMetaClasses.isEmpty()) return; revertMetaClassesFromAndClear(methodLevelSavedMetaClasses); } public void afterSpec(SpecInfo spec) { if (specRestorations.isEmpty()) return; revertMetaClassesFromAndClear(specLevelSavedMetaClasses); } private void saveMetaClassesInto(Set> toSave, Map, MetaClass> into) { MetaClassRegistry registry = GroovySystem.getMetaClassRegistry(); for (Class clazz : toSave) { into.put(clazz, registry.getMetaClass(clazz)); MetaClass newMetaClass = new ExpandoMetaClass(clazz, true, true); newMetaClass.initialize(); registry.setMetaClass(clazz, newMetaClass); } } private void revertMetaClassesFromAndClear(Map, MetaClass> savedMetaClasses) { MetaClassRegistry registry = GroovySystem.getMetaClassRegistry(); for (Entry, MetaClass> entry : savedMetaClasses.entrySet()) { Class clazz = entry.getKey(); MetaClass originalMetaClass = entry.getValue(); registry.removeMetaClass(clazz); registry.setMetaClass(clazz, originalMetaClass); } savedMetaClasses.clear(); } } RuleExtension.java000066400000000000000000000051451202022523300354030ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.util.ArrayList; import java.util.List; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.FieldInfo; import org.spockframework.runtime.model.SpecInfo; // This extension supports different JUnit versions with different rule capabilities/implementations. // Implementation makes use of reflection and nested classes to make sure that no ClassNotFoundErrorS will occur. @SuppressWarnings("UnusedDeclaration") public class RuleExtension extends AbstractRuleExtension { public void visitSpec(SpecInfo spec) { if (ruleClass == null) return; List methodRuleFields = new ArrayList(); List testRuleFields = new ArrayList(); for (FieldInfo field : spec.getAllFields()) { if (!field.isAnnotationPresent(ruleClass)) continue; checkIsInstanceField(field); if (hasFieldType(field, methodRuleClass)) { methodRuleFields.add(field); } else if (hasFieldType(field, testRuleClass)) { testRuleFields.add(field); } else { invalidFieldType(field); } } if (!methodRuleFields.isEmpty()) MethodRuleInterceptorInstaller.install(spec, methodRuleFields); if (!testRuleFields.isEmpty()) TestRuleInterceptorInstaller.install(spec, testRuleFields); } private static class MethodRuleInterceptorInstaller { static void install(SpecInfo spec, List ruleFields) { MethodRuleInterceptor interceptor = new MethodRuleInterceptor(ruleFields); for (FeatureInfo feature : spec.getAllFeatures()) { feature.getFeatureMethod().addInterceptor(interceptor); } } } private static class TestRuleInterceptorInstaller { static void install(SpecInfo spec, List ruleFields) { TestRuleInterceptor interceptor = new TestRuleInterceptor(ruleFields); for (FeatureInfo feature : spec.getAllFeatures()) { feature.addIterationInterceptor(interceptor); } } } } StepwiseExtension.java000066400000000000000000000045011202022523300362720ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.lang.annotation.Annotation; import java.util.*; import org.spockframework.runtime.AbstractRunListener; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.*; public class StepwiseExtension extends AbstractAnnotationDrivenExtension { public void visitSpecAnnotation(Annotation annotation, final SpecInfo spec) { sortFeaturesInDeclarationOrder(spec); includeFeaturesBeforeLastIncludedFeature(spec); skipFeaturesAfterFirstFailingFeature(spec); } private void sortFeaturesInDeclarationOrder(SpecInfo spec) { for (FeatureInfo feature : spec.getFeatures()) feature.setExecutionOrder(feature.getDeclarationOrder()); } private void includeFeaturesBeforeLastIncludedFeature(SpecInfo spec) { List features = spec.getFeatures(); boolean includeRemaining = false; for (int i = features.size() - 1; i >= 0; i--) { FeatureInfo feature = features.get(i); if (includeRemaining) feature.setExcluded(false); else if (!feature.isExcluded()) includeRemaining = true; } } private void skipFeaturesAfterFirstFailingFeature(final SpecInfo spec) { spec.getBottomSpec().addListener(new AbstractRunListener() { public void error(ErrorInfo error) { // @Dependent only affects class that carries the annotation, // but not sub- and super classes if (!error.getMethod().getParent().equals(spec)) return; // we can just set skip flag on all features, even though // some of them might already have run for (FeatureInfo feature : spec.getFeatures()) feature.setSkipped(true); } }); } } TestRuleInterceptor.java000066400000000000000000000025711202022523300365650ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.util.List; import org.junit.rules.TestRule; import org.junit.runners.model.Statement; import org.spockframework.runtime.extension.IMethodInvocation; import org.spockframework.runtime.model.FieldInfo; public class TestRuleInterceptor extends AbstractRuleInterceptor { public TestRuleInterceptor(List ruleFields) { super(ruleFields); } public void intercept(final IMethodInvocation invocation) throws Throwable { Statement stat = createBaseStatement(invocation); for (FieldInfo field : ruleFields) { TestRule rule = (TestRule) getRuleInstance(field, invocation.getInstance()); stat = rule.apply(stat, invocation.getIteration().getDescription()); } stat.evaluate(); } } TimeoutExtension.java000077500000000000000000000032311202022523300361170ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.MethodInfo; import org.spockframework.runtime.model.SpecInfo; import spock.lang.Timeout; /** * @author Peter Niederwieser */ public class TimeoutExtension extends AbstractAnnotationDrivenExtension { @Override public void visitSpecAnnotation(Timeout timeout, SpecInfo spec) { for (FeatureInfo feature : spec.getFeatures()) { if (!feature.getFeatureMethod().getReflection().isAnnotationPresent(Timeout.class)) { visitFeatureAnnotation(timeout, feature); } } } @Override public void visitFeatureAnnotation(Timeout timeout, FeatureInfo feature) { feature.getFeatureMethod().addInterceptor(new TimeoutInterceptor(timeout)); } @Override public void visitFixtureAnnotation(Timeout timeout, MethodInfo fixtureMethod) { fixtureMethod.addInterceptor(new TimeoutInterceptor(timeout)); } }TimeoutInterceptor.java000077500000000000000000000103201202022523300364360ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.text.DecimalFormat; import java.util.concurrent.*; import org.spockframework.runtime.SpockTimeoutError; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.runtime.extension.IMethodInvocation; import spock.lang.Timeout; /** * Times out a method invocation if it takes too long. The method invocation * will occur on the regular test framework thread. This can be important * for integration tests with thread-local state. * * @author Peter Niederwieser */ public class TimeoutInterceptor implements IMethodInterceptor { private final Timeout timeout; public TimeoutInterceptor(Timeout timeout) { this.timeout = timeout; } public void intercept(final IMethodInvocation invocation) throws Throwable { final Thread mainThread = Thread.currentThread(); final SynchronousQueue sync = new SynchronousQueue(); new Thread(String.format("[spock.lang.Timeout] Watcher for method '%s'", invocation.getMethod().getName())) { public void run() { StackTraceElement[] stackTrace = new StackTraceElement[0]; long waitMillis = timeout.unit().toMillis(timeout.value()); boolean synced = false; while (!synced) { try { synced = sync.offer(stackTrace, waitMillis, TimeUnit.MILLISECONDS); } catch (InterruptedException ignored) { // The mission of this thread is to repeatedly interrupt the main thread until // the latter returns. Once this mission has been accomplished, this thread will die quickly } if (!synced) { if (stackTrace.length == 0) { stackTrace = mainThread.getStackTrace(); waitMillis = 250; } else { waitMillis *= 2; System.out.printf("[spock.lang.Timeout] Method '%s' has not yet returned - interrupting. Next try in %1.2f seconds.\n", invocation.getMethod().getName(), waitMillis / 1000.); } mainThread.interrupt(); } } } }.start(); Throwable saved = null; try { invocation.proceed(); } catch (Throwable t) { saved = t; } StackTraceElement[] stackTrace = null; while (stackTrace == null) { try { stackTrace = sync.take(); } catch (InterruptedException e) { // There is a small chance that this came from the watcher thread, // i.e. the two threads narrowly missed each other at the sync point. // Therefore, let's sync again to learn whether this thread has timed out or not. // As this won't take long, it should also be acceptable if this thread // got interrupted by some other thread. To report on the latter case, // we save off the exception, overriding any previously saved exception. saved = e; } } if (stackTrace.length > 0) { // We know that this thread got timed out (and interrupted) by the watcher thread and // act accordingly. We gloss over the fact that some other thread might also have tried to // interrupt this thread. This shouldn't be a problem in practice, in particular because // throwing an InterruptedException wouldn't abort the whole test run anyway. SpockTimeoutError timeoutError = new SpockTimeoutError(timeout.value(), timeout.unit(), "Method timed out after %d %s", timeout.value(), timeout.unit().toString().toLowerCase()); timeoutError.setStackTrace(stackTrace); throw timeoutError; } if (saved != null) { throw saved; } } }UnrollExtension.java000066400000000000000000000036031202022523300357440ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.IterationInfo; import org.spockframework.runtime.model.NameProvider; import org.spockframework.runtime.model.SpecInfo; import spock.lang.Unroll; public class UnrollExtension extends AbstractAnnotationDrivenExtension { @Override public void visitSpecAnnotation(Unroll unroll, SpecInfo spec) { for (FeatureInfo feature : spec.getFeatures()) { if (feature.isParameterized()) { visitFeatureAnnotation(unroll, feature); } } } @Override public void visitFeatureAnnotation(Unroll unroll, FeatureInfo feature) { if (!feature.isParameterized()) return; // could also throw exception feature.setReportIterations(true); feature.setIterationNameProvider(chooseNameProvider(unroll, feature)); } private NameProvider chooseNameProvider(Unroll unroll, FeatureInfo feature) { if (unroll.value().length() > 0) { return new UnrollNameProvider(feature, unroll.value()); } if (feature.getName().contains("#")) { return new UnrollNameProvider(feature, feature.getName()); } return null; } } UnrollNameProvider.java000066400000000000000000000057171202022523300363730ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.IterationInfo; import org.spockframework.runtime.model.NameProvider; import org.spockframework.util.GroovyRuntimeUtil; /** * @author Peter Niederwieser */ public class UnrollNameProvider implements NameProvider { private static final Pattern EXPRESSION_PATTERN = Pattern.compile("#([a-zA-Z_\\$][\\w\\$\\.\\(\\)]*)"); private final FeatureInfo feature; private final Matcher expressionMatcher; private int iterationCount; public UnrollNameProvider(FeatureInfo feature, String namePattern) { this.feature = feature; expressionMatcher = EXPRESSION_PATTERN.matcher(namePattern); } // always returns a name public String getName(IterationInfo iterationInfo) { return nameFor(iterationInfo.getDataValues()); } String nameFor(Object... dataValues) { StringBuffer result = new StringBuffer(); expressionMatcher.reset(); while (expressionMatcher.find()) { String expr = expressionMatcher.group(1); String value = evaluateExpression(expr, dataValues); expressionMatcher.appendReplacement(result, Matcher.quoteReplacement(value)); } expressionMatcher.appendTail(result); iterationCount++; return result.toString(); } private String evaluateExpression(String expr, Object[] dataValues) { String[] exprParts = expr.split("\\."); String firstPart = exprParts[0]; Object result; if (firstPart.equals("featureName")) { result = feature.getName(); } else if (firstPart.equals("iterationCount")) { result = String.valueOf(iterationCount); } else { int index = feature.getDataVariables().indexOf(firstPart); if (index < 0) return "#Error:" + expr; result = dataValues[index]; } try { for (int i = 1; i < exprParts.length; i++) { String currPart = exprParts[i]; if (currPart.endsWith("()")) { result = GroovyRuntimeUtil.invokeMethod(result, currPart.substring(0, currPart.length() - 2)); } else { result = GroovyRuntimeUtil.getProperty(result, currPart); } } return GroovyRuntimeUtil.toString(result); } catch (Exception e) { return "#Error:" + expr; } } } UseExtension.java000066400000000000000000000032131202022523300352220ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.runtime.model.IInterceptable; import org.spockframework.runtime.model.MethodInfo; import org.spockframework.runtime.model.SpecInfo; import spock.util.mop.Use; import java.util.Arrays; public class UseExtension extends AbstractAnnotationDrivenExtension { public void visitSpecAnnotation(Use annotation, SpecInfo spec) { addInterceptor(annotation, spec.getBottomSpec()); } public void visitFeatureAnnotation(Use annotation, FeatureInfo feature) { addInterceptor(annotation, feature.getFeatureMethod()); } @Override public void visitFixtureAnnotation(Use annotation, MethodInfo fixtureMethod) { addInterceptor(annotation, fixtureMethod); } private void addInterceptor(Use annotation, IInterceptable interceptable) { interceptable.addInterceptor(new UseInterceptor(Arrays.asList(annotation.value()))); } }UseInterceptor.java000077500000000000000000000027231202022523300355540ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin; import java.util.List; import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.runtime.extension.IMethodInvocation; import groovy.lang.Closure; /** * @author Peter Niederwieser */ public class UseInterceptor implements IMethodInterceptor { private final List categories; public UseInterceptor(List categories) { this.categories = categories; } public void intercept(final IMethodInvocation invocation) throws Throwable { DefaultGroovyMethods.use(null, categories, new Closure(invocation.getTarget(), invocation.getTarget()) { public Void doCall(Object[] args) throws Throwable { invocation.proceed(); return null; } }); } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/000077500000000000000000000000001202022523300274245ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/BlockInfo.java000077500000000000000000000021561202022523300321440ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import java.util.List; /** * Runtime information about a block in a method of a Spock specification. * * @author Peter Niederwieser */ public class BlockInfo { private BlockKind kind; private List texts; public BlockKind getKind() { return kind; } public void setKind(BlockKind kind) { this.kind = kind; } public List getTexts() { return texts; } public void setTexts(List texts) { this.texts = texts; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/BlockKind.java000077500000000000000000000015371202022523300321400ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; /** * The different kind of blocks that a BlockInfo instance can represent. * * @author Peter Niederwieser */ public enum BlockKind { SETUP, EXPECT, WHEN, THEN, CLEANUP, WHERE } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/BlockMetadata.java000077500000000000000000000020241202022523300327630ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import java.lang.annotation.*; /** * Internal block metadata generated by the compiler for consumption by the runtime. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface BlockMetadata { String KIND = "kind"; String TEXTS = "texts"; BlockKind kind(); String[] texts(); // IDEA: rename to "description(s)" } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/DataProviderInfo.java000066400000000000000000000016071202022523300334730ustar00rootroot00000000000000package org.spockframework.runtime.model; import java.lang.reflect.AnnotatedElement; import java.util.List; /** * Internal metadata about a data provider from which the runtime model is built. * * @author Peter Niederwieser */ public class DataProviderInfo extends NodeInfo { private List dataVariables; private MethodInfo dataProviderMethod; @Override public AnnotatedElement getReflection() { throw new UnsupportedOperationException("getReflection"); } public List getDataVariables() { return dataVariables; } public void setDataVariables(List dataVariables) { this.dataVariables = dataVariables; } public MethodInfo getDataProviderMethod() { return dataProviderMethod; } public void setDataProviderMethod(MethodInfo dataProviderMethod) { this.dataProviderMethod = dataProviderMethod; } } DataProviderMetadata.java000066400000000000000000000005141202022523300342350ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/modelpackage org.spockframework.runtime.model; import java.lang.annotation.*; /** * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DataProviderMetadata { String LINE = "line"; String DATA_VARIABLES = "dataVariables"; int line(); String[] dataVariables(); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/ErrorInfo.java000066400000000000000000000017211202022523300321750ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; public class ErrorInfo { private final MethodInfo method; private final Throwable error; public ErrorInfo(MethodInfo method, Throwable error) { this.method = method; this.error = error; } public MethodInfo getMethod() { return method; } public Throwable getException() { return error; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/ExpressionInfo.java000077500000000000000000000123431202022523300332500ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import java.util.*; import org.spockframework.util.Nullable; import org.spockframework.util.ReflectionUtil; /** * @author Peter Niederwieser */ public class ExpressionInfo implements Iterable { public static final String TEXT_NOT_AVAILABLE = new String("(n/a)"); /** * Indicates that an expression's value is not available, either because the * expression has no value (e.g. def foo = 42), or because it wasn't evaluated * (due to shortcut evaluation of boolean expressions). */ public static final Object VALUE_NOT_AVAILABLE = new Object() { @Override public String toString() { return "(n/a)"; } }; private TextRegion region; private TextPosition anchor; /** * Examples where operation is null: * - GString method name: foo."$bar"() * - Argument list (has children but no operation) */ @Nullable private final String operation; private final List children; private String text; private Object value; private String renderedValue; private boolean relevant = true; public ExpressionInfo(TextRegion region, TextPosition anchor, @Nullable String operation, List children) { this.region = region; this.anchor = anchor; this.operation = operation; this.children = children; } public ExpressionInfo(TextRegion region, TextPosition anchor, @Nullable String operation, ExpressionInfo... children) { this(region, anchor, operation, Arrays.asList(children)); } public TextRegion getRegion() { return region; } public TextPosition getAnchor() { return anchor; } public String getOperation() { return operation; } public List getChildren() { return children; } public String getText() { return text; } public void setText(String text) { this.text = text; } public Object getValue() { return value; } public ExpressionInfo setValue(Object value) { this.value = value; return this; } public String getRenderedValue() { return renderedValue; } public void setRenderedValue(String renderedValue) { this.renderedValue = renderedValue; } public String getEffectiveRenderedValue() { return renderedValue != null ? renderedValue : text; } public boolean isRelevant() { return relevant && value != VALUE_NOT_AVAILABLE; } public ExpressionInfo setRelevant(boolean relevant) { this.relevant = relevant; return this; } public void shiftVertically(int numLines) { region = region.shiftVertically(numLines); anchor = anchor.shiftVertically(numLines); } public Iterator iterator() { List list = new ArrayList(); collectPrefix(list, false); return list.iterator(); } public Iterable inPrefixOrder(final boolean skipIrrelevant) { return new Iterable() { public Iterator iterator() { List list = new ArrayList(); collectPrefix(list, skipIrrelevant); return list.iterator(); } }; } public Iterable inPostfixOrder(final boolean skipIrrelevant) { return new Iterable() { public Iterator iterator() { List list = new ArrayList(); collectPostfix(list, skipIrrelevant); return list.iterator(); } }; } public Iterable inCustomOrder(boolean skipIrrelevant, Comparator comparator) { List list = new ArrayList(); collectPrefix(list, skipIrrelevant); Collections.sort(list, comparator); return list; } public boolean isEqualityComparison() { return "==".equals(operation) && children.size() == 2; } public boolean isEqualityComparison(Class... types) { if (!isEqualityComparison()) return false; if (!ReflectionUtil.hasAnyOfTypes(children.get(0).getValue(), types)) return false; if (!ReflectionUtil.hasAnyOfTypes(children.get(1).getValue(), types)) return false; return true; } private void collectPrefix(List collector, boolean skipIrrelevant) { if (!skipIrrelevant || isRelevant()) collector.add(this); for (ExpressionInfo expr : children) expr.collectPrefix(collector,skipIrrelevant); } private void collectPostfix(List collector, boolean skipIrrelevant) { for (ExpressionInfo expr : children) expr.collectPostfix(collector, skipIrrelevant); if (!skipIrrelevant || isRelevant()) collector.add(this); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/FeatureInfo.java000066400000000000000000000104731202022523300325030ustar00rootroot00000000000000package org.spockframework.runtime.model; import java.lang.reflect.AnnotatedElement; import java.util.ArrayList; import java.util.List; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.util.Nullable; /** * @author Peter Niederwieser */ public class FeatureInfo extends NodeInfo implements ISkippable, IExcludable, IInterceptable { private int declarationOrder; // per spec class private int executionOrder; // per spec inheritance chain private List parameterNames = new ArrayList(); private final List blocks = new ArrayList(); private final List interceptors = new ArrayList(); private final List iterationInterceptors = new ArrayList(); private MethodInfo featureMethod; private MethodInfo dataProcessorMethod; private NameProvider iterationNameProvider; private final List dataProviders = new ArrayList(); private boolean excluded = false; private boolean skipped = false; private boolean reportIterations = false; @Override public AnnotatedElement getReflection() { throw new UnsupportedOperationException("getReflection"); } public int getDeclarationOrder() { return declarationOrder; } public void setDeclarationOrder(int declarationOrder) { this.declarationOrder = declarationOrder; } public int getExecutionOrder() { return executionOrder; } public void setExecutionOrder(int executionOrder) { this.executionOrder = executionOrder; } public List getParameterNames() { return parameterNames; } public void addParameterName(String parameterName) { parameterNames.add(parameterName); } public List getDataVariables() { return parameterNames; // currently the same } public List getBlocks() { return blocks; } public void addBlock(BlockInfo block) { blocks.add(block); } public List getInterceptors() { return interceptors; } public void addInterceptor(IMethodInterceptor interceptor) { interceptors.add(interceptor); } public List getIterationInterceptors() { return iterationInterceptors; } public void addIterationInterceptor(IMethodInterceptor interceptor) { iterationInterceptors.add(interceptor); } public MethodInfo getFeatureMethod() { return featureMethod; } public void setFeatureMethod(MethodInfo method) { this.featureMethod = method; } public MethodInfo getDataProcessorMethod() { return dataProcessorMethod; } public void setDataProcessorMethod(MethodInfo method) { this.dataProcessorMethod = method; } public List getDataProviders() { return dataProviders; } public void addDataProvider(DataProviderInfo dataProvider) { dataProviders.add(dataProvider); } public boolean isParameterized() { return dataProcessorMethod != null; } public boolean isReportIterations() { return reportIterations; } public void setReportIterations(boolean flag) { reportIterations = flag; } @Nullable public NameProvider getIterationNameProvider() { return iterationNameProvider; } public void setIterationNameProvider(NameProvider provider) { iterationNameProvider = provider; } public boolean isExcluded() { return excluded; } public void setExcluded(boolean excluded) { this.excluded = excluded; } public boolean isSkipped() { return skipped; } public void setSkipped(boolean skipped) { this.skipped = skipped; } /** * Tells if any of the methods associated with this feature has the specified * name in bytecode. * * @param name a method name in bytecode * @return true { private int ordinal; public int getOrdinal() { return ordinal; } public void setOrdinal(int ordinal) { this.ordinal = ordinal; } public Class getType() { return getReflection().getType(); } public boolean isStatic() { return Modifier.isStatic(getReflection().getModifiers()); } public boolean isShared() { return getReflection().isAnnotationPresent(Shared.class); } public T getAnnotation(Class clazz) { return getReflection().getAnnotation(clazz); } public boolean isAnnotationPresent(Class clazz) { return getReflection().isAnnotationPresent(clazz); } public Object readValue(Object target) { return GroovyRuntimeUtil.getProperty(target, getReflection().getName()); } public void writeValue(Object target, Object value) { GroovyRuntimeUtil.setProperty(target, getReflection().getName(), value); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/FieldMetadata.java000077500000000000000000000020101202022523300327470ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import java.lang.annotation.*; /** * Internal metadata about a field, from which the runtime model is built. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface FieldMetadata { String NAME = "name"; String ORDINAL = "ordinal"; String LINE = "line"; String name(); int ordinal(); int line(); }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/IExcludable.java000066400000000000000000000013551202022523300324540ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; public interface IExcludable { boolean isExcluded(); void setExcluded(boolean excluded); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/IInterceptable.java000066400000000000000000000015571202022523300331710ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import org.spockframework.runtime.extension.IMethodInterceptor; import java.util.List; public interface IInterceptable { List getInterceptors(); void addInterceptor(IMethodInterceptor interceptor); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/ISkippable.java000066400000000000000000000013511202022523300323120ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; public interface ISkippable { boolean isSkipped(); void setSkipped(boolean skipped); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/IterationInfo.java000066400000000000000000000052131202022523300330420ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import java.lang.reflect.AnnotatedElement; /** * Runtime information about an iteration of a feature method. */ public class IterationInfo extends NodeInfo { private final Object[] dataValues; private final int estimatedNumIterations; public IterationInfo(FeatureInfo feature, Object[] dataValues, int estimatedNumIterations) { setParent(feature); this.dataValues = dataValues; this.estimatedNumIterations = estimatedNumIterations; } @Override public AnnotatedElement getReflection() { throw new UnsupportedOperationException("getReflection"); } /** * Returns the name of this iteration. No strong guarantees are provided for this name, * except that it is non-null. For example, it may be the same as the feature name, * and it may not be unique among iterations of the same feature execution. * Nevertheless, this is generally the name that should be presented to the user (if any). * * @return the name of this iteration */ public String getName() { return super.getName(); } /** * Return this iteration's data values for the ongoing execution of the * owning feature method. The names of the data values (in the same order) * are available through {@link FeatureInfo#getDataVariables}. * * @return this iteration's data values for the ongoing execution of the * owning feature method */ public Object[] getDataValues() { return dataValues; } /** * Returns the estimated total number of iterations for the ongoing execution * of the owning feature method. The value is obtained by calling * size() on each data provider before the first iteration is run. * It is only an estimate and won't change during feature execution (i.e. all * FeatureInfos will return the same value). * * @return the estimated total number of iterations for the execution * of the owning feature method */ public int getEstimatedNumIterations() { return estimatedNumIterations; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/MethodInfo.java000077500000000000000000000033431202022523300323310ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.util.Nullable; /** * Runtime information about a method in a Spock specification. * * @author Peter Niederwieser */ public class MethodInfo extends NodeInfo implements IInterceptable { private MethodKind kind; private FeatureInfo feature; private final List interceptors = new ArrayList(); public MethodKind getKind() { return kind; } public void setKind(MethodKind kind) { this.kind = kind; } @Nullable public FeatureInfo getFeature() { return feature; } public void setFeature(FeatureInfo feature) { this.feature = feature; } public List getInterceptors() { return interceptors; } public void addInterceptor(IMethodInterceptor interceptor) { interceptors.add(interceptor); } public boolean hasBytecodeName(String name) { return getReflection().getName().equals(name); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/MethodKind.java000077500000000000000000000027211202022523300323220ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; /** * The different kinds of methods that a MethodInfo instance can represent. * * @author Peter Niederwieser */ public enum MethodKind { INITIALIZER, SHARED_INITIALIZER, SETUP, CLEANUP, SETUP_SPEC, CLEANUP_SPEC, FEATURE, DATA_PROVIDER, DATA_PROCESSOR, SPEC_EXECUTION, FEATURE_EXECUTION, ITERATION_EXECUTION; public boolean isFixtureMethod() { return isSetupMethod() || isCleanupMethod(); } public boolean isSetupMethod() { return this == SETUP || this == SETUP_SPEC; } public boolean isCleanupMethod() { return this == CLEANUP || this == CLEANUP_SPEC; } public boolean isFeatureScopedFixtureMethod() { return this == SETUP || this == CLEANUP; } public boolean isSpecScopedFixtureMethod() { return this == SETUP_SPEC || this == CLEANUP_SPEC; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/NameProvider.java000066400000000000000000000013111202022523300326560ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; public interface NameProvider { String getName(T t); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/NodeInfo.java000077500000000000000000000037421202022523300320010ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import java.lang.reflect.AnnotatedElement; import org.junit.runner.Description; import org.spockframework.util.Nullable; /** * Base class for runtime information about an element in a Spock specification. * * @author Peter Niederwieser */ public abstract class NodeInfo

{ private String name; private int line = -1; private P parent; private R reflection; private Object metadata; private Description description; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getLine() { return line; } public void setLine(int line) { this.line = line; } public P getParent() { return parent; } public void setParent(P parent) { this.parent = parent; } public R getReflection() { return reflection; } public void setReflection(R reflection) { this.reflection = reflection; } @Nullable public Object getMetadata() { return metadata; } public void setMetadata(Object metadata) { this.metadata = metadata; } @Nullable public Description getDescription() { return description; } public void setDescription(Description description) { this.description = description; } public boolean isStub() { return getReflection() == null; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/SpecInfo.java000077500000000000000000000172411202022523300320050ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import java.util.*; import org.spockframework.runtime.*; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.util.*; /** * Runtime information about a Spock specification. * * @author Peter Niederwieser */ public class SpecInfo extends NodeInfo> implements IMethodNameMapper, ISkippable, IExcludable, IInterceptable { private final List fields = new ArrayList(); private final List interceptors = new ArrayList(); private final List listeners = new ArrayList(); private String filename; private SpecInfo superSpec; private SpecInfo subSpec; private List specsTopToBottom; private List specsBottomToTop; private FieldInfo sharedInstanceField; private MethodInfo initializerMethod; private MethodInfo sharedInitializerMethod; private MethodInfo setupMethod; private MethodInfo cleanupMethod; private MethodInfo setupSpecMethod; private MethodInfo cleanupSpecMethod; private List features = new ArrayList(); private boolean excluded = false; private boolean skipped = false; public String getFilename() { return filename; } public void setFilename(String filename) { this.filename = filename; } public SpecInfo getSuperSpec() { return superSpec; } public void setSuperSpec(SpecInfo superSpec) { this.superSpec = superSpec; } public SpecInfo getSubSpec() { return subSpec; } public void setSubSpec(SpecInfo subSpec) { this.subSpec = subSpec; } public SpecInfo getTopSpec() { SpecInfo curr = this; while (curr.getSuperSpec() != null) curr = curr.getSuperSpec(); return curr; } public boolean isTopSpec() { return superSpec == null; } public SpecInfo getBottomSpec() { SpecInfo curr = this; while (curr.getSubSpec() != null) curr = curr.getSubSpec(); return curr; } public boolean isBottomSpec() { return subSpec == null; } public List getSpecsTopToBottom() { if (specsTopToBottom == null) { specsTopToBottom = new ArrayList(); SpecInfo curr = getTopSpec(); while (curr != null) { specsTopToBottom.add(curr); curr = curr.getSubSpec(); } } return specsTopToBottom; } public List getSpecsBottomToTop() { if (specsBottomToTop == null) { specsBottomToTop = new ArrayList(); SpecInfo curr = getBottomSpec(); while (curr != null) { specsBottomToTop.add(curr); curr = curr.getSuperSpec(); } } return specsBottomToTop; } public FieldInfo getSharedInstanceField() { return sharedInstanceField; } public void setSharedInstanceField(FieldInfo sharedInstanceField) { this.sharedInstanceField = sharedInstanceField; } public MethodInfo getInitializerMethod() { return initializerMethod; } public void setInitializerMethod(MethodInfo initializerMethod) { this.initializerMethod = initializerMethod; } public MethodInfo getSharedInitializerMethod() { return sharedInitializerMethod; } public void setSharedInitializerMethod(MethodInfo sharedInitializerMethod) { this.sharedInitializerMethod = sharedInitializerMethod; } public MethodInfo getSetupMethod() { return setupMethod; } public void setSetupMethod(MethodInfo setupMethod) { this.setupMethod = setupMethod; } public MethodInfo getCleanupMethod() { return cleanupMethod; } public void setCleanupMethod(MethodInfo cleanupMethod) { this.cleanupMethod = cleanupMethod; } public MethodInfo getSetupSpecMethod() { return setupSpecMethod; } public void setSetupSpecMethod(MethodInfo setupSpecMethod) { this.setupSpecMethod = setupSpecMethod; } public MethodInfo getCleanupSpecMethod() { return cleanupSpecMethod; } public void setCleanupSpecMethod(MethodInfo cleanupSpecMethod) { this.cleanupSpecMethod = cleanupSpecMethod; } public List getFixtureMethods() { return Arrays.asList(setupSpecMethod, setupMethod, cleanupMethod, cleanupSpecMethod); } public List getAllFixtureMethods() { if (superSpec == null) return getFixtureMethods(); List result = new ArrayList(superSpec.getAllFixtureMethods()); result.addAll(getFixtureMethods()); return result; } public List getFields() { return fields; } public List getAllFields() { if (superSpec == null) return fields; List result = new ArrayList(superSpec.getAllFields()); result.addAll(fields); return result; } public void addField(FieldInfo field) { fields.add(field); } public List getFeatures() { return features; } public List getAllFeatures() { if (superSpec == null) return features; List result = new ArrayList(superSpec.getAllFeatures()); result.addAll(features); return result; } public List getAllFeaturesInExecutionOrder() { List result = getAllFeatures(); Collections.sort(result, new Comparator() { public int compare(FeatureInfo f1, FeatureInfo f2) { return f1.getExecutionOrder() - f2.getExecutionOrder(); } }); return result; } public void addFeature(FeatureInfo feature) { features.add(feature); } public List getInterceptors() { return interceptors; } public void addInterceptor(IMethodInterceptor interceptor) { interceptors.add(interceptor); } public List getListeners() { return listeners; } public void addListener(IRunListener listener) { listeners.add(listener); } public boolean isExcluded() { return excluded; } public void setExcluded(boolean excluded) { this.excluded = excluded; } public boolean isSkipped() { return skipped; } public void setSkipped(boolean skipped) { this.skipped = skipped; } public void filterFeatures(final IFeatureFilter filter) { for (FeatureInfo feature: getAllFeatures()) { if (!filter.matches(feature)) feature.setExcluded(true); } } public void sortFeatures(final IFeatureSortOrder order) { List features = getAllFeatures(); Collections.sort(features, order); for (int i = 0; i < features.size(); i++) features.get(i).setExecutionOrder(i); } public boolean isInitializerOrFixtureMethod(String className, String methodName) { if (!InternalIdentifiers.INITIALIZER_AND_FIXTURE_METHODS.contains(methodName)) return false; for (SpecInfo spec : getSpecsBottomToTop()) if (spec.getReflection().getName().equals(className)) return true; return false; } public String toFeatureName(String methodName) { for (FeatureInfo feature : getAllFeatures()) if (feature.hasBytecodeName(methodName)) return feature.getName(); return methodName; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/SpecMetadata.java000077500000000000000000000021331202022523300326240ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import java.lang.annotation.*; /** * Internal specification metadata generated by the compiler for consumption * by the runtime. Currently only serves as an indication that the specification * has been compiled successfully. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface SpecMetadata { String FILENAME = "filename"; String LINE = "line"; String filename(); int line(); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/TextPosition.java000077500000000000000000000055641202022523300327550ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.syntax.Token; /** * A position in a text, given as a line/column pair. The first character in the * text has position (1,1). TextPosition instances are immutable. * * @author Peter Niederwieser */ public class TextPosition implements Comparable { // IDEA: override methods to throw UnsupportedOperationException public static final TextPosition NOT_AVAILABLE = new TextPosition(-1, -1); private final int line; private final int column; /** * Creates a new TextPosition instance. * * @param line the position's line number * @param column the position's column number * @throws IllegalArgumentException if line or column is less than 1 */ private TextPosition(int line, int column) { this.line = line; this.column = column; } public int getLine() { return line; } public int getColumn() { return column; } public int getLineIndex() { return line - 1; } public int getColumnIndex() { return column - 1; } public TextPosition shiftVertically(int numLines) { return create(line + numLines, column); } public boolean equals(Object obj) { if (obj == null || getClass() != obj.getClass()) return false; TextPosition other = (TextPosition)obj; return line == other.line && column == other.column; } public int hashCode() { return line * 31 + column; } public String toString() { return String.format("(%d,%d)", line, column); } public int compareTo(TextPosition other) { if (line != other.line) return line - other.line; return column - other.column; } // inclusive public static TextPosition startOf(Token token) { return create(token.getStartLine(), token.getStartColumn()); } // inclusive public static TextPosition startOf(ASTNode node) { return create(node.getLineNumber(), node.getColumnNumber()); } // exclusive public static TextPosition endOf(ASTNode node) { return create(node.getLastLineNumber(), node.getLastColumnNumber()); } public static TextPosition create(int line, int column) { if (line < 1 || column < 1) return TextPosition.NOT_AVAILABLE; return new TextPosition(line, column); } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/model/TextRegion.java000077500000000000000000000047141202022523300323700ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.model; import org.codehaus.groovy.ast.ASTNode; /** * A region of text spanning all characters between a start position (inclusive) * and an end position (exclusive). Positions are given as line/column pairs * (starting at 1). TextRegion instances are immutable. * * @author Peter Niederwieser */ public class TextRegion { // IDEA: override methods to throw UnsupportedOperationException public static final TextRegion NOT_AVAILABLE = new TextRegion(TextPosition.NOT_AVAILABLE, TextPosition.NOT_AVAILABLE); private final TextPosition start; // inclusive private final TextPosition end; // exclusive private TextRegion(TextPosition start, TextPosition end) { this.start = start; this.end = end; } public TextPosition getStart() { return start; } public TextPosition getEnd() { return end; } public boolean contains(TextPosition position) { return position.compareTo(start) >= 0 && position.compareTo(end) <= 0; } public TextRegion shiftVertically(int numLines) { return create(start.shiftVertically(numLines), end.shiftVertically(numLines)); } public boolean equals(Object obj) { if (obj == null || getClass() != obj.getClass()) return false; TextRegion other = (TextRegion)obj; return start.equals(other.start) && end.equals(other.end); } public int hashCode() { return start.hashCode() * 31 + end.hashCode(); } public String toString() { return String.format("%s-%s", start, end); } public static TextRegion of(ASTNode node) { return create(TextPosition.startOf(node), TextPosition.endOf(node)); } public static TextRegion create(TextPosition start, TextPosition end) { if (start == TextPosition.NOT_AVAILABLE || end == TextPosition.NOT_AVAILABLE) return TextRegion.NOT_AVAILABLE; return new TextRegion(start, end); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/000077500000000000000000000000001202022523300256165ustar00rootroot00000000000000AbstractExpressionConverter.java000077500000000000000000000064351202022523300341300ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.util.ArrayList; import java.util.List; import org.codehaus.groovy.ast.GroovyCodeVisitor; import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.stmt.*; // IDEA: abstract method that provides default conversion if result not set public abstract class AbstractExpressionConverter implements GroovyCodeVisitor { protected T result; // tries to detect all situations where a visitXXXExpression // method doesn't set a result, as this would corrupt the // conversion public T convert(Expression expr) { result = null; expr.visit(this); if (result == null) Assert.fail("No result set for expression: " + expr); T temp = result; result = null; return temp; } protected List convertAll(List expressions) { List converted = new ArrayList(expressions.size()); for (Expression expr : expressions) converted.add(convert(expr)); return converted; } protected void unsupported() { throw new UnsupportedOperationException(); } // remaining methods are statement callbacks of GroovyCodeVisitor public final void visitBlockStatement(BlockStatement statement) { unsupported(); } public final void visitForLoop(ForStatement forLoop) { unsupported(); } public final void visitWhileLoop(WhileStatement loop) { unsupported(); } public final void visitDoWhileLoop(DoWhileStatement loop) { unsupported(); } public final void visitIfElse(IfStatement ifElse) { unsupported(); } public final void visitExpressionStatement(ExpressionStatement statement) { unsupported(); } public final void visitReturnStatement(ReturnStatement statement) { unsupported(); } public final void visitAssertStatement(AssertStatement statement) { unsupported(); } public final void visitTryCatchFinally(TryCatchStatement finally1) { unsupported(); } public final void visitSwitch(SwitchStatement statement) { unsupported(); } public final void visitCaseStatement(CaseStatement statement) { unsupported(); } public final void visitBreakStatement(BreakStatement statement) { unsupported(); } public final void visitContinueStatement(ContinueStatement statement) { unsupported(); } public final void visitThrowStatement(ThrowStatement statement) { unsupported(); } public final void visitSynchronizedStatement(SynchronizedStatement statement) { unsupported(); } public final void visitCatchStatement(CatchStatement statement) { unsupported(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/Assert.java000077500000000000000000000030171202022523300277260ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; /** * Assertions for use within Spock code. Failures indicate internal errors. * * @author Peter Niederwieser */ public abstract class Assert { // IDEA: beef up error message ("please submit bug report", include caller in message in case stack trace is lost) public static void notNull(Object obj) { notNull(obj, "argument is null"); } public static void notNull(Object obj, String msg, Object... values) { if (obj == null) throw new InternalSpockError(String.format(msg, values)); } public static void that(boolean condition) { that(condition, "internal error"); } public static void that(boolean condition, String msg, Object... values) { if (!condition) throw new InternalSpockError(String.format(msg, values)); } public static void fail(String msg, Object... values) { that(false, msg, values); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/CollectionUtil.java000066400000000000000000000066541202022523300314250ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.util.*; public abstract class CollectionUtil { public static ArrayList filterMap(Collection collection, IFunction function) { ArrayList result = new ArrayList(collection.size()); for (E elem : collection) { F resultElem = function.apply(elem); if (resultElem != null) result.add(resultElem); } return result; } /** * (Partial) replacement for Arrays.copyOfRange, which is only available in JDK6. */ public static Object[] copyArray(Object[] array, int from, int to) { Object[] result = new Object[to - from]; System.arraycopy(array, from, result, 0, to - from); return result; } public static @Nullable T getLastElement(List list) { Assert.that(list.size() > 0); return list.get(list.size() - 1); } public static void setLastElement(List list, T elem) { Assert.that(list.size() > 0); list.set(list.size() - 1, elem); } public static void addLastElement(List list, T element) { list.add(list.size(), element); } public static Iterable reverse(final List list) { return new Iterable() { public Iterator iterator() { final ListIterator listIterator = list.listIterator(list.size()); return new Iterator() { public boolean hasNext() { return listIterator.hasPrevious(); } public T next() { return listIterator.previous(); } public void remove() { listIterator.remove(); } }; } }; } public static Set asSet(T[] values) { return new HashSet(Arrays.asList(values)); } public static Iterable concat(Iterable... iterables) { return concat(Arrays.asList(iterables)); } public static Iterable concat(final List> iterables) { return new Iterable() { public Iterator iterator() { return new Iterator() { Iterator iter; int pos = 0; public boolean hasNext() { while (pos < iterables.size()) { if (iter == null) iter = iterables.get(pos).iterator(); if (iter.hasNext()) return true; iter = null; pos++; } return false; } public T next() { while (pos < iterables.size()) { if (iter == null) iter = iterables.get(pos).iterator(); if (iter.hasNext()) return iter.next(); iter = null; pos++; } throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException("remove"); } }; } }; } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/ExceptionUtil.java000066400000000000000000000020361202022523300312560ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; /** * @author Peter Niederwieser */ public class ExceptionUtil { /** * Allows to throw an unchecked exception without declaring it in a throws clause. */ public static void sneakyThrow(Throwable t) { ExceptionUtil.doSneakyThrow(t); } @SuppressWarnings("unchecked") private static void doSneakyThrow(Throwable t) throws T { throw (T) t; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/Filter.java000066400000000000000000000024311202022523300277060ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.util.*; public class Filter { private final IMatcher matcher; private Filter(IMatcher matcher) { this.matcher = matcher; } public List filter(List items) { List result = new ArrayList(); for (T item : items) if (matcher.matches(item)) result.add(item); return result; } public void filterInPlace(List items) { Iterator iter = items.iterator(); while (iter.hasNext()) if (!matcher.matches(iter.next())) iter.remove(); } public static Filter create(IMatcher matcher) { return new Filter(matcher); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/GroovyReleaseInfo.java000066400000000000000000000017611202022523300320700ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import groovy.lang.GroovyObject; import org.codehaus.groovy.util.ReleaseInfo; public class GroovyReleaseInfo { public static VersionNumber getVersion() { return VersionNumber.parse(ReleaseInfo.getVersion()); } public static String getArtifactPath() { return GroovyObject.class.getProtectionDomain().getCodeSource().getLocation().toString(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/GroovyRuntimeUtil.java000066400000000000000000000161411202022523300321530ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import groovy.lang.Closure; import groovy.lang.MetaClass; import groovy.lang.MetaMethod; import org.codehaus.groovy.runtime.*; import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation; import java.util.Iterator; /** * Provides convenient access to Groovy language and runtime features. * By convention, all usages of Groovy's InvokerHelper and * ScriptBytecodeAdapter go through this class. * * @author Peter Niederwieser */ public abstract class GroovyRuntimeUtil { public static boolean isTruthy(Object obj) { return DefaultTypeTransformation.castToBoolean(obj); } // can't generify return type because DefaultTypeTransformation // returns a wrapper if 'type' refers to a primitive type public static Object coerce(Object obj, Class type) { return DefaultTypeTransformation.castToType(obj, type); } public static boolean equals(Object obj, Object other) { return DefaultTypeTransformation.compareEqual(obj, other); } public static String toString(Object obj) { return DefaultGroovyMethods.toString(obj); } public static MetaClass getMetaClass(Object object) { return InvokerHelper.getMetaClass(object); } public static String propertyToMethodName(String prefix, String propertyName) { return prefix + MetaClassHelper.capitalize(propertyName); } /** * Note: This method may throw checked exceptions although it doesn't say so. */ public static Object getProperty(Object target, String property) { try { return InvokerHelper.getProperty(target, property); } catch (InvokerInvocationException e) { ExceptionUtil.sneakyThrow(e.getCause()); return null; // never reached } } /** * Note: This method may throw checked exceptions although it doesn't say so. */ public static void setProperty(Object target, String property, Object value) { try { InvokerHelper.setProperty(target, property, value); } catch (InvokerInvocationException e) { ExceptionUtil.sneakyThrow(e.getCause()); } } /** * Note: This method may throw checked exceptions although it doesn't say so. */ public static Object invokeConstructor(Class clazz, Object... args) { try { return InvokerHelper.invokeConstructorOf(clazz, args); } catch (InvokerInvocationException e) { ExceptionUtil.sneakyThrow(e.getCause()); return null; // never reached } } /** * Note: This method may throw checked exceptions although it doesn't say so. */ public static Object invokeMethod(Object target, String method, Object... args) { try { return InvokerHelper.invokeMethod(target, method, args); } catch (InvokerInvocationException e) { ExceptionUtil.sneakyThrow(e.getCause()); return null; // never reached } } public static Object invokeMethodNullSafe(Object target, String method, Object... args) { try { return InvokerHelper.invokeMethodSafe(target, method, args); } catch (InvokerInvocationException e) { ExceptionUtil.sneakyThrow(e.getCause()); return null; // never reached } } public static Object invokeMethodQuietly(Object target, String method, Object... args) { try { return InvokerHelper.invokeMethod(target, method, args); } catch (Throwable ignored) { return null; } } /** * Note: This method may throw checked exceptions although it doesn't say so. */ @SuppressWarnings("unchecked") public static Object invokeClosure(Closure closure, Object... args) { try { return closure.call(args); } catch (InvokerInvocationException e) { ExceptionUtil.sneakyThrow(e.getCause()); return null; // never reached } } /** * Note: This method may throw checked exceptions although it doesn't say so. */ public static Iterator asIterator(Object object) { try { return InvokerHelper.asIterator(object); } catch (InvokerInvocationException e) { ExceptionUtil.sneakyThrow(e.getCause()); return null; // never reached } } public static Object[] asArray(Object args) { return InvokerHelper.asArray(args); } public static Object[] despreadList(Object[] args, Object[] spreads, int[] positions) { return ScriptBytecodeAdapter.despreadList(args, spreads, positions); } // let's try to find the method that was invoked and see if it has return type void // since we now do another method dispatch (w/o actually invoking the method), // there is a small chance that we get an incorrect result because a MetaClass has // been changed since the first dispatch; to eliminate this chance we would have to // first find the MetaMethod and then invoke it, but the problem is that calling // MetaMethod.invoke doesn't have the exact same semantics as calling // InvokerHelper.invokeMethod, even if the same method is chosen (see Spec GroovyMopExploration) public static boolean isVoidMethod(Object target, String method, Object... args) { Class[] argTypes = ReflectionUtil.getTypes(args); // the way we choose metaClass, we won't find methods on java.lang.Class // but since java.lang.Class has no void methods other than the ones inherited // from java.lang.Object, and since we operate on a best effort basis, that's OK // also we will choose a static method like Foo.getName() over the equally // named method on java.lang.Class, but this is consistent with current Groovy semantics // (see http://jira.codehaus.org/browse/GROOVY-3548) // in the end it's probably best to rely on NullAwareInvokeMethodSpec to tell us if // everything is OK MetaClass metaClass = target instanceof Class ? InvokerHelper.getMetaClass((Class) target) : InvokerHelper.getMetaClass(target); // seems to find more methods than getMetaMethod() MetaMethod metaMethod = metaClass.pickMethod(method, argTypes); if (metaMethod == null) return false; // we were unable to figure out which method was called Class returnType = metaMethod.getReturnType(); // although Void.class will occur rarely, it makes sense to handle // it in the same way as void.class return returnType == void.class || returnType == Void.class; } /** * Note: This method may throw checked exceptions although it doesn't say so. */ public static Object getAttribute(Object target, String name) { try { return InvokerHelper.getAttribute(target, name); } catch (InvokerInvocationException e) { ExceptionUtil.sneakyThrow(e.getCause()); return null; // never reached } } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/IFunction.java000066400000000000000000000015051202022523300303600ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; /** * A function from domain D to co-domain C. * * @author Peter Niederwieser */ public interface IFunction extends IThrowableFunction { C apply(D value); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/IMatcher.java000066400000000000000000000013001202022523300301470ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; public interface IMatcher { boolean matches(T node); } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/IThrowableFunction.java000066400000000000000000000015431202022523300322320ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; /** * A function from domain D to co-domain C that may throw a checked exception. * * @author Peter Niederwieser */ public interface IThrowableFunction { C apply(D value) throws T; } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/Identifiers.java000077500000000000000000000046441202022523300307410ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.util.Arrays; import java.util.List; /** * Identifiers used throughout the core. * * @author Peter Niederwieser */ public abstract class Identifiers { // Tokens ------------------------------------------------------------------- public static final String SETUP = "setup"; public static final String GIVEN = "given"; public static final String EXPECT = "expect"; /** * Label name identifying a when-block. */ public static final String WHEN = "when"; /** * Label name identifying a then-block. */ public static final String THEN = "then"; /** * Label name identifying a cleanup-block. */ public static final String CLEANUP = "cleanup"; /** * Label name identifying a where-block. */ public static final String WHERE = "where"; public static final String AND = "and"; public static final List BLOCK_LABELS = Arrays.asList(SETUP, GIVEN, EXPECT, WHEN, THEN, CLEANUP, WHERE, AND); public static final String SETUP_METHOD = "setup"; public static final String CLEANUP_METHOD = "cleanup"; /** * Method name identifying a fixture method that is executed before each spec. */ public static final String SETUP_SPEC_METHOD = "setupSpec"; /** * Method name identifying a fixture method that is executed after each spec. */ public static final String CLEANUP_SPEC_METHOD = "cleanupSpec"; public static final List FIXTURE_METHODS = Arrays.asList(SETUP_METHOD, CLEANUP_METHOD, SETUP_SPEC_METHOD, CLEANUP_SPEC_METHOD); public static final String MOCK = "Mock"; public static final String THROWN = "thrown"; public static final String INTERACTION = "interaction"; public static final String OLD = "old"; } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/Immutable.java000066400000000000000000000013771202022523300304100ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Immutable {}IncompatibleGroovyVersionException.java000066400000000000000000000014471202022523300354510ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; public class IncompatibleGroovyVersionException extends RuntimeException { public IncompatibleGroovyVersionException(String message) { super(message); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/InternalIdentifiers.java000066400000000000000000000036601202022523300324300ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Internal identifiers in generated bytecode. * * @author Peter Niederwieser */ public class InternalIdentifiers { public static final String SHARED_INSTANCE_NAME = "$spock_sharedInstance"; public static final String INITIALIZER_METHOD = "$spock_initializeFields"; public static final String SHARED_INITIALIZER_METHOD = "$spock_initializeSharedFields"; public static final List INITIALIZER_METHODS = Arrays.asList(INITIALIZER_METHOD, SHARED_INITIALIZER_METHOD); public static final List INITIALIZER_AND_FIXTURE_METHODS; static { INITIALIZER_AND_FIXTURE_METHODS = new ArrayList(); INITIALIZER_AND_FIXTURE_METHODS.addAll(INITIALIZER_METHODS); INITIALIZER_AND_FIXTURE_METHODS.addAll(Identifiers.FIXTURE_METHODS); } public static String getDataProcessorName(String featureName) { return featureName + "proc"; } public static String getDataProviderName(String featureName, int providerIndex) { return featureName + "prov" + providerIndex; } public static boolean isFeatureMethodName(String name) { return name.startsWith("$spock_feature"); } public static String getSharedFieldName(String baseName) { return "$spock_sharedField_" + baseName; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/InternalSpockError.java000077500000000000000000000024321202022523300322530ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; /** * * @author Peter Niederwieser */ public class InternalSpockError extends Error { private Object[] msgArgs; public InternalSpockError() { super("unexpected error"); } public InternalSpockError(Throwable throwable) { super("unexpected error", throwable); } public InternalSpockError(String msg) { super(msg); } public InternalSpockError(String msg, Throwable throwable) { super(msg, throwable); } public InternalSpockError withArgs(Object... msgArgs) { this.msgArgs = msgArgs; return this; } @Override public String getMessage() { return String.format(super.getMessage(), msgArgs); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/IoUtil.java000066400000000000000000000071251202022523300276730ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.io.*; public class IoUtil { public static void closeQuietly(@Nullable Closeable... closeables) { if (closeables == null) return; for (Closeable closeable : closeables) { if (closeable == null) return; try { closeable.close(); } catch (IOException ignored) {} } } /** * Returns the text read from the given reader as a String. * Closes the given reader upon return. */ public static String getText(Reader reader) throws IOException { try { StringBuilder source = new StringBuilder(); BufferedReader buffered = new BufferedReader(reader); String line = buffered.readLine(); while (line != null) { source.append(line); source.append('\n'); line = buffered.readLine(); } return source.toString(); } finally { closeQuietly(reader); } } /** * Returns the text read from the given file as a String. */ public static String getText(File path) throws IOException { return getText(new FileReader(path)); } /** * Returns the text read from the given stream as a String. * Closes the given stream upon return. */ public static String getText(InputStream stream) throws IOException { return getText(new InputStreamReader(stream)); } public static void createDirectory(File dir) throws IOException { if (!dir.isDirectory() && !dir.mkdirs()) throw new IOException("Failed to create directory: " + dir); } public static void copyStream(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[4096]; try { int read = in.read(buffer); while (read > 0) { out.write(buffer, 0, read); read = in.read(buffer); } } finally { IoUtil.closeQuietly(in, out); } } public static void copyFile(File source, File target) throws FileNotFoundException, IOException { if (!source.isFile()) throw new IOException(String.format("Error copying file %s to %s; source file does not exist", source, target)); createDirectory(target.getParentFile()); doCopyFile(source, target); checkSameSize(source, target); } private static void doCopyFile(File source, File target) throws IOException { FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream(source); out = new FileOutputStream(target); // instead of checking transferred size, we'll compare file sizes in checkSameSize() in.getChannel().transferTo(0, Long.MAX_VALUE, out.getChannel()); } finally { IoUtil.closeQuietly(in, out); } } private static void checkSameSize(File source, File target) throws IOException { long fromSize = source.length(); long toSize = target.length(); if (fromSize != toSize) throw new IOException(String.format( "Error copying file %s to %s; source file size is %d, but target file size is %d", source, target, fromSize, toSize)); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/Matchers.java000066400000000000000000000026511202022523300302330ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; public class Matchers { public static IMatcher and(final IMatcher... matchers) { return new IMatcher() { public boolean matches(T item) { for (IMatcher matcher : matchers) if (!matcher.matches(item)) return false; return true; } }; } public static IMatcher or(final IMatcher... matchers) { return new IMatcher() { public boolean matches(T item) { for (IMatcher matcher : matchers) if (matcher.matches(item)) return true; return false; } }; } public static IMatcher not(final IMatcher matcher) { return new IMatcher() { public boolean matches(T item) { return !matcher.matches(item); } }; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/MopUtil.java000066400000000000000000000110541202022523300300530ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.lang.reflect.*; import org.codehaus.groovy.reflection.CachedField; import org.codehaus.groovy.reflection.CachedMethod; import org.codehaus.groovy.runtime.metaclass.*; import groovy.lang.*; public abstract class MopUtil { private static final Field ReflectionMetaMethod_method = getDeclaredField(ReflectionMetaMethod.class, "method"); private static final Field CachedField_field = getDeclaredField(CachedField.class, "field"); private static Field getDeclaredField(Class clazz, String name) { try { Field result = clazz.getDeclaredField(name); result.setAccessible(true); return result; } catch (NoSuchFieldException e) { throw new RuntimeException(String.format( "Found an incompatibility between the Spock and Groovy versions you are using: field '%s.%s' does not exist.", clazz, name)); } } public static Method methodFor(MetaMethod method) { if (method instanceof CachedMethod) return ((CachedMethod) method).getCachedMethod(); if (method instanceof ClosureMetaMethod) return ((ClosureMetaMethod) method).getDoCall().getCachedMethod(); if (method instanceof ReflectionMetaMethod) { try { return ((CachedMethod) ReflectionMetaMethod_method.get(method)).getCachedMethod(); } catch (IllegalAccessException e) { throw new UnreachableCodeError(e); } } // could try stunts for MixinInstanceMetaMethod and TransformMetaMethod or // even apply some general heuristics (e.g. look for field named "method" or // "metaMethod" (or with type Method/MetaMethod) and invoke methodFor() // recursively), but we won't do this for now return null; } public static Member memberFor(MetaProperty property) { if (property instanceof CachedField) try { return (Member)CachedField_field.get(property); } catch (IllegalAccessException e) { throw new UnreachableCodeError(e); } if (property instanceof MetaBeanProperty) { MetaBeanProperty mbp = (MetaBeanProperty) property; if (mbp.getGetter() != null) return methodFor(mbp.getGetter()); if (mbp.getSetter() != null) return methodFor(mbp.getSetter()); if (mbp.getField() != null) return memberFor(mbp.getField()); return null; } return null; } public static Field fieldFor(MetaProperty property) { if (property instanceof CachedField) try { return (Field)CachedField_field.get(property); } catch (IllegalAccessException e) { throw new UnreachableCodeError(e); } if (property instanceof MetaBeanProperty) { MetaBeanProperty mbp = (MetaBeanProperty) property; if (mbp.getField() != null) return fieldFor(mbp.getField()); return null; } return null; } public static Method getterFor(MetaProperty property) { if (property instanceof MetaBeanProperty) { MetaBeanProperty mbp = (MetaBeanProperty) property; if (mbp.getGetter() != null) return methodFor(mbp.getGetter()); return null; } return null; } public static Method setterFor(MetaProperty property) { if (property instanceof MetaBeanProperty) { MetaBeanProperty mbp = (MetaBeanProperty) property; if (mbp.getSetter() != null) return methodFor(mbp.getSetter()); return null; } return null; } public static boolean isReadable(MetaProperty property) { if (property instanceof CachedField) return true; if (property instanceof MetaBeanProperty) { MetaBeanProperty mbp = (MetaBeanProperty) property; return mbp.getGetter() != null || mbp.getField() != null; } return false; } public static boolean isWriteable(MetaProperty property) { if (property instanceof CachedField) return true; if (property instanceof MetaBeanProperty) { MetaBeanProperty mbp = (MetaBeanProperty) property; return mbp.getSetter() != null || mbp.getField() != null; } return false; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/NotThreadSafe.java000066400000000000000000000014041202022523300311470ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface NotThreadSafe {} spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/Nullable.java000066400000000000000000000014551202022523300302240ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.lang.annotation.*; @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @Retention(RetentionPolicy.SOURCE) public @interface Nullable {} spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/ObjectUtil.java000066400000000000000000000032451202022523300305310ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; /** * Utility methods applicable to (almost) any object. Includes null-safe variants of methods on class Object. */ public abstract class ObjectUtil { public static boolean equals(Object obj1, Object obj2) { if (obj1 == null) return obj2 == null; return obj1.equals(obj2); } public static int hashCode(Object obj) { return obj == null ? 0 : obj.hashCode(); } public static String toString(Object obj) { return obj == null ? "null" : obj.toString(); } public static Class getClass(Object obj) { return obj == null ? null : obj.getClass(); } public static Class voidAwareGetClass(Object obj) { return obj == null ? void.class : obj.getClass(); } public static boolean eitherNull(Object... objs) { for (Object obj: objs) { if (obj == null) return true; } return false; } public static > int compare(T c1, T c2) { if (c1 == null && c2 == null) return 0; if (c1 == null) return -1; if (c2 == null) return 1; return c1.compareTo(c2); } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/Pair.java000066400000000000000000000032271202022523300273600ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; /** * An immmutable pair of elements. * * @author Peter Niederwieser */ public class Pair { private final E1 first; private final E2 second; private Pair(E1 first, E2 second) { this.first = first; this.second = second; } public E1 first() { return first; } public E2 second() { return second; } @Override public boolean equals(Object other) { if (this == other) return true; if (other == null || getClass() != other.getClass()) return false; Pair tuple2 = (Pair) other; if (first != null ? !first.equals(tuple2.first) : tuple2.first != null) return false; if (second != null ? !second.equals(tuple2.second) : tuple2.second != null) return false; return true; } @Override public int hashCode() { int result = first != null ? first.hashCode() : 0; result = 31 * result + (second != null ? second.hashCode() : 0); return result; } public static Pair of(E1 first, E2 second) { return new Pair(first, second); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/ReflectionUtil.java000066400000000000000000000144631202022523300314210ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.beans.Introspector; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.*; public abstract class ReflectionUtil { public static Class loadClassIfAvailable(String className) { try { return ReflectionUtil.class.getClassLoader().loadClass(className); } catch (ClassNotFoundException e) { return null; } } public static boolean isClassAvailable(String className) { return loadClassIfAvailable(className) != null; } public static boolean isMethodAvailable(String className, String methodName) { try { Class clazz = ReflectionUtil.class.getClassLoader().loadClass(className); return getMethodByName(clazz, methodName) != null; } catch (ClassNotFoundException e) { return false; } } public static boolean isAnnotationPresent(AnnotatedElement element, String className) { for (Annotation ann : element.getAnnotations()) if (ann.annotationType().getName().equals(className)) return true; return false; } /** * Finds a public method with the given name declared in the given * class/interface or one of its super classes/interfaces. If multiple such * methods exists, it is undefined which one is returned. */ public static @Nullable Method getMethodByName(Class clazz, String name) { for (Method method : clazz.getMethods()) if (method.getName().equals(name)) return method; return null; } public static @Nullable Method getDeclaredMethodByName(Class clazz, String name) { for (Method method : clazz.getDeclaredMethods()) if (method.getName().equals(name)) return method; return null; } public static @Nullable Method getMethodBySignature(Class clazz, String name, Class... parameterTypes) { try { return clazz.getMethod(name, parameterTypes); } catch (NoSuchMethodException e) { return null; } } public static @Nullable Method getDeclaredMethodBySignature(Class clazz, String name, Class... parameterTypes) { try { return clazz.getDeclaredMethod(name, parameterTypes); } catch (NoSuchMethodException e) { return null; } } /** * Returns the class file for the given class (which has been verified to exist in the returned location), * or null if the class file could not be found (e.g. because it is contained in a Jar). */ public static File getClassFile(Class clazz) { File dir = new File(clazz.getProtectionDomain().getCodeSource().getLocation().getPath()); if (!dir.isDirectory()) return null; // class file might be contained in Jar File clazzFile = new File(dir, clazz.getName().replace('.', File.separatorChar) + ".class"); return clazzFile.isFile() ? clazzFile : null; } /** * Returns the contents of the file in which the given class is declared, * or null if the file cannot be found; */ public static String getSourceCode(String packageName, String filename) throws IOException { String resourceName = packageName.replace('.', '/') + "/" + filename; InputStream stream = ReflectionUtil.class.getClassLoader().getResourceAsStream(resourceName); return stream == null ? null : IoUtil.getText(stream); } public static Object getDefaultValue(Class type) { if (!type.isPrimitive()) return null; if (type == boolean.class) return false; if (type == int.class) return 0; if (type == long.class) return 0l; if (type == float.class) return 0f; if (type == double.class) return 0d; if (type == char.class) return (char)0; if (type == short.class) return (short)0; if (type == byte.class) return (byte)0; assert type == void.class; return null; } /** * Checks if the given method is a getter method according * to Groovy rules. If yes, the corresponding property name * is returned. Otherwise, null is returned. * This method differs from Groovy 1.6.8 in that the latter * doesn't support the "is" prefix for static boolean properties; * however, that seems more like a bug. * See http://jira.codehaus.org/browse/GROOVY-4206 */ public static @Nullable String getPropertyNameForGetterMethod(Method method) { if (method.getTypeParameters().length != 0) return null; if (method.getReturnType() == void.class) return null; // Void.class is allowed String methodName = method.getName(); if (methodName.startsWith("get")) return getPropertyName(methodName, 3); if (methodName.startsWith("is") && method.getReturnType() == boolean.class) // Boolean.class is not allowed return getPropertyName(methodName, 2); return null; } public static boolean hasAnyOfTypes(Object value, Class... types) { for (Class type : types) if (type.isInstance(value)) return true; return false; } public static Class[] getTypes(Object... objects) { Class[] classes = new Class[objects.length]; for (int i = 0; i < objects.length; i++) classes[i] = ObjectUtil.getClass(objects[i]); return classes; } private static String getPropertyName(String methodName, int prefixLength) { String result = methodName.substring(prefixLength); if (result.length() == 0) return null; return Introspector.decapitalize(result); } @Nullable public static Object invokeMethod(@Nullable Object target, Method method, @Nullable Object... args) { try { return method.invoke(target, args); } catch (IllegalAccessException e) { ExceptionUtil.sneakyThrow(e); return null; // never reached } catch (InvocationTargetException e) { ExceptionUtil.sneakyThrow(e.getCause()); return null; // never reached } } }spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/SpockReleaseInfo.java000066400000000000000000000026321202022523300316600ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; public class SpockReleaseInfo { private static final VersionNumber spockVersion = VersionNumber.parse("0.6-groovy-1.8"); private static final VersionNumber minGroovyVersion = VersionNumber.parse("1.8.0"); private static final VersionNumber maxGroovyVersion = VersionNumber.parse("1.8.99"); public static VersionNumber getVersion() { return spockVersion; } public static String getArtifactPath() { return SpockReleaseInfo.class.getProtectionDomain().getCodeSource().getLocation().toString(); } public static boolean isCompatibleGroovyVersion(VersionNumber groovyVersion) { if (groovyVersion == VersionNumber.UNKNOWN) return true; return minGroovyVersion.compareTo(groovyVersion) <= 0 && maxGroovyVersion.compareTo(groovyVersion) >= 0; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/TextUtil.java000077500000000000000000000075571202022523300302640ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Arrays; import java.util.List; /** * Utility methods for text processing. * * @author Peter Niederwieser */ public abstract class TextUtil { public static String repeatChar(char ch, int times) { char[] chars = new char[times]; Arrays.fill(chars, ch); return new String(chars); } public static int getIndent(String line) { int i = 0; while (i < line.length() && Character.isWhitespace(line.charAt(i))) i++; return i; } public static int getIndent(List lines) { int result = Integer.MAX_VALUE; for (String line : lines) { int indent = getIndent(line); if (indent < result) result = indent; } return result; } public static String changeIndent(String line, int delta) { return delta > 0 ? repeatChar(' ', delta) + line : line.substring(-delta); } public static void changeIndent(List lines, int delta) { if (delta == 0) return; for (int i = 0; i < lines.size(); i++) lines.set(i, changeIndent(lines.get(i), delta)); } public static String erase(String line, int from, int to) { return line.substring(0, from) + repeatChar(' ', to - from) + line.substring(to); } public static String erase(String line, int from) { return erase(line, from, line.length()); } /** * Returns the number of whitespace characters at the end of the given line. * * @param line * @return */ public static int getTrailingWhitespace(String line) { return line.length() - line.trim().length() - getIndent(line); } public static String join(String separator, List objects) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < objects.size(); i++) { builder.append(objects.get(i)); if (i != objects.size() - 1) builder.append(separator); } return builder.toString(); } public static String join(String separator, Object... objects) { return join(separator, Arrays.asList(objects)); } public static int countOccurrences(String text, char symbol) { int result = 0; for (char ch : text.toCharArray()) if (ch == symbol) result++; return result; } public static String escape(char ch) { if (ch == '\\') return "\\\\"; if (ch == '\t') return "\\t"; if (ch == '\n') return "\\n"; if (ch == '\b') return "\\b"; if (ch == '\r') return "\\r"; if (ch == '\f') return "\\f"; return String.valueOf(ch); } public static String escape(CharSequence seq) { StringBuilder builder = new StringBuilder(seq.length() * 3 / 2); for (int i = 0; i < seq.length(); i++) builder.append(escape(seq.charAt(i))); return builder.toString(); } public static String printStackTrace(Throwable throwable) { StringWriter writer = new StringWriter(); throwable.printStackTrace(new PrintWriter(writer)); return writer.toString(); } // taken from: // http://stackoverflow.com/questions/1660501/what-is-a-good-64bit-hash-function-in-java-for-textual-strings public static long longHashCode(String string) { long h = 1125899906842597L; int len = string.length(); for (int i = 0; i < len; i++) { h = 31 * h + string.charAt(i); } return h; } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/ThreadSafe.java000066400000000000000000000014001202022523300304620ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface ThreadSafe {}spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/UnreachableCodeError.java000066400000000000000000000021301202022523300324730ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; /** * * @author Peter Niederwieser */ public class UnreachableCodeError extends InternalSpockError { public UnreachableCodeError() { this("You shouldn't be here...fascinating", null); } public UnreachableCodeError(String msg) { this(msg, null); } public UnreachableCodeError(Throwable t) { this("You shouldn't be here...fascinating", t); } public UnreachableCodeError(String msg, Throwable cause) { super(msg, cause); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/VersionChecker.java000066400000000000000000000025001202022523300313700ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; public class VersionChecker { private static final boolean compatibleGroovyVersion = SpockReleaseInfo.isCompatibleGroovyVersion(GroovyReleaseInfo.getVersion()); public static void checkGroovyVersion(String whoIsChecking) { if (!compatibleGroovyVersion) throw new IncompatibleGroovyVersionException(String.format( "The Spock %s cannot execute because Spock %s is not compatible with Groovy %s. For more information, see http://versioninfo.spockframework.org\n" + "Spock location: %s\n" + "Groovy location: %s", whoIsChecking, SpockReleaseInfo.getVersion(), GroovyReleaseInfo.getVersion(), SpockReleaseInfo.getArtifactPath(), GroovyReleaseInfo.getArtifactPath())); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/VersionNumber.java000066400000000000000000000055321202022523300312640ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * A version number with format major.minor.micro-qualifier. */ @Immutable public final class VersionNumber implements Comparable { public static final VersionNumber UNKNOWN = new VersionNumber(0, 0, 0, null); private static final Pattern versionPattern = Pattern.compile("(\\d+)(?:\\.(\\d+))?+(?:\\.(\\d+))?+(?:[-\\.](.+))?"); private static final String versionTemplate = "%d.%d.%d%s"; private final int major; private final int minor; private final int micro; private final String qualifier; public VersionNumber(int major, int minor, int micro, @Nullable String qualifier) { this.major = major; this.minor = minor; this.micro = micro; this.qualifier = qualifier; } public int getMajor() { return major; } public int getMinor() { return minor; } public int getMicro() { return micro; } public String getQualifier() { return qualifier; } public int compareTo(VersionNumber other) { if (major != other.major) return major - other.major; if (minor != other.minor) return minor - other.minor; if (micro != other.micro) return micro - other.micro; return ObjectUtil.compare(qualifier, other.qualifier); } public boolean equals(Object other) { return other instanceof VersionNumber && compareTo((VersionNumber)other) == 0; } public int hashCode() { int result = major; result = 31 * result + minor; result = 31 * result + micro; result = 31 * result + ObjectUtil.hashCode(qualifier); return result; } public String toString() { return String.format(versionTemplate, major, minor, micro, qualifier == null ? "" : "-" + qualifier); } public static VersionNumber parse(String versionString) { if (versionString == null) return UNKNOWN; Matcher m = versionPattern.matcher(versionString); if (!m.matches()) return UNKNOWN; int major = Integer.valueOf(m.group(1)); String minorString = m.group(2); int minor = minorString == null ? 0 : Integer.valueOf(minorString); String microString = m.group(3); int micro = microString == null ? 0 : Integer.valueOf(microString); String qualifier = m.group(4); return new VersionNumber(major, minor, micro, qualifier); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/WrappedException.java000066400000000000000000000017461202022523300317520ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util; /** * Wraps a checked exception s.t. it can be thrown from a method that doesn't * declare to throw it. * * @author Peter Niederwieser */ public class WrappedException extends RuntimeException { public WrappedException(Throwable cause) { super(cause); } public WrappedException(String msg, Throwable cause) { super(msg, cause); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/inspector/000077500000000000000000000000001202022523300276245ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/inspector/AstInspector.java000077500000000000000000000420141202022523300331110ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util.inspector; import java.io.*; import java.security.CodeSource; import java.util.*; import org.codehaus.groovy.ast.*; import org.codehaus.groovy.ast.expr.*; import org.codehaus.groovy.ast.stmt.*; import org.codehaus.groovy.control.*; import groovy.lang.GroovyClassLoader; /** * Utility class for inspecting the abstract syntax tree (AST) produced by * the Groovy compiler. Provides convenient ways to directly access AST nodes * without having to navigate the AST from its root. * *

Nodes representing class/method/property/field declarations are most easily * accessed by name. In the case of ambiguity the first node found is returned. * Another, more fine-grained but slightly invasive way to access declarations * is to annotate them with @Inspect. * *

Individual statements and expressions can be accessed by prepending them * with a label, or by wrapping them in an "inspect_" method call. See * AstInspectorTest for examples. * *

Code example: *

 * def inspector = new AstInspector(CompilePhase.SEMANTIC_ANALYSIS)
 * inspector.load("def foo() { label: println 'hi!' }")
 * def expr = inspector.getExpression("label")
 * assert expr instanceof MethodCallExpression
 * 
markedNodes = new HashMap(); private final Map classes = new HashMap(); private final Map fields = new HashMap(); private final Map properties = new HashMap(); private final Map constructors = new HashMap(); private final Map methods = new HashMap(); private final Map statements = new HashMap(); private final Map expressions = new HashMap(); /** * Constructs an AstInspector, configuring the GroovyClassLoader used * underneath with default values. */ public AstInspector() { classLoader = new MyClassLoader(AstInspector.class.getClassLoader(), null); } /** * Convenience constructor that calls the default constructor and * additionally sets the specified compile phase. * * @see #setCompilePhase * @param phase the compile phase up to which compilation should proceed */ public AstInspector(CompilePhase phase) { this(); setCompilePhase(phase); } /** * Constructs an AstInspector, configuring the GroovyClassLoader used * underneath with the specified parent class loader and compiler configuration. * * @param parent the parent class loader for the GroovyClassLoader used underneath * @param config the compiler configuration for the GroovyClassLoader used underneath */ public AstInspector(ClassLoader parent, CompilerConfiguration config) { classLoader = new MyClassLoader(parent, config); } /** * Sets the compile phase up to which compilation should proceed. Defaults to * CompilePhase.CONVERSION (the phase in which the AST is first constructed). * * @param phase the compile phase up to which compilation should proceed * @throws IllegalArgumentException if a compile phase before * CompilePhase.CONVERSION is specified */ public void setCompilePhase(CompilePhase phase) { if (phase.getPhaseNumber() < CompilePhase.CONVERSION.getPhaseNumber()) throw new IllegalArgumentException("AST is only available from phase CONVERSION onwards"); compilePhase = phase; } /** * Controls whether to throw an AstInspectorException or to return null * when a getXXX() method cannot find a matching AST node. Defaults to true. * * @param flag true if an exception should be thrown, * false otherwise */ public void setThrowOnNodeNotFound(boolean flag) { throwOnNodeNotFound = flag; } /** * Compiles the specified source text up to the configured compile * phase and stores the resulting AST for subsequent inspection. * * @param sourceText the source text to compile * @throws CompilationFailedException if an error occurrs during compilation */ public void load(String sourceText) throws CompilationFailedException { reset(); try { classLoader.parseClass(sourceText); } catch (AstSuccessfullyCaptured e) { indexAstNodes(); return; } throw new AstInspectorException("internal error"); } /** * Compiles the source text in the specified file up to the * configured compile phase and stores the resulting AST for subsequent * inspection. * * @param sourceFile the file containing the source text to compile * @throws CompilationFailedException if an error occurs during compilation * @throws AstInspectorException if an IOException occurs when reading from * the file */ public void load(File sourceFile) throws CompilationFailedException { reset(); try { classLoader.parseClass(sourceFile); } catch (IOException e) { throw new AstInspectorException("cannot read source file", e); } catch (AstSuccessfullyCaptured e) { indexAstNodes(); return; } throw new AstInspectorException("internal error"); } /** * Returns the root of the inspected AST. * * @return the root of the inspected AST */ public ModuleNode getModule() { return module; } /** * Returns the first declaration found that * is marked with an @Inspect annotation with the specified name. * * @param name the name specified in the @Inspect annotation marking * the declaration of interest * @return the first declaration found that is marked with an @Inspect * annotation with the specified name */ public AnnotatedNode getMarkedNode(String name) { return getNode(markedNodes, name); } /** * Returns the first class found with the specified * simple name. * * @param name the simple name of the class of interest * @return the first class found with the specified simple name */ public ClassNode getClass(String name) { return getNode(classes, name); } /** * Returns the first field found with the specified name. * * @param name the name of the field of interest * @return the first field found with the specified name */ public FieldNode getField(String name) { return getNode(fields, name); } /** * Returns the first property found with the specified name. * * @param name the name of the property of interest * @return the first property found with the specified name */ public PropertyNode getProperty(String name) { return getNode(properties, name); } /** * Returns the first constructor found in the class with the specified simple name. * * @param className the simple name of the class declaring the constructor of * interest * @return the first constructor found in the class with the specified simple name */ public ConstructorNode getConstructor(String className) { return getNode(constructors, className); } /** * Returns the first method found with the specified name (including both * script and class methods). * * @param name the name of the method of interest * @return the first method found with the specified name */ public MethodNode getMethod(String name) { return getNode(methods, name); } /** * Returns the top-level statements in a script. If no such statements are * found, an empty list is returned. * * @return the top-level statements in a script */ public List getScriptStatements() { return getStatements(module.getStatementBlock()); } /** * Returns the top-level expressions in a script. If no such expressions are * found, an empty list is returned. * * @return the top-level expressions in a script */ public List getScriptExpressions() { return getExpressions(getScriptStatements()); } /** * Returns the top-level statements in the specified method or constructor. * If no such statements are found, an empty * list is returned. * * @param node a MethodNode representing a method or constructor * @return the top-level statements in the specified method or constructor */ public List getStatements(MethodNode node) { return getStatements((BlockStatement)node.getCode()); } /** * Returns the top-level expressions in the specified method or constructor. * If no such expressions are found, an empty list is returned. * * @param node a MethodNode representing a method or constructor * @return the top-level expressions in the specified method or constructor */ public List getExpressions(MethodNode node) { return getExpressions(getStatements(node)); } /** * Returns the top-level statements in the specified closure definition. * If no such statements are found, an empty list is returned. * * @param expr a ClosureExpression representing a closure defintion * @return the top-level statements in the specified closure definition */ public List getStatements(ClosureExpression expr) { return getStatements((BlockStatement)expr.getCode()); } /** * Returns the top-level expressions in the specified closure definition. * If no such expressions are found, an empty list is returned. * * @param expr a ClosureExpression representing a closure definition * @return the top-level expressions in the specified closure definition */ public List getExpressions(ClosureExpression expr) { return getExpressions(getStatements(expr)); } /** * Returns the first statement found immediately preceded by a label with the * specified name. * * @param name the name of the label immediately preceding the statement of * interest * @return the first statement found immediately preceded by a label with the * specified name */ public Statement getStatement(String name) { return getNode(statements, name); } /** * Returns the first expression found that is * either immediately preceded by a label with the specified name, or is the * single argument in a method call of the form "inspect_name(expression)". * *

Example: *

   * def inspector = new AstInspector()
   * inspector.load("fooBar: foo.bar(inspect_firstArg(a), b)")
   * def fooBar = inspector.getExpression("fooBar")
   * def firstArg = inspector.getExpression("firstArg")
   * 
* * @param name the name of a label immediately preceding the expression of * interest, or NAME in a method call "inspect_NAME" wrapping the expression * of interest * @return the Expression representing the first matching expression */ public Expression getExpression(String name) { return getNode(expressions, name); } @SuppressWarnings("unchecked") private void indexAstNodes() { visitor.visitBlockStatement(module.getStatementBlock()); for (MethodNode method : module.getMethods()) visitor.visitMethod(method); for (ClassNode clazz : module.getClasses()) visitor.visitClass(clazz); } private void reset() { module = null; markedNodes.clear(); classes.clear(); fields.clear(); properties.clear(); constructors.clear(); methods.clear(); statements.clear(); expressions.clear(); } private void addNode(Map map, String name, T node) { if (!map.containsKey(name)) map.put(name, node); } private T getNode(Map nodes, String key) { T node = nodes.get(key); if (node == null && throwOnNodeNotFound) throw new AstInspectorException( String.format("cannot find a node named '%s' of the requested kind", key)); return node; } @SuppressWarnings("unchecked") private static List getStatements(BlockStatement blockStat) { return blockStat == null ? Collections. emptyList() : blockStat.getStatements(); } private static List getExpressions(List statements) { List exprs = new ArrayList(); for (Statement stat : statements) if (stat instanceof ExpressionStatement) exprs.add(((ExpressionStatement)stat).getExpression()); return exprs; } private class MyClassLoader extends GroovyClassLoader { MyClassLoader(ClassLoader parent, CompilerConfiguration config) { super(parent, config); } @Override protected CompilationUnit createCompilationUnit(CompilerConfiguration config, CodeSource source) { CompilationUnit unit = super.createCompilationUnit(config, source); unit.addPhaseOperation(new CompilationUnit.SourceUnitOperation() { @Override public void call(SourceUnit source) throws CompilationFailedException { module = source.getAST(); throw new AstSuccessfullyCaptured(); } }, compilePhase.getPhaseNumber()); return unit; } } private class MyVisitor extends ClassCodeVisitorSupport { @Override @SuppressWarnings("unchecked") public void visitAnnotations(AnnotatedNode node) { for (AnnotationNode an : node.getAnnotations()) { ClassNode cn = an.getClassNode(); // this comparison should be good enough, and also works in phase conversion if (cn.getNameWithoutPackage().equals(Inspect.class.getSimpleName())) { ConstantExpression name = (ConstantExpression)an.getMember("value"); if (name == null || !(name.getValue() instanceof String)) throw new AstInspectorException("@Inspect must have a String argument"); addNode(markedNodes, (String)name.getValue(), node); break; } } super.visitAnnotations(node); } @Override public void visitClass(ClassNode node) { addNode(classes, node.getNameWithoutPackage(), node); super.visitClass(node); } @Override public void visitField(FieldNode node) { addNode(fields, node.getName(), node); super.visitField(node); } @Override public void visitProperty(PropertyNode node) { addNode(properties, node.getName(), node); super.visitProperty(node); } @Override protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { // ClassCodeVisitorSupport doesn't seem to visit parameters for (Parameter param: node.getParameters()) { visitAnnotations(param); if (param.getInitialExpression() != null) param.getInitialExpression().visit(this); } super.visitConstructorOrMethod(node, isConstructor); } @Override public void visitConstructor(ConstructorNode node) { addNode(constructors, node.getDeclaringClass().getNameWithoutPackage(), node); super.visitConstructor(node); } @Override public void visitMethod(MethodNode node) { addNode(methods, node.getName(), node); super.visitMethod(node); } @Override public void visitStatement(Statement node) { if (node.getStatementLabel() != null) { addNode(statements, node.getStatementLabel(), node); if (node instanceof ExpressionStatement) addNode(expressions, node.getStatementLabel(), ((ExpressionStatement)node).getExpression()); } super.visitStatement(node); } @Override public void visitMethodCallExpression(MethodCallExpression node) { if (node.isImplicitThis()) { String methodName = node.getMethodAsString(); if (methodName != null && methodName.startsWith(EXPRESSION_MARKER_PREFIX)) { ArgumentListExpression args = (ArgumentListExpression)node.getArguments(); if (args != null && args.getExpressions().size() == 1) addNode(expressions, methodName.substring(EXPRESSION_MARKER_PREFIX.length()), args.getExpressions().get(0)); } } super.visitMethodCallExpression(node); } @Override protected SourceUnit getSourceUnit() { throw new AstInspectorException("internal error"); } } private static class AstSuccessfullyCaptured extends Error {} } AstInspectorException.java000077500000000000000000000022171202022523300347120ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/inspector/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util.inspector; /** * Unchecked exception thrown by AstInspector when: *
    *
  • an IOException occurs when loading a file
  • *
  • a declaration with the specified name cannot be found
  • *
  • an internal error occurs
  • *
* * @author Peter Niederwieser (pniederw@gmail.com) */ public class AstInspectorException extends RuntimeException { public AstInspectorException(String msg) { super(msg); } public AstInspectorException(String msg, Exception cause) { super(msg, cause); } } spock-0.6-groovy-1.8/spock-core/src/main/java/org/spockframework/util/inspector/Inspect.java000077500000000000000000000020131202022523300320730ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util.inspector; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Marks a declaration in Groovy code so that it can be easily accessed using * AstInspector. * * @author Peter Niederwieser (pniederw@gmail.com) */ @Retention(RetentionPolicy.SOURCE) public @interface Inspect { /** * The name of the inspection mark. */ String value(); } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/000077500000000000000000000000001202022523300221345ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/spock/config/000077500000000000000000000000001202022523300234015ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/spock/config/ConfigurationException.java000066400000000000000000000020221202022523300307260ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.config; /** * Thrown to indicate that there is a problem with Spock's configuration (file). * * @author Peter Niederwieser */ public class ConfigurationException extends RuntimeException { public ConfigurationException(String msg, Object... args) { super(String.format(msg, args)); } public ConfigurationException(String msg, Throwable t, Object... args) { super(String.format(msg, args), t); } } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/config/IncludeExcludeCriteria.java000066400000000000000000000031021202022523300306200ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.config; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; /** * Configuration indicating which specs and methods should be * included/excluded from a spec run. Specs can be included/excluded * based on their annotations and their (base) classes. Methods * can be included/excluded based on their annotations. * * @author Peter Niederwieser */ public class IncludeExcludeCriteria { @SuppressWarnings("unchecked") public IncludeExcludeCriteria(Class... criteria) { for (Class criterium : criteria) if (criterium.isAnnotation()) annotations.add((Class)criterium); else baseClasses.add(criterium); } public List> annotations = new ArrayList>(); public List> baseClasses = new ArrayList>(); public boolean isEmpty() { return annotations.isEmpty() && baseClasses.isEmpty(); } } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/config/RunnerConfiguration.java000066400000000000000000000023741202022523300302530ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.config; /** * Configuration settings for the spec runner. * *

Example: *

 * import some.pkg.Fast
 * import some.pkg.IntegrationSpec
 *
 * runner {
 *   include Fast // could be either an annotation or a (base) class
 *   exclude {
 *     annotation some.pkg.Slow
 *     baseClass IntegrationSpec
 *   }
 *   filterStackTrace true // this is the default
 * }
 * 
*/ public class RunnerConfiguration { public IncludeExcludeCriteria include = new IncludeExcludeCriteria(); public IncludeExcludeCriteria exclude = new IncludeExcludeCriteria(); public boolean filterStackTrace = true; public boolean optimizeRunOrder = false; } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/config/package-info.java000066400000000000000000000012621202022523300265710ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Classes modeling Spock's configuration options. */ package spock.config;spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/000077500000000000000000000000001202022523300230555ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/AutoCleanup.java000066400000000000000000000051461202022523300261460ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.*; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.runtime.extension.builtin.AutoCleanupExtension; /** * Automatically cleans up the object stored in the annotated field or property * at the end of its life time. More precisely, auto-cleanup of an object has * the same effect as, and serves as a convenient replacement for, calling the * object's close method at the end of the spec's cleanup method. * @Shared objects are cleaned up at the end of the spec's * cleanupSpec method. *

Customizing how cleanup is performed

* By default, an object is cleaned up by invoking its parameterless close() * method (which is assumed to exist); visibility and return type of this method * are irrelevant. If some other method should be called instead, override the * annotation's value attribute: * *
 * @AutoCleanup("dispose") // invoke the object's "dispose" method
 * 
Cleaning up multiple objects * If multiple fields or properties are annotated with @AutoCleanup, * their objects are cleaned up sequentially in reverse field/property declaration * order, starting from the most derived class and walking up the inheritance chain. * *

Handling of exceptions during cleanup

* If a cleanup operation fails with an exception, the exception is reported * (just as if it had occurred in a cleanup or cleanupSpec * method) and cleanup proceeds with the next annotated object. To prevent * cleanup exceptions from being reported, override the annotation's quiet * attribute: * *
 * @AutoCleanup(quiet = true) // don't report exceptions
 * 
Applying this annotation to a specification has the same effect as applying it * to all feature methods that aren't already annotated with @FailsWith. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @ExtensionAnnotation(FailsWithExtension.class) public @interface FailsWith { /** * The expected exception type. * * @return the expected exception type */ Class value(); /** * The reason for the failure. * * @return the reason for the failure */ String reason() default "unknown"; } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/Ignore.java000077500000000000000000000022741202022523300251530ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.*; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.runtime.extension.builtin.IgnoreExtension; /** * Indicates that a specification or feature method should not be run. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @ExtensionAnnotation(IgnoreExtension.class) public @interface Ignore { /** * The reason for ignoring this element. * * @return the reason for ignoring this element */ String value() default ""; } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/IgnoreIf.java000066400000000000000000000023251202022523300254240ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.runtime.extension.builtin.IgnoreIfExtension; import groovy.lang.Closure; /** * Ignores the annotated spec/feature if the given condition holds. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @ExtensionAnnotation(IgnoreIfExtension.class) public @interface IgnoreIf { Class value(); } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/IgnoreRest.java000066400000000000000000000021051202022523300257770ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.*; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.runtime.extension.builtin.IgnoreRestExtension; /** * Indicates that all feature methods except the ones carrying this annotation * should be ignored. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @ExtensionAnnotation(IgnoreRestExtension.class) public @interface IgnoreRest {}spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/Issue.java000066400000000000000000000021401202022523300250050ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.*; /** * Indicates that a feature method or specification relates to one or more * issues in an external issue tracking system. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface Issue { /** * The IDs of the issues that the annotated element relates to. * * @return the IDs of the issues that the annotated element relates to */ String[] value(); } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/See.java000066400000000000000000000021171202022523300244350ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.*; /** * One or more references to external information related to a specification or feature. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.SOURCE) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface See { /** * References to external information related to a specification or feature. * * @return references to external information related to a specification or feature */ String[] value(); }spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/Shared.java000077500000000000000000000021301202022523300251250ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.*; /** * Indicates that a field is shared among all feature methods in a * specification. Initializing a shared field at the point of declaration * is encouraged; semantically, this is equivalent to initializing the field at * the very beginning of the setupSpec() method. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Shared {} spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/Specification.java000066400000000000000000000204641202022523300265060ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import org.junit.runner.RunWith; import org.spockframework.lang.Wildcard; import org.spockframework.mock.MockController; import org.spockframework.runtime.*; import org.spockframework.util.GroovyRuntimeUtil; import groovy.lang.Closure; /** * Base class for Spock specifications. All specifications must inherit from * this class, either directly or indirectly. * * @author Peter Niederwieser */ // NOTE: if method implementations are declared private instead of package private, // they are no longer visible to Specs that extend spock.lang.Specification // (runtime dispatch fails) @RunWith(Sputnik.class) public abstract class Specification { /** * The wildcard symbol. Used in several places as a don't care value: *
    *
  • Mock interactions
  • * Example: 1 * foo.bar(_) *
  • Data parameterizations
  • * Example: [foo, _] << loadDataFromDb() *
*/ public static final Object _ = Wildcard.INSTANCE; /** * Specifies that the preceding when block should throw an exception. * May only occur as the initializer expression of a typed variable declaration * in a then block; the expected exception type is inferred from the * variable type. *

This form of exception condition is typically used if the thrown * exception instance is used in subsequent conditions. * *

Example: *

   * when:
   * "".charAt(0)
   *
   * then:
   * IndexOutOfBoundsException e = thrown()
   * e.message.contains(...)
   * 
* * @return the thrown exception instance */ public T thrown() { throw new InvalidSpecException( "Exception conditions are only allowed in 'then' blocks, and may not be nested inside other elements"); } /** * Specifies that the preceding when block should throw an exception * of the given type. May only occur in a then block. *

This form of exception condition is typically used if the thrown * exception instance is not used in subsequent conditions. * *

Example: *

   * when:
   * "".charAt(0)
   *
   * then:
   * thrown(IndexOutOfBoundsException)
   *
   * @param type the expected exception type
   * @param  the expected exception type
   * @return the thrown exception instance
   */
  @SuppressWarnings("UnusedDeclaration")
  public  T thrown(Class type) {
    throw new InvalidSpecException(
        "Exception conditions are only allowed in 'then' blocks, and may not be nested inside other elements");
  }

  /**
   * Specifies that in particular, no exception of the given type should be
   * thrown. This method has only documentation purposes and does not affect
   * the execution of the specification.
   *
   * @param type an exception type
   */
  @SuppressWarnings("UnusedDeclaration")
  public void notThrown(Class type) {
    // IDEA: provide an implementation that makes it possible to differentiate
    // between this exception being thrown, and any other exception being thrown
  }

  /**
   * Specifies that no exception should be thrown. Equivalent to
   * notThrown(Throwable). This method has only documentation purposes
   * and does not affect the execution of the specification.
   */
  @SuppressWarnings("UnusedDeclaration")
  public void noExceptionThrown() { /* nothing to do */ }

  /**
   * Creates a mock object whose name and type are inferred from the variable
   * that the mock object is assigned to. For example,
   * IOrderService service = Mock() will create a mock object named
   * "service" and of type IOrderService.
   *
   * @return the new mock object
   */
  public Object Mock() {
    throw new InvalidSpecException("Mock objects may only be created during the lifetime of a feature (iteration)");
  }

  /**
   * Creates a mock object of the given type. If this method is used
   * to initialize a new variable, the mock's name is inferred from the
   * variable's name. For example, def service = Mock(IOrderService)
   * will create a mock object named "service" and of type
   * IOrderService. Otherwise, the mock will be named after
   * its type (e.g. "IOrderService").
   *
   * @param type the type of the mock object to be created
   * @param  the type of the mock object to be created
   * @return the new mock object
   */
  @SuppressWarnings("UnusedDeclaration")
  public  T Mock(Class type) {
    throw new InvalidSpecException("Mock objects can only be created inside a Spec");
  }

  /**
   * Encloses one or more interaction definitions in a then block.
   * Required when an interaction definition uses a statement that doesn't
   * match one of the following patterns, and therefore isn't automatically
   * recognized as belonging to an interaction definition:
   * 
    *
  • num * target.method(args)
  • *
  • target.method(args) >>(>) result(s)
  • *
  • num * target.method(args) >>(>) result(s)
  • *
* *

Regular interaction definition: *

   * def "published messages are received at least once"() {
   *   when:
   *   publisher.send(msg)
   *
   *   then:
   *   (1.._) * subscriber.receive(msg)
   * }
   * 
* *

Equivalent definition that uses a helper variable: *

   * def "published messages are received at least once"() {
   *   when:
   *   publisher.send(msg)
   *
   *   then:
   *   interaction {
   *     def num = (1.._)
   *     num * subscriber.receive(msg)
   *   }
   * }
   * 
* *

Equivalent definition that uses a helper method: *

   * def "published messages are received at least once"() {
   *   when:
   *   publisher.send(msg)
   *
   *   then:
   *   interaction {
   *     messageReceived(msg)
   *   }
   * }
   *
   * def messageReceived(msg) {
   *   (1.._) * subscriber.receive(msg)
   * }
   * 
* * @param block a block of code containing one or more interaction definitions */ public void interaction(Closure block) { GroovyRuntimeUtil.invokeClosure(block); } /** * Used in a then-block to access an expression's value at the time just * before the previous where-block was entered. * * @param expression an arbitrary expression, except that it may not * reference variables defined in the then-block * @param the expression's type * @return the expression's value at the time the previous where-block was * entered */ @SuppressWarnings("UnusedDeclaration") public T old(T expression) { throw new InvalidSpecException("old() can only be used in a 'then' block"); } @SuppressWarnings("UnusedDeclaration") T thrown(Class type, String name, Throwable exception) { if (!Throwable.class.isAssignableFrom(type)) throw new InvalidSpecException( "Invalid exception condition: '%s' is not a (subclass of) java.lang.Throwable" ).withArgs(type.getSimpleName()); if (type.isInstance(exception)) return type.cast(exception); throw new WrongExceptionThrownError(type, exception); } @SuppressWarnings("UnusedDeclaration") T Mock(Class type, String name, MockController controller) { if (type == null) throw new InvalidSpecException("Mock object type may not be 'null'"); if (controller == null) { // mock has been created in a context where no controller exists Mock(); return null; // unreachable; just exists to avoid compiler warning } return type.cast(controller.create(name, type)); } // dummy parameter exists just to create a new overload of old() with different implementation @SuppressWarnings("UnusedDeclaration") T old(T expression, boolean dummy) { return expression; } } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/Stepwise.java000066400000000000000000000030071202022523300255230ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.*; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.runtime.extension.builtin.StepwiseExtension; /** * Indicates that a spec's feature methods should be run sequentially * in their declared order (even in the presence of a parallel spec runner), * always starting from the first method. If a method fails, the remaining * methods will be skipped. Feature methods declared in super- and subspecs * are not affected. * *

@Stepwise is useful for specs with * (logical) dependencies between methods. In particular, it helps to avoid * consecutive errors after a method has failed, which makes it easier to * understand what really went wrong. * * @author Peter Niederwieser */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @ExtensionAnnotation(StepwiseExtension.class) public @interface Stepwise {} spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/Subject.java000066400000000000000000000026421202022523300253230ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.*; /** * Indicates which objects/classes are the subjects of a specification. If applied * to a field, indicates that the field holds the subject of the specification. * If applied to a class, indicates that the classes listed as annotation * arguments are the subjects of the specification. Currently, this annotation * has only informational purposes. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.FIELD, ElementType.LOCAL_VARIABLE}) public @interface Subject { /** * The classes which are the subjects of the specification. Irrelevant if the * annotation is applied to a field. * * @return the classes which are the subjects of the specification */ Class[] value() default Void.class; }spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/Timeout.java000077500000000000000000000047151202022523300253600ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.lang; import java.lang.annotation.*; import java.util.concurrent.TimeUnit; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.runtime.extension.builtin.TimeoutExtension; /** * Indicates that the execution of a method should time out * after the given duration has elapsed. The default time unit is seconds. * *

Timeouts can be applied to feature methods, fixture methods, and spec classes. * When applied to a feature method, the timeout is per execution of one iteration, * and does not include time spent in fixture methods. When applied to a fixture * method, the timeout is per execution of the fixture method. Applying the timeout * to a spec class has the same effect as applying it to each feature (but not fixture) * method that isn't already annotated with {@code Timeout}. * *

Timed methods are invoked on the regular test framework thread. This can be * important for integration tests that hold thread-local state. When a method * times out, it will be interrupted repeatedly until it (hopefully) returns. * Methods that continue to ignore interruption may run forever. * *

When a timeout is reported to the user, the stack trace shown reflects the * execution stack of the test framework thread when the timeout was reached. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @ExtensionAnnotation(TimeoutExtension.class) public @interface Timeout { /** * The duration after which the execution of the annotated feature or fixture * method times out. * * @return the duration after which the execution of the annotated feature or * fixture method times out */ int value(); /** * The duration's time unit * * @return the duration's time unit */ TimeUnit unit() default TimeUnit.SECONDS; } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/Unroll.java000066400000000000000000000030131202022523300251700ustar00rootroot00000000000000package spock.lang; import java.lang.annotation.*; import groovy.lang.Closure; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.runtime.extension.builtin.UnrollExtension; /** * Indicates that iterations of a data-driven feature should be made visible * as separate features to the outside world (IDEs, reports, etc.). By default, * the name of an iteration is the feature's name followed by a consecutive number. * This can be changed by providing a naming pattern after @Unroll. A naming pattern * may refer to data variables by prepending their names with #. Example: * *

 * @Unroll("#name should have length #length")
 * def "name length"() {
 *   expect:
 *   name.size() == length
 *
 *   where:
 *   name << ["Kirk", "Spock", "Scotty"]
 *   length << [4, 5, 6]
 * }
 * 
* * Alternatively, the naming pattern can also be embedded in the method name: * *
 * @Unroll
 * def "#name should have length #length"() {
 *   ...
 * }
 * 
* * The {@code Unroll} annotation can also be put on a spec class. This has the same * effect as putting it on every data-driven feature method that is not already * annotated with {@code Unroll}. By embedding the naming pattern in the method * names, each method can still have its own pattern. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @ExtensionAnnotation(UnrollExtension.class) public @interface Unroll { String value() default ""; } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/lang/package-info.java000066400000000000000000000012471202022523300262500ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * The core specification language. */ package spock.lang;spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/000077500000000000000000000000001202022523300231115ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/concurrent/000077500000000000000000000000001202022523300252735ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/concurrent/AsyncConditions.java000066400000000000000000000110061202022523300312430ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.concurrent; import java.util.concurrent.*; import org.spockframework.runtime.SpockTimeoutError; import org.spockframework.util.ThreadSafe; /** * Alternative to class BlockingVariable(s) that allows to evaluate conditions * in a thread other than the spec runner's thread(s). Rather than transferring * state to an expect- or then-block, it is verified right where it is captured. * On the upside, this can result in a more informative stack trace if the * evaluation of a condition fails. On the downside, the coordination between * threads is more explicit (number of evaluate blocks has to be specified if * greater than one), and the usual structure of a feature method cannot be * preserved (conditions are no longer located in expect-/then-block). * *

Example: *

 * // create object under specification
 * def machine = new Machine()
 *
 * def conds = new AsyncConditions()
 *
 * // register async callback
 * machine.workDone << { result ->
 *   conds.evaluate {
 *     assert result == WorkResult.OK
 *     // could add more explicit conditions here
 *   }
 * }
 *
 * when:
 * machine.start()
 *
 * then:
 * // wait for the evaluation to complete
 * // any exception thrown in the evaluate block will be rethrown from this method
 * conds.await()
 *
 * cleanup:
 * // shut down all threads
 * machine?.shutdown()
 * 
 *
 * @author Peter Niederwieser
 */
@ThreadSafe
public class AsyncConditions {
  private final int numEvalBlocks;
  private final CountDownLatch latch;
  private final ConcurrentLinkedQueue exceptions = new ConcurrentLinkedQueue();

  /**
   * Same as AsyncConditions(1).
   */
  public AsyncConditions() {
    this(1);
  }

  /**
   * Instantiates an AsyncConditions instance with the specified number
   * of evaluate blocks. await() will block until all evaluate blocks
   * have completed or a timeout expires.
   *
   * 

Note: One evaluate block may contain multiple conditions. * * @param numEvalBlocks the number of evaluate blocks that await() * should wait for */ public AsyncConditions(int numEvalBlocks) { this.numEvalBlocks = numEvalBlocks; latch = new CountDownLatch(numEvalBlocks); } /** * Evaluates the specified block, which is expected to contain * one or more explicit conditions (i.e. assert statements). * Any caught exception will be rethrown from await(). * * @param block the code block to evaluate * @throws Throwable */ public void evaluate(Runnable block) { try { block.run(); } catch (Throwable t) { exceptions.add(t); wakeUp(); } latch.countDown(); } private void wakeUp() { // this will definitely wake us up; it doesn't matter that countDown() // might get called too often long pendingEvalBlocks = latch.getCount(); for (int i = 0; i < pendingEvalBlocks; i++) latch.countDown(); } /** * Same as await(1, TimeUnit.SECONDS). */ public void await() throws InterruptedException, Throwable { await(1, TimeUnit.SECONDS); } /** * Waits until all evaluate blocks have completed or the specified timeout * expires. If one of the evaluate blocks throws an exception, it is rethrown * from this method. * * @throws InterruptedException if the calling thread is interrupted * * @throws Throwable the first exception thrown by an evaluate block */ public void await(int timeout, TimeUnit unit) throws InterruptedException, Throwable { latch.await(timeout, unit); if (!exceptions.isEmpty()) throw exceptions.poll(); long pendingEvalBlocks = latch.getCount(); if (pendingEvalBlocks > 0) throw new SpockTimeoutError(timeout, unit, "Async conditions timed out after %d %s; %d out of %d evaluate blocks did not complete in time", timeout, unit.toString().toLowerCase(), pendingEvalBlocks, numEvalBlocks); } } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/concurrent/BlockingVariable.java000066400000000000000000000062671202022523300313470ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.concurrent; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.spockframework.runtime.SpockTimeoutError; import org.spockframework.util.ThreadSafe; /** * A statically typed variable whose get() method will block until some other * thread has set a value with the set() method, or a timeout expires. Useful * for verifying state in an expect- or then-block that has been captured in * some other thread. * *

Example: *

 * // create object under specification
 * def machine = new Machine()
 *
 * def result = new BlockingVariable<WorkResult>
 *
 * // register async callback
 * machine.workDone << { r ->
 *  result.set(r)
 * }
 *
 * when:
 * machine.start()
 *
 * then:
 * // blocks until workDone callback has set result, or a timeout expires
 * result.get() == WorkResult.OK
 *
 * cleanup:
 * // shut down all threads
 * machine?.shutdown()
 * 
* * @param the variable's type * * @author Peter Niederwieser */ @ThreadSafe public class BlockingVariable { private final int timeout; private final TimeUnit unit; private T value; // access guarded by valueReady private final CountDownLatch valueReady = new CountDownLatch(1); /** * Same as BlockingVariable(1, TimeUnit.SECONDS). */ public BlockingVariable() { this(1, TimeUnit.SECONDS); } /** * Instantiates a BlockingVariable with the specified timeout in seconds. * * @param timeout the timeout (seconds) for calls to get(). */ public BlockingVariable(int timeout) { this(timeout, TimeUnit.SECONDS); } /** * Instantiates a BlockingVariable with the specified timeout. * * @param timeout the timeout for calls to get(). * * @param unit the time unit */ public BlockingVariable(int timeout, TimeUnit unit) { this.timeout = timeout; this.unit = unit; } /** * Blocks until a value has been set for this variable, or a timeout expires. * * @return the variable's value * * @throws InterruptedException if the calling thread is interrupted */ public T get() throws InterruptedException { if (!valueReady.await(timeout, unit)) throw new SpockTimeoutError(timeout, unit, "BlockingVariable.get() timed out after %d %s", timeout, unit.toString().toLowerCase()); return value; } /** * Sets a value for this variable. Wakes up all threads blocked in get(). * * @param value the value to be set for this variable */ public void set(T value) { this.value = value; valueReady.countDown(); } }spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/concurrent/BlockingVariablesImpl.java000066400000000000000000000034271202022523300323470ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.concurrent; import java.util.concurrent.*; import org.spockframework.util.ThreadSafe; /** * Implementation underlying class BlockingVariables. Should not be * used directly. * * @author Peter Niederwieser */ @ThreadSafe class BlockingVariablesImpl { private final int timeout; private final TimeUnit unit; private final ConcurrentHashMap> map = new ConcurrentHashMap>(); public BlockingVariablesImpl(int timeout, TimeUnit unit) { this.timeout = timeout; this.unit = unit; } public Object get(String name) throws InterruptedException { BlockingVariable entry = new BlockingVariable(timeout, unit); BlockingVariable oldEntry = map.putIfAbsent(name, entry); if (oldEntry == null) return entry.get(); else return oldEntry.get(); } public void put(String name, Object value) { BlockingVariable entry = new BlockingVariable(timeout, unit); BlockingVariable oldEntry = map.putIfAbsent(name, entry); if (oldEntry == null) entry.set(value); else oldEntry.set(value); } } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/concurrent/package-info.java000066400000000000000000000012621202022523300304630ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Utilities for testing concurrent code. */ package spock.util.concurrent;spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/matcher/000077500000000000000000000000001202022523300245345ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/matcher/HamcrestSupport.java000066400000000000000000000054141202022523300305460ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.matcher; import org.hamcrest.Matcher; import org.spockframework.runtime.InvalidSpecException; public class HamcrestSupport { /** * Used to match a value against a (Hamcrest) matcher. * Only allowed in places where a condition is expected * (expect-block, then-block, after an 'assert' keyword). * *

Basic example: * *

   * import static spock.util.matcher.HamcrestSupport.that
   * import static org.hamcrest.CoreMatchers.equalTo // ships with JUnit
   *
   * def foo = 42
   *
   * expect:
   * that(foo, equalTo(42))
   * 
* * Note that Spock supports an even simpler syntax for applying matchers: * *
   * expect:
   * foo equalTo(42)
   * 
* * However, the simpler syntax cannot be used in explicit conditions * (i.e. after the 'assert' keyword), and may not be as IDE-friendly. * That's why this method is provided as an alternative. * *

When would I use matchers?

* *

Due to Spock's good diagnostic messages and Groovy's expressivity, * matchers are less often needed than when, say, writing JUnit tests * in Java. However, they come in handy when more complex conditions * are required (and possibly repeated throughout a project). * In such cases, Spock's Hamcrest integration provides the best of two worlds: * the diagnostic messages known from Spock's conditions, and the * custom failure messages of Hamcrest matchers. * *

Third-party matchers

* *

The matchers that ship with JUnit aren't very useful per se. * Instead, you will want to use matchers from Hamcrest * (http://code.google.com/p/hamcrest/) or other libraries. Both Hamcrest * 1.1 and 1.2 are supported. You can also write your own matchers, * building up a matcher library that's specific to the needs of your project. * * @param value an actual value * @param matcher a matcher describing the expected value(s) * @param the value's type */ @SuppressWarnings("UnusedDeclaration") public static void that(T value, Matcher matcher) { throw new InvalidSpecException("that() can only be used where a condition is expected"); } } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/matcher/package-info.java000066400000000000000000000013501202022523300277220ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Utilities for using (Hamcrest) matchers. */ package spock.util.matcher;spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/mop/000077500000000000000000000000001202022523300237045ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/mop/ConfineMetaClassChanges.java000066400000000000000000000035621202022523300312240ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.mop; import java.lang.annotation.*; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.runtime.extension.builtin.ConfineMetaClassChangesExtension; /** * Confines any changes made to the meta classes of the specified classes to the * annotated scope. This is done by installing new meta classes when the scope is * entered, and restoring the previously installed meta classes when the scope is * left. Note that this only works reliably as long as spec execution is * single-threaded. * *

If a spec class is annotated, the meta classes are restored to as they * were before setupSpec() was executed, after cleanupSpec * was executed. * *

If a feature method is annotated, the meta classes are restored to as they * were after setup() was executed, before cleanup() is executed. * For a data-driven feature method, meta classes are restored after each iteration. * * @author Luke Daley */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @ExtensionAnnotation(ConfineMetaClassChangesExtension.class) public @interface ConfineMetaClassChanges { /** * The classes whose meta class changes are to be confined. */ Class[] value(); } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/mop/Use.java000066400000000000000000000037451202022523300253140ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.mop; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.runtime.extension.builtin.UseExtension; /** * Activates one or more Groovy categories while the annotated spec method * or class executes. In other words, @Use(SomeCategory) * has the same effect as wrapping the execution of the annotated method or * class with use(SomeCategory) { ... }. * *

Basic example: * *

 * class ListExtensions {
 *   static avg(List list) { list.sum() / list.size() }
 * }
 *
 * class MySpec extends Specification {
 *   @Use(ListExtensions)
 *   def "can use avg() method"() {
 *     expect:
 *     [1, 2, 3].avg() == 2
 *   }
 * }
 * 
* *

One use case for this feature is the stubbing of dynamic methods which * are usually provided by the runtime environment (e.g. Grails). * *

Note: @Use has no effect when applied to a helper method. * However, when applied to a spec class it will also affect its helper methods. * * @author Peter Niederwieser */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @ExtensionAnnotation(UseExtension.class) public @interface Use { Class[] value(); } spock-0.6-groovy-1.8/spock-core/src/main/java/spock/util/mop/package-info.java000066400000000000000000000012701202022523300270730ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Utilities related to Groovy meta programming. */ package spock.util.mop;spock-0.6-groovy-1.8/spock-core/src/main/resources/000077500000000000000000000000001202022523300221065ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/resources/META-INF/000077500000000000000000000000001202022523300232465ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/resources/META-INF/services/000077500000000000000000000000001202022523300250715ustar00rootroot00000000000000org.codehaus.groovy.transform.ASTTransformation000077500000000000000000000000521202022523300362310ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/resources/META-INF/servicesorg.spockframework.compiler.SpockTransformorg.spockframework.runtime.extension.IGlobalExtension000066400000000000000000000005211202022523300374600ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-core/src/main/resources/META-INF/servicesorg.spockframework.runtime.extension.builtin.IncludeExcludeExtension org.spockframework.runtime.extension.builtin.RuleExtension org.spockframework.runtime.extension.builtin.ClassRuleExtension org.spockframework.runtime.extension.builtin.OptimizeRunOrderExtension org.spockframework.runtime.extension.builtin.JUnitFixtureMethodsExtension spock-0.6-groovy-1.8/spock-guice/000077500000000000000000000000001202022523300165255ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/guice.gradle000066400000000000000000000006201202022523300207770ustar00rootroot00000000000000apply from: script("publishMaven") displayName = "Spock Framework - Guice Module" description = "Spock's Guice Module provides support for testing Guice 2/3 based applications." dependencies { compile project(":spock-core") compile "com.google.inject:guice:3.0", provided // surfaces in the Guice API; groovyc complains if we don't add it compile "aopalliance:aopalliance:1.0", internal } spock-0.6-groovy-1.8/spock-guice/src/000077500000000000000000000000001202022523300173145ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/main/000077500000000000000000000000001202022523300202405ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/main/java/000077500000000000000000000000001202022523300211615ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/main/java/org/000077500000000000000000000000001202022523300217505ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/main/java/org/spockframework/000077500000000000000000000000001202022523300250055ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/main/java/org/spockframework/guice/000077500000000000000000000000001202022523300261015ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/main/java/org/spockframework/guice/GuiceExtension.java000066400000000000000000000030351202022523300316760ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice; import java.util.*; import com.google.inject.Module; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.SpecInfo; import spock.guice.UseModules; public class GuiceExtension extends AbstractAnnotationDrivenExtension { private final Set> moduleClasses = new HashSet>(); @Override public void visitSpecAnnotation(UseModules useModules, SpecInfo spec) { moduleClasses.addAll(Arrays.asList(useModules.value())); } @Override public void visitSpec(SpecInfo spec) { if (moduleClasses.isEmpty()) return; GuiceInterceptor interceptor = new GuiceInterceptor(spec, moduleClasses); SpecInfo topSpec = spec.getTopSpec(); topSpec.getSharedInitializerMethod().addInterceptor(interceptor); topSpec.getInitializerMethod().addInterceptor(interceptor); } } spock-0.6-groovy-1.8/spock-guice/src/main/java/org/spockframework/guice/GuiceExtensionException.java000066400000000000000000000016771202022523300335670ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice; import org.spockframework.runtime.extension.ExtensionException; public class GuiceExtensionException extends ExtensionException { public GuiceExtensionException(String message) { super(message); } public GuiceExtensionException(String message, Throwable cause) { super(message, cause); } } spock-0.6-groovy-1.8/spock-guice/src/main/java/org/spockframework/guice/GuiceInterceptor.java000066400000000000000000000063351202022523300322260ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice; import java.lang.reflect.Field; import java.util.*; import com.google.inject.*; import com.google.inject.Module; // needs to stay due to Eclipse bug import com.google.inject.spi.InjectionPoint; import org.spockframework.runtime.extension.*; import org.spockframework.runtime.model.SpecInfo; import spock.lang.Shared; /** * Creates a Guice injector, and injects Guice-provided objects into specifications. * * @author Peter Niederwieser */ // Important implementation detail: Only the fixture methods of // spec.getTopSpec() are intercepted (see GuiceExtension) public class GuiceInterceptor extends AbstractMethodInterceptor { private final Set> moduleClasses; private final Set injectionPoints; private Injector injector; public GuiceInterceptor(SpecInfo spec, Set> moduleClasses) { this.moduleClasses = moduleClasses; injectionPoints = InjectionPoint.forInstanceMethodsAndFields(spec.getReflection()); } @Override public void interceptSharedInitializerMethod(IMethodInvocation invocation) throws Throwable { createInjector(); injectValues(invocation.getTarget(), true); invocation.proceed(); } @Override public void interceptInitializerMethod(IMethodInvocation invocation) throws Throwable { injectValues(invocation.getTarget(), false); invocation.proceed(); } private void createInjector() { injector = Guice.createInjector(createModules()); } private List createModules() { List modules = new ArrayList(); for (Class clazz : moduleClasses) { try { modules.add(clazz.newInstance()); } catch (InstantiationException e) { throw new GuiceExtensionException("Failed to instantiate module '%s'", e).withArgs(clazz.getSimpleName()); } catch (IllegalAccessException e) { throw new GuiceExtensionException("Failed to instantiate module '%s'", e).withArgs(clazz.getSimpleName()); } } return modules; } private void injectValues(Object target, boolean sharedFields) throws IllegalAccessException { for (InjectionPoint point : injectionPoints) { if (!(point.getMember() instanceof Field)) throw new GuiceExtensionException("Method injection is not supported; use field injection instead"); Field field = (Field)point.getMember(); if (field.isAnnotationPresent(Shared.class) != sharedFields) continue; Object value = injector.getInstance(point.getDependencies().get(0).getKey()); field.setAccessible(true); field.set(target, value); } } }spock-0.6-groovy-1.8/spock-guice/src/main/java/spock/000077500000000000000000000000001202022523300223005ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/main/java/spock/guice/000077500000000000000000000000001202022523300233745ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/main/java/spock/guice/UseModules.java000066400000000000000000000024131202022523300263240ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.guice; import java.lang.annotation.*; import com.google.inject.Module; import org.spockframework.guice.GuiceExtension; import org.spockframework.runtime.extension.ExtensionAnnotation; /** * Activates Guice integration for a specification. * The specified modules will be started before and stopped after the specification's execution. * Services will be injected into the specification based on regular Guice annotations. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @ExtensionAnnotation(GuiceExtension.class) public @interface UseModules { Class[] value(); } spock-0.6-groovy-1.8/spock-guice/src/main/java/spock/guice/package-info.java000066400000000000000000000013221202022523300265610ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Integration with Guice 2/3. */ package spock.guice;spock-0.6-groovy-1.8/spock-guice/src/test/000077500000000000000000000000001202022523300202735ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/test/groovy/000077500000000000000000000000001202022523300216205ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/000077500000000000000000000000001202022523300224075ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/000077500000000000000000000000001202022523300254445ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/000077500000000000000000000000001202022523300265405ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/BindingAnnotation1.groovy000066400000000000000000000015411202022523300334760ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice import com.google.inject.BindingAnnotation import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy @BindingAnnotation @Retention(RetentionPolicy.RUNTIME) @interface BindingAnnotation1 {}spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/BindingAnnotation2.groovy000066400000000000000000000015411202022523300334770ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice import com.google.inject.BindingAnnotation import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy @BindingAnnotation @Retention(RetentionPolicy.RUNTIME) @interface BindingAnnotation2 {}GuiceSpecInheritance.groovy000066400000000000000000000027021202022523300337520ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice import com.google.inject.Inject import spock.guice.UseModules import spock.lang.* @UseModules(Module1) abstract class BaseSpec extends Specification { @Inject IService1 service1 @Inject IService2 service2 def setup() { assert service1 instanceof IService1 assert service2 instanceof IService2 } } @UseModules(Module2) class GuiceSpecInheritance extends BaseSpec { @Inject IService2 anotherService2 def setup() { assert service1 instanceof IService1 assert service2 instanceof IService2 assert anotherService2 instanceof IService2 } def "fields of base class have been injected"() { expect: service1 instanceof IService1 service2 instanceof IService2 } def "fields of derived class have been injected"() { expect: anotherService2 instanceof IService2 } } spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/IService1.groovy000066400000000000000000000013021202022523300315750ustar00rootroot00000000000000package org.spockframework.guice /* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ public interface IService1 { String generateString() }spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/IService2.groovy000066400000000000000000000013131202022523300316000ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice public interface IService2 { public String generateQuickBrownFox(); }spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/InjectionExamples.groovy000066400000000000000000000053661202022523300334420ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice import com.google.inject.Inject import com.google.inject.Injector import com.google.inject.name.Named import spock.guice.UseModules import spock.lang.Shared import spock.lang.Specification @UseModules(Module1) class InjectionExamples extends Specification { @Inject IService1 service @Inject @Shared IService1 sharedService @Inject @Named("value1") String namedValue1 @Inject @Named("value2") String namedValue2 @Inject @BindingAnnotation1 String annotatedValue1 @Inject @BindingAnnotation2 String annotatedValue2 IService1 copiedService = service @Shared IService1 copiedSharedService = sharedService @Inject Injector injector @Shared List savedServices = [] @Shared List savedSharedServices = [] def setupSpec() { assert sharedService instanceof Service1 } def cleanupSpec() { assert sharedService instanceof Service1 } def setup() { assert service instanceof Service1 assert sharedService instanceof Service1 savedServices << service savedSharedServices << sharedService } def cleanup() { assert service instanceof Service1 assert sharedService instanceof Service1 } def "injecting a field"() { expect: service instanceof Service1 } def "injecting a shared field"() { expect: sharedService instanceof Service1 } def "using @Named"() { expect: namedValue1 == "named value 1" namedValue2 == "named value 2" } def "using a binding annotation"() { expect: annotatedValue1 == "annotated value 1" annotatedValue2 == "annotated value 2" } def "accessing injected values from field initializers"() { expect: copiedService == service copiedSharedService == sharedService } def "explicit use of injector (discouraged)"() { expect: injector.getInstance(IService1) instanceof Service1 } def "instance fields are injected once per feature iteration"() { expect: (savedServices as Set).size() == savedServices.size() } def "shared fields are injected once per specification"() { expect: (savedSharedServices as Set).size() == 1 } }spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/Module1.groovy000066400000000000000000000022171202022523300313170ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice import com.google.inject.AbstractModule import com.google.inject.name.Names class Module1 extends AbstractModule { protected void configure() { bind(IService1).to(Service1) bind(String).annotatedWith(Names.named("value1")).toInstance("named value 1") bind(String).annotatedWith(Names.named("value2")).toInstance("named value 2") bind(String).annotatedWith(BindingAnnotation1).toInstance("annotated value 1") bind(String).annotatedWith(BindingAnnotation2).toInstance("annotated value 2") } }spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/Module2.groovy000066400000000000000000000014321202022523300313160ustar00rootroot00000000000000 /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice import com.google.inject.AbstractModule class Module2 extends AbstractModule { protected void configure() { bind(IService2).to(Service2) } }spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/Service1.groovy000066400000000000000000000013351202022523300314720ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice class Service1 implements IService1 { String generateString() { "foo" } }spock-0.6-groovy-1.8/spock-guice/src/test/groovy/org/spockframework/guice/Service2.groovy000066400000000000000000000014351202022523300314740ustar00rootroot00000000000000 /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.guice public class Service2 implements IService2 { public String generateQuickBrownFox() { return "The quick brown fox jumps over the lazy dog."; } } spock-0.6-groovy-1.8/spock-maven/000077500000000000000000000000001202022523300165375ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/maven.gradle000066400000000000000000000012271202022523300210270ustar00rootroot00000000000000apply from: script("publishMaven") displayName = "Spock Framework - Maven Module" description = "Spock's Maven Module provides some advanced features when executing Spock specifications with Maven 2. \ This module is purely optional; Maven 2/3 will execute Spock specifications just fine without it." dependencies { compile project(":spock-core") // Surefire provider compile "org.apache.maven.surefire:surefire-junit47:2.11" // Mojo compile "org.apache.maven:maven-plugin-api:2.0" compile "org.apache.maven:maven-project:2.0" compile "org.apache.maven:maven-core:2.0" compile "org.codehaus.plexus:plexus-utils:1.5.7" runtime libs.asm } spock-0.6-groovy-1.8/spock-maven/src/000077500000000000000000000000001202022523300173265ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/000077500000000000000000000000001202022523300202525ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/000077500000000000000000000000001202022523300211735ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/org/000077500000000000000000000000001202022523300217625ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/org/apache/000077500000000000000000000000001202022523300232035ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/org/apache/maven/000077500000000000000000000000001202022523300243115ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/org/apache/maven/surefire/000077500000000000000000000000001202022523300261355ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/org/apache/maven/surefire/junitcore/000077500000000000000000000000001202022523300301375ustar00rootroot00000000000000SpockProvider.java000066400000000000000000000155101202022523300335170ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/org/apache/maven/surefire/junitcore/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.maven.surefire.junitcore; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.surefire.common.junit4.JUnit4RunListenerFactory; import org.apache.maven.surefire.common.junit4.JUnit4TestChecker; import org.apache.maven.surefire.common.junit48.FilterFactory; import org.apache.maven.surefire.common.junit48.JUnit48Reflector; import org.apache.maven.surefire.providerapi.AbstractProvider; import org.apache.maven.surefire.providerapi.ProviderParameters; import org.apache.maven.surefire.report.ConsoleLogger; import org.apache.maven.surefire.report.ConsoleOutputCapture; import org.apache.maven.surefire.report.ConsoleOutputReceiver; import org.apache.maven.surefire.report.ReporterException; import org.apache.maven.surefire.report.ReporterFactory; import org.apache.maven.surefire.report.RunListener; import org.apache.maven.surefire.suite.RunResult; import org.apache.maven.surefire.testset.TestSetFailedException; import org.apache.maven.surefire.util.DirectoryScanner; import org.apache.maven.surefire.util.RunOrderCalculator; import org.apache.maven.surefire.util.ScannerFilter; import org.apache.maven.surefire.util.TestsToRun; import org.apache.maven.surefire.util.internal.StringUtils; import org.junit.runner.Description; import org.junit.runner.manipulation.Filter; /** * Adaptation of {@link org.apache.maven.surefire.junitcore.JUnitCoreProvider} * to Spock. Not meant to run JUnit tests. * * @author Kristian Rosenvold */ @SuppressWarnings( { "UnusedDeclaration" } ) public class SpockProvider extends AbstractProvider { private final ClassLoader testClassLoader; private final DirectoryScanner directoryScanner; private final JUnitCoreParameters jUnitCoreParameters; private final ScannerFilter scannerFilter; private final List customRunListeners; private final ProviderParameters providerParameters; private TestsToRun testsToRun; private JUnit48Reflector jUnit48Reflector; private RunOrderCalculator runOrderCalculator; private String requestedTestMethod; public SpockProvider( ProviderParameters providerParameters ) { this.providerParameters = providerParameters; this.testClassLoader = providerParameters.getTestClassLoader(); this.directoryScanner = providerParameters.getDirectoryScanner(); this.runOrderCalculator = providerParameters.getRunOrderCalculator(); this.jUnitCoreParameters = new JUnitCoreParameters( providerParameters.getProviderProperties() ); this.scannerFilter = new JUnit4TestChecker( testClassLoader ); this.requestedTestMethod = providerParameters.getTestRequest().getRequestedTestMethod(); customRunListeners = JUnit4RunListenerFactory. createCustomListeners( providerParameters.getProviderProperties().getProperty( "listener" ) ); jUnit48Reflector = new JUnit48Reflector( testClassLoader ); } public Boolean isRunnable() { return Boolean.TRUE; } public Iterator getSuites() { final Filter filter = jUnit48Reflector.isJUnit48Available() ? createJUnit48Filter() : null; testsToRun = getSuitesAsList( filter ); return testsToRun.iterator(); } public RunResult invoke( Object forkTestSet ) throws TestSetFailedException, ReporterException { final String message = "Concurrency config is " + jUnitCoreParameters.toString() + "\n"; final ReporterFactory reporterFactory = providerParameters.getReporterFactory(); final ConsoleLogger consoleLogger = providerParameters.getConsoleLogger(); consoleLogger.info( message ); Filter filter = jUnit48Reflector.isJUnit48Available() ? createJUnit48Filter() : null; if ( testsToRun == null ) { testsToRun = forkTestSet == null ? getSuitesAsList( filter ) : TestsToRun.fromClass( (Class) forkTestSet ); } if (testsToRun.size() == 0) { filter = null; } final Map testSetMap = new ConcurrentHashMap(); RunListener listener = ConcurrentReporterManager.createInstance( testSetMap, reporterFactory, jUnitCoreParameters.isParallelClasses(), jUnitCoreParameters.isParallelBoth(), consoleLogger ); ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) listener ); org.junit.runner.notification.RunListener jUnit4RunListener = new JUnitCoreRunListener( listener, testSetMap ); customRunListeners.add( 0, jUnit4RunListener ); JUnitCoreWrapper.execute( testsToRun, jUnitCoreParameters, customRunListeners, filter ); return reporterFactory.close(); } @SuppressWarnings( "unchecked" ) private TestsToRun getSuitesAsList( Filter filter ) { List> res = new ArrayList>( 500 ); TestsToRun max = scanClassPath(); if ( filter == null ) { return max; } Iterator> it = max.iterator(); while ( it.hasNext() ) { Class clazz = it.next(); boolean isCategoryAnnotatedClass = jUnit48Reflector.isCategoryAnnotationPresent( clazz ); Description d = Description.createSuiteDescription( clazz ); if ( filter.shouldRun( d ) ) { res.add( clazz ); } else { for ( Method method : clazz.getMethods() ) { final Description testDescription = Description.createTestDescription( clazz, method.getName(), method.getAnnotations() ); if ( filter.shouldRun( testDescription ) ) { res.add( clazz ); break; } } } } return new TestsToRun( res ); } private Filter createJUnit48Filter() { final FilterFactory filterFactory = new FilterFactory( testClassLoader ); return isMethodFilterSpecified() ? filterFactory.createMethodFilter( requestedTestMethod ) : filterFactory.createGroupFilter( providerParameters.getProviderProperties() ); } private TestsToRun scanClassPath() { final TestsToRun scanned = directoryScanner.locateTestClasses( testClassLoader, scannerFilter ); return runOrderCalculator.orderTestClasses( scanned ); } private boolean isMethodFilterSpecified() { return !StringUtils.isBlank( requestedTestMethod ); } } spock-0.6-groovy-1.8/spock-maven/src/main/java/org/spockframework/000077500000000000000000000000001202022523300250175ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/org/spockframework/buildsupport/000077500000000000000000000000001202022523300275535ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/org/spockframework/buildsupport/maven/000077500000000000000000000000001202022523300306615ustar00rootroot00000000000000FindSpecsMojo.java000066400000000000000000000221711202022523300341530ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/java/org/spockframework/buildsupport/maven/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.buildsupport.maven; import java.io.*; import java.util.ArrayList; import java.util.List; import org.apache.maven.execution.RuntimeInformation; import org.apache.maven.model.ConfigurationContainer; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.spockframework.buildsupport.SpecClassFileFinder; import org.spockframework.runtime.OptimizeRunOrderSuite; import org.spockframework.util.IoUtil; import org.spockframework.util.TextUtil; /** * Plugin that auto-detects and runs all Spock specs in a Maven project. * Specs are run by adding them as <include>'s to Surefire's * configuration. Unless overrideSurefireIncludes is set to true, * Surefire's default includes or any explicit <include>'s overriding * those defaults will remain intact. This means that Spock specs will get run * together with all other JUnit-based tests that would get run without this * plugin being present. * *

Note:This plugin is not required for using Spock * together with Maven; it merely adds some advanced capabilities like auto- * detection of specs. If you decide not to use this plugin, make sure that your * spec classes conform to Surefire's naming conventions. By default, these are * **/Test*.java, **/*Test.java, and **/*TestCase.java. * * @author Peter Niederwieser * @goal find-specs * @phase process-test-classes */ public class FindSpecsMojo extends AbstractMojo { /** * @component */ private RuntimeInformation runtimeInformation; /** * @parameter expression="${project}" */ private MavenProject project; /** * @parameter expression="${project.build.testOutputDirectory}" */ private File testOutputDirectory; /** * If true, the execution of this plugin will be skipped. * * @parameter expression="${findspecs.skip}" default="false" */ private boolean skip; /** * If true, any existing Surefire <include>'s will * be overridden to make sure that only Spock specs will get run. * * @parameter expression="${findspecs.overrideSurefireIncludes}" default="false" */ private boolean overrideSurefireIncludes; /** * If non-null, <include>'s for Spock specs will be added to the * configuration of the specified Surefire execution. Otherwise, they * will be added to the global Surefire configuration. * * @parameter expression="${findspecs.surefireExecutionId}" default="null" */ private String surefireExecutionId; /** * If true the run order of spec classes will be * optimized such that frequently failing specs are run first. Note * that this requires all specs to be wrapped with a dynamically * generated JUnit suite, which may have a negative impact on test * reporting. * * @parameter expression="${findspecs.optimizeRunOrder}" default="false" */ private boolean optimizeRunOrder; public void execute() throws MojoExecutionException { checkMavenVersion(); if (!shouldRun()) return; List specNames = findSpecs(); configureSurefire(specNames); } private void checkMavenVersion() throws MojoExecutionException { if (runtimeInformation.getApplicationVersion().getMajorVersion() == 3) { throw new MojoExecutionException("The Spock Maven plugin is not compatible with Maven 3. To use Spock with " + "Maven 3, remove this plugin and make sure that your spec classes adhere to Surefire's naming conventions " + "(e.g. '*Test'). You can also configure Surefire to support other naming conventions (e.g. '*Spec')."); } } private boolean shouldRun() { if (skip) { getLog().info(String.format("Skipping goal 'find-specs'")); return false; } if (!testOutputDirectory.exists()) { getLog().info(String.format("Found 0 Spock specifications")); return false; } return true; } private List findSpecs() throws MojoExecutionException { final List specNames; try { List specFiles = new SpecClassFileFinder().findRunnableSpecs(testOutputDirectory); specNames = new ArrayList(specFiles.size()); for (File file : specFiles) { String path = file.getAbsolutePath(); String name = path.substring(testOutputDirectory.getAbsolutePath().length() + 1, path.length() - ".class".length()).replace(File.separatorChar, '.'); specNames.add(name); } } catch (IOException e) { // chaining the exception would result in a cluttered error message throw new MojoExecutionException(e.toString()); } getLog().info(String.format("Found %d Spock specifications", specNames.size())); return specNames; } private void configureSurefire(List specNames) throws MojoExecutionException { ConfigurationContainer container = getSurefireConfigurationContainer(); Xpp3Dom config = (Xpp3Dom) container.getConfiguration(); if (config == null) { config = new Xpp3Dom("configuration"); container.setConfiguration(config); } Xpp3Dom includes = getOrAddChild(config, "includes"); if (overrideSurefireIncludes) { removeChildren(includes); } else if (includes.getChildCount() == 0) { addDefaultSurefireIncludes(includes); } if (optimizeRunOrder) { optimizeRunOrder(config, includes, specNames); } else { for (String name : specNames) addInclude(includes, name); } } private ConfigurationContainer getSurefireConfigurationContainer() throws MojoExecutionException { @SuppressWarnings("unchecked") List plugins = project.getBuildPlugins(); for (Plugin plugin : plugins) { if (!plugin.getGroupId().equals("org.apache.maven.plugins")) continue; if (!plugin.getArtifactId().equals("maven-surefire-plugin")) continue; if (surefireExecutionId == null) return plugin; PluginExecution execution = (PluginExecution) plugin.getExecutionsAsMap().get(surefireExecutionId); if (execution == null) throw new MojoExecutionException( String.format("Cannot find Surefire execution with ID '%s'", surefireExecutionId)); return execution; } throw new MojoExecutionException("Surefire plugin not found; make sure it is bound to a lifecycle phase"); } private void optimizeRunOrder(Xpp3Dom config, Xpp3Dom includes, List specNames) throws MojoExecutionException { getLog().info(String.format("Optimizing spec run order")); copySuiteClassToTestOutputDirectory(); addInclude(includes, OptimizeRunOrderSuite.class.getName()); Xpp3Dom systemProperties = getOrAddChild(config, "systemPropertyVariables"); addChild(systemProperties, OptimizeRunOrderSuite.CLASSES_TO_RUN_KEY, TextUtil.join(",", specNames)); } private void addInclude(Xpp3Dom includes, String value) { addChild(includes, "include", value.replace('.', '/') + ".java"); } private void addDefaultSurefireIncludes(Xpp3Dom includes) { addInclude(includes, "**/Test*"); addInclude(includes, "**/*Test"); addInclude(includes, "**/*TestCase"); } private void copySuiteClassToTestOutputDirectory() throws MojoExecutionException { try { InputStream source = getClass().getClassLoader().getResourceAsStream( OptimizeRunOrderSuite.class.getName().replace(".", "/") + ".class"); OutputStream target = new FileOutputStream(new File(testOutputDirectory, OptimizeRunOrderSuite.class.getName().replace('.', File.separatorChar) + ".class")); IoUtil.copyStream(source, target); } catch (IOException e) { throw new MojoExecutionException("Failed to copy OptimizeRunOrderSuite.class to test-classes directory\n" + e.toString()); } } private Xpp3Dom addChild(Xpp3Dom parent, String name) { return addChild(parent, name, null); } private Xpp3Dom addChild(Xpp3Dom parent, String name, String value) { Xpp3Dom child = new Xpp3Dom(name); child.setValue(value); parent.addChild(child); return child; } private Xpp3Dom getOrAddChild(Xpp3Dom parent, String name) { Xpp3Dom child = parent.getChild(name); if (child == null) child = addChild(parent, name); return child; } private void removeChildren(Xpp3Dom parent) { for (int i = parent.getChildCount() - 1; i >= 0; i--) parent.removeChild(i); } } spock-0.6-groovy-1.8/spock-maven/src/main/resources/000077500000000000000000000000001202022523300222645ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/resources/META-INF/000077500000000000000000000000001202022523300234245ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/resources/META-INF/maven/000077500000000000000000000000001202022523300245325ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/resources/META-INF/maven/plugin.xml000066400000000000000000000263521202022523300265620ustar00rootroot00000000000000 org.spockframework spock-maven 0.6-groovy-1.8 spock false true find-specs Plugin that auto-detects and runs all Spock specs in a Maven project. Specs are run by adding them as &lt;include&gt;'s to Surefire's configuration. Unless <tt>overrideSurefireIncludes</tt> is set to <tt>true</tt>, Surefire's default includes or any explicit &lt;include&gt;'s overriding those defaults will remain intact. This means that Spock specs will get run together with all other JUnit-based tests that would get run without this plugin being present. <p><strong>Note:</strong>This plugin is <em>not</em> required for using Spock together with Maven; it merely adds some advanced capabilities like auto- detection of specs. If you decide not to use this plugin, make sure that your spec classes conform to Surefire's naming conventions. By default, these are &#42;&#42;/Test&#42;.java, &#42;&#42;/&#42;Test.java, and &#42;&#42;/&#42;TestCase.java. false true false false false true process-test-classes org.spockframework.buildsupport.maven.FindSpecsMojo java per-lookup once-per-session optimizeRunOrder boolean false true If <tt>true</tt> the run order of spec <em>classes</em> will be optimized such that frequently failing specs are run first. Note that this requires all specs to be wrapped with a dynamically generated JUnit suite, which may have a negative impact on test reporting. overrideSurefireIncludes boolean false true If <tt>true</tt>, any existing Surefire &lt;include&gt;'s will be overridden to make sure that only Spock specs will get run. project org.apache.maven.project.MavenProject false true skip boolean false true If <tt>true</tt>, the execution of this plugin will be skipped. surefireExecutionId java.lang.String false true If non-null, &lt;include&gt;'s for Spock specs will be added to the configuration of the specified Surefire execution. Otherwise, they will be added to the global Surefire configuration. testOutputDirectory java.io.File false true ${findspecs.surefireExecutionId} ${project} ${findspecs.overrideSurefireIncludes} ${findspecs.skip} ${findspecs.optimizeRunOrder} ${project.build.testOutputDirectory} org.apache.maven.execution.RuntimeInformation runtimeInformation org.spockframework spock-core jar 0.6-groovy-1.8 junit junit-dep jar 4.9 org.hamcrest hamcrest-core jar 1.2 org.codehaus.groovy groovy-all jar 1.8.6 org.apache.maven maven-plugin-api jar 2.0 org.apache.maven maven-project jar 2.0 org.apache.maven maven-profile jar 2.0 org.apache.maven maven-model jar 2.0 org.codehaus.plexus plexus-utils jar 1.5.7 org.codehaus.plexus plexus-container-default jar 1.0-alpha-8 classworlds classworlds jar 1.1-alpha-2 org.apache.maven maven-artifact-manager jar 2.0 org.apache.maven maven-repository-metadata jar 2.0 org.apache.maven maven-artifact jar 2.0 org.apache.maven.wagon wagon-provider-api jar 1.0-alpha-5 org.apache.maven maven-core jar 2.0 org.apache.maven maven-settings jar 2.0 org.apache.maven.wagon wagon-file jar 1.0-alpha-5 org.apache.maven maven-plugin-parameter-documenter jar 2.0 org.apache.maven.wagon wagon-http-lightweight jar 1.0-alpha-5 org.apache.maven.reporting maven-reporting-api jar 2.0 doxia doxia-sink-api jar 1.0-alpha-4 org.apache.maven maven-error-diagnostics jar 2.0 org.apache.maven maven-plugin-registry jar 2.0 commons-cli commons-cli jar 1.0 org.apache.maven maven-plugin-descriptor jar 2.0 org.codehaus.plexus plexus-interactivity-api jar 1.0-alpha-4 org.apache.maven maven-monitor jar 2.0 org.apache.maven.wagon wagon-ssh jar 1.0-alpha-5 com.jcraft jsch jar 0.1.23 org.apache.maven.surefire surefire-junit47 jar 2.11 org.apache.maven.surefire common-junit48 jar 2.11 org.apache.maven.surefire common-junit4 jar 2.11 org.apache.maven.surefire common-junit3 jar 2.11 org.apache.maven.surefire surefire-api jar 2.11 asm asm jar 3.2 spock-0.6-groovy-1.8/spock-maven/src/main/resources/META-INF/services/000077500000000000000000000000001202022523300252475ustar00rootroot00000000000000org.apache.maven.surefire.providerapi.SurefireProvider000066400000000000000000000000551202022523300376730ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-maven/src/main/resources/META-INF/servicesapache.maven.surefire.junitcore.SpockProviderspock-0.6-groovy-1.8/spock-specs/000077500000000000000000000000001202022523300165465ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/specs.gradle000077500000000000000000000011201202022523300210400ustar00rootroot00000000000000displayName = "Spock Framework - Specs for Core Module" description = "Spock specifications for the Core Module. Yes, we eat our own dog food." dependencies { testCompile project(":spock-core") testCompile libs.hamcrest_core testCompile libs.junit testCompile libs.easymock testCompile libs.jmock_junit4 testCompile libs.jmock testCompile libs.mockito testRuntime libs.asm testRuntime libs.cglib testRuntime libs.objenesis testRuntime libs.h2database } //tasks.withType(Test) { // maxParallelForks Math.max(2, (int) (Runtime.runtime.availableProcessors() / 2)) //}spock-0.6-groovy-1.8/spock-specs/src/000077500000000000000000000000001202022523300173355ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/000077500000000000000000000000001202022523300203145ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/000077500000000000000000000000001202022523300216415ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/000077500000000000000000000000001202022523300224305ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/000077500000000000000000000000001202022523300254655ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/EmbeddedSpecification.groovy000066400000000000000000000032621202022523300331310ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework import spock.lang.Specification import spock.util.EmbeddedSpecCompiler import spock.util.EmbeddedSpecRunner /** * Convenience base class for specifications that need to compile * and/or run other specifications. * * @author Peter Niederwieser */ abstract class EmbeddedSpecification extends Specification { EmbeddedSpecRunner runner = new EmbeddedSpecRunner() EmbeddedSpecCompiler compiler = new EmbeddedSpecCompiler() void stackTraceLooksLike(Throwable exception, String template) { def trace = exception.stackTrace def lines = template.trim().split("\n") assert trace.size() == lines.size() lines.eachWithIndex { line, index -> def traceElem = trace[index] def parts = line.split("\\|") def className = parts[0].trim() def methodName = parts[1].trim() def lineNumber = parts[2].trim() assert className == "-" || className == traceElem.className assert methodName == "-" || methodName == traceElem.methodName assert lineNumber == "-" || lineNumber as int == traceElem.lineNumber } } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/builder/000077500000000000000000000000001202022523300271135ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/builder/PojoBuilderSpec.groovy000066400000000000000000000071051202022523300334160ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.builder import spock.lang.Specification class PojoBuilderSpec extends Specification { Person person = new Person() PojoBuilder builder = new PojoBuilder() def "configure top-level property"() { when: builder.build(person) { name "fred" } then: person.name == "fred" } def "configure nested property"() { when: builder.build(person) { address { street "columbo road" } } then: person.address.street == "columbo road" } def "configure collection property"() { when: builder.build(person) { gadget "iphone" gadget "blackberry" } then: person.gadgets == ["iphone", "blackberry"] } def "configure collection property that has concrete declared type"() { when: def house = new House() builder.build(house) { room "living room" room "dining room" } then: house.rooms instanceof TreeSet house.rooms == ["living room", "dining room"] as Set } def "configure collection property and choose collection type"() { when: def computer = new Computer() builder.build(computer) { addresses new LinkedList() address { city "munich" } address { city "vienna" } } then: computer.addresses instanceof LinkedList computer.addresses.size() == 2 } def "adding elements to collection"() { when: def elements = new Elements() builder.build(elements) { clock "tic tac" address "mercury road" rowdy "fred" } then: elements.clocks == ["tic tac"] elements.addresses == ["mercury road"] elements.rowdies == ["fred"] } def "configure primitives"() { when: def pr = new Primitives() builder.build(pr) { aByte 0 as byte aShort 300 as short anInt 70000 aLong 3000000000l aFloat 0.1 as float aDouble 0.2 aChar "a" as char aBoolean true } then: pr.aByte == 0 pr.aShort == 300 pr.anInt == 70000 pr.aLong == 3000000000 pr.aFloat == 0.1 as float pr.aDouble == 0.2 pr.aChar == "a" as char pr.aBoolean == true } def "access local variable"() { def contextVar = "flamingo rd." when: builder.build(person) { address { street contextVar } } then: person.address.street == contextVar } def aField = "pancorn av." def "access field"() { when: builder.build(person) { address { street aField } } then: person.address.street == aField } } class Person { String name Address address List gadgets } class Address { String street String city } class House { TreeSet rooms } class Computer { List

addresses } class Elements { List clocks List addresses List rowdies } class Primitives { byte aByte short aShort int anInt long aLong float aFloat double aDouble char aChar boolean aBoolean } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/buildsupport/000077500000000000000000000000001202022523300302215ustar00rootroot00000000000000SpecClassFileFinderSpec.groovy000066400000000000000000000026331202022523300360400ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/buildsupport /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.buildsupport import org.spockframework.util.ReflectionUtil import spock.lang.* class SpecClassFileFinderSpec extends Specification { def finder = new SpecClassFileFinder() def "class file of regular class isn't considered a runnable spec"() { expect: !finder.isRunnableSpec(ReflectionUtil.getClassFile(RegularClass)) } def "class file of abstract spec isn't considered a runnable spec"() { expect: !finder.isRunnableSpec(ReflectionUtil.getClassFile(AbstractSpec)) } def "class file of concrete spec is considered a runnable spec"() { expect: finder.isRunnableSpec(ReflectionUtil.getClassFile(ConcreteSpec)) } static class RegularClass {} } abstract class AbstractSpec extends Specification {} @Ignore class ConcreteSpec extends Specification {} spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/example/000077500000000000000000000000001202022523300271205ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/example/FeatureUnrolling.groovy000066400000000000000000000024511202022523300336560ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.example import spock.lang.Specification import spock.lang.Unroll /** * @author Peter Niederwieser */ class FeatureUnrolling extends Specification { def "without unrolling"() { expect: name.size() == length where: name << ["Kirk", "Spock", "Scotty"] length << [4, 5, 6] } @Unroll def "with unrolling"() { expect: name.size() == length where: name << ["Kirk", "Spock", "Scotty"] length << [4, 5, 6] } @Unroll("length of '#name' should be #length") def "with unrolling and custom naming pattern"() { expect: name.size() == length where: name << ["Kirk", "Spock", "Scotty"] length << [4, 5, 6] } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/000077500000000000000000000000001202022523300270125ustar00rootroot00000000000000AssertStatementSourcePositionTest.groovy000066400000000000000000000026041202022523300371000ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.spockframework.util.inspector.AstInspector import org.codehaus.groovy.ast.stmt.AssertStatement class AssertStatementSourcePositionTest extends GroovyTestCase { void test() { def inspector = new AstInspector() inspector.load(""" class Foo { def bar() { assert 1 == 2 } } """) def method = inspector.getMethod("bar"); def stat = method.code.statements[0] assert stat instanceof AssertStatement assert stat.lineNumber == 4 assert stat.columnNumber == 5 assert stat.lastLineNumber == 4 assert stat.lastColumnNumber == 18 def expr = stat.booleanExpression assert expr.lineNumber == 4 assert expr.columnNumber == 12 assert expr.lastLineNumber == 4 assert expr.lastColumnNumber == 18 } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/AstInspectorTest.groovy000077500000000000000000000104061202022523300335430ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.stmt.ForStatement import org.codehaus.groovy.control.CompilePhase import org.junit.BeforeClass import org.junit.Test import static org.junit.Assert.* import org.spockframework.util.inspector.* class AstInspectorTest { static AstInspector inspector = new AstInspector(CompilePhase.SEMANTIC_ANALYSIS) @BeforeClass static void loadSource() { inspector.load(""" import org.spockframework.util.inspector.Inspect scriptLoop: for (i in 1..5) println "hi!" scriptExpr: script(me) @Inspect("bar1") def bar() {} class Foo { def field = inspect_init1(42) def Foo(@Inspect("param")f = inspect_init2(5)) { this.field = f } @Inspect("bar2") def bar() { stat1: def x = 10 stat2: (1..inspect_upperValue(5)).each { println(3 * inspect_varRef(x)) } stat3: println "bye" } } """) } @Test void inspectScript() { assertEquals(2, inspector.scriptStatements.size()) assertEquals(1, inspector.scriptExpressions.size()) def scriptLoop = inspector.getStatement("scriptLoop") assertTrue(scriptLoop instanceof ForStatement) def scriptStat = inspector.getStatement("scriptExpr") def scriptExpr = inspector.getExpression("scriptExpr") assertSame(scriptExpr, scriptStat.expression) } @Test void inspectModule() { // one class is auto-generated to hold the script assertEquals(2, inspector.module.classes.size()) def scriptStats = inspector.module.statementBlock.statements assertEquals(scriptStats, inspector.scriptStatements) } @Test void inspectClass() { def foo = inspector.getClass("Foo") def field = inspector.getField("field") assertSame(field, foo.getField("field")) } @Test void inspectConstructor() { def ctor = inspector.getConstructor("Foo") assertTrue(inspector.getExpressions(ctor)[0] instanceof BinaryExpression) def param = inspector.getMarkedNode("param") def init1 = inspector.getExpression("init1") def init2 = inspector.getExpression("init2") assertEquals(42, init1.value) assertEquals(5, init2.value) assertSame(init2, param.initialExpression.arguments.expressions[0]) } @Test void inspectMethod() { def method = inspector.getMarkedNode("bar2") def stat1 = inspector.getStatement("stat1") def stat2 = inspector.getStatement("stat2") def stat3 = inspector.getStatement("stat3") assertEquals([stat1,stat2,stat3], inspector.getStatements(method)) def upperValue = inspector.getExpression("upperValue") assertEquals(5, upperValue.value) } @Test void inspectWhiskeyBars() { def bar = inspector.getMethod("bar") def bar1 = inspector.getMarkedNode("bar1") def bar2 = inspector.getMarkedNode("bar2") assertSame(bar, bar1) assertSame(inspector.getClass("Foo"), bar2.declaringClass) } @Test void someMoreSemanticAnalysis() { def varDef = inspector.getExpression("stat1") def varRef = inspector.getExpression("varRef") assertSame(varDef.variableExpression, varRef.accessedVariable) def method = inspector.getMarkedNode("bar2") // we're hooked to the same classloader (hopefully) assertSame(Inspect.class, method.annotations[0].classNode.typeClass) } @Test(expected=AstInspectorException.class) void throwOnNodeNotFound() { inspector.getMethod("notExisting") } @Test void dontThrowOnNodeNotFound() { inspector.throwOnNodeNotFound = false assertNull(inspector.getMethod("notExisting")) } @Test(expected=IllegalArgumentException.class) void rejectUnsupportedCompilePhase() { inspector.compilePhase = CompilePhase.PARSING } }ClassAnnotationUsageTest.groovy000077500000000000000000000101421202022523300351300ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.codehaus.groovy.control.CompilePhase import org.spockframework.util.inspector.AstInspector class ClassAnnotationUsageTest extends GroovyTestCase { static classes static inspector = new AstInspector() static source = """ import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy import org.spockframework.groovy.GroovyAnnotationWithSourceRetention import org.spockframework.groovy.GroovyAnnotationWithClassRetention import org.spockframework.groovy.GroovyAnnotationWithRuntimeRetention import org.spockframework.groovy.JavaAnnotationWithSourceRetention import org.spockframework.groovy.JavaAnnotationWithClassRetention import org.spockframework.groovy.JavaAnnotationWithRuntimeRetention @GroovyAnnotationWithSourceRetention class GroovySource {} @GroovyAnnotationWithClassRetention class GroovyClass {} @GroovyAnnotationWithRuntimeRetention class GroovyRuntime {} @JavaAnnotationWithSourceRetention class JavaSource {} @JavaAnnotationWithClassRetention class JavaClass {} @JavaAnnotationWithRuntimeRetention class JavaRuntime {} """ static { // compile the classes def compiler = new GroovyClassLoader() compiler.parseClass(source) classes = compiler.loadedClasses // prepare AST inspection // why isn't AnnotationVisitor run as part of semantic analysis? inspector.compilePhase = CompilePhase.CLASS_GENERATION inspector.load(source) } void testGroovySourceRetention() { check("GroovySource", GroovyAnnotationWithSourceRetention, true, false, false) } void testGroovyClassRetention() { check("GroovyClass", GroovyAnnotationWithClassRetention, false, true, false) } void testGroovyRuntimeRetention() { check("GroovyRuntime", GroovyAnnotationWithRuntimeRetention, false, false, true) } void testJavaSourceRetention() { check("JavaSource", JavaAnnotationWithSourceRetention, true, false, false) } void testJavaClassRetention() { check("JavaClass", JavaAnnotationWithClassRetention, false, true, false) } void testJavaRuntimeRetention() { check("JavaRuntime", JavaAnnotationWithRuntimeRetention, false, false, true) } // Checks the annotation's AST and runtime representation. def check(className, annType, sourceRet, classRet, runtimeRet) { checkAstInfo(className, annType, sourceRet, classRet, runtimeRet) checkRuntimeInfo(className, annType, sourceRet, classRet) } // Checks the annotation's AST representation. def checkAstInfo(className, annType, sourceRet, classRet, runtimeRet) { def classNode = inspector.getClass(className) // annotation present? assertTrue(classNode.annotations.size() == 1) // retention policy set correctly? def annNode = classNode.annotations[0] assertEquals(sourceRet, annNode.hasSourceRetention()) assertEquals(classRet, annNode.hasClassRetention()) assertEquals(runtimeRet, annNode.hasRuntimeRetention()) // annotation type resolved correctly? assertSame(annType, annNode.classNode.typeClass) } // Checks the annotation's runtime representation. Ideally one should also // check the class file (to differentiate between source and class retention); // however, this is out of scope for this test. def checkRuntimeInfo(className, annType, sourceRet, classRet) { def classObj = classes.find { it.name == className } assertNotNull(classObj) // annotation only available if it has runtime retention? assertEquals(!sourceRet && !classRet, classObj.isAnnotationPresent(annType)) } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/DGMMatcherIterator.groovy000066400000000000000000000020431202022523300337050ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import spock.lang.Specification /** * * @author Peter Niederwieser */ class DGMMatcherIterator extends Specification { def "can cope with multiple hasNext calls"() { def matcher = "a1a2a3" =~ /a./ def iter = matcher.iterator() when: iter.hasNext() iter.hasNext() iter.hasNext() iter.hasNext() iter.hasNext() iter.next() then: notThrown(Exception) } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/FieldInitializers.groovy000077500000000000000000000024641202022523300337040ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.codehaus.groovy.control.CompilePhase import org.spockframework.util.inspector.AstInspector import spock.lang.Specification /** * A ... * @author Peter Niederwieser */ class FieldInitializers extends Specification { def inspector = new AstInspector() def setup() { inspector.compilePhase = CompilePhase.SEMANTIC_ANALYSIS } def defaultInitializers() { inspector.load(""" class Foo { def x int y Integer z } """) def x = inspector.getField("x") def y = inspector.getField("y") def z = inspector.getField("z") expect: x.initialExpression == null y.initialExpression == null z.initialExpression == null } }Groovy2767_PatchLineColumnInfoTest.groovy000077500000000000000000000045761202022523300366150ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.spockframework.util.inspector.AstInspector class Groovy2767_PatchLineColumnInfoTest extends GroovyTestCase { def inspector = new AstInspector() def exprs def idx = 0 void setUp() { inspector.load(""" true false null "" this super true false null "" this super """) exprs = inspector.scriptExpressions } void testLineColumnInfo() { col 1,5 col 1,6 col 1,5 col 1,3 col 1,5 col 1,6 col 10,14 col 10,15 col 10,14 col 10,12 col 10,14 col 10,15 } void testCorrectComparisons() { exprs[0].isTrueExpression() exprs[1].isFalseExpression() exprs[2].isNullExpression() exprs[3].isEmptyStringExpression() exprs[4].isThisExpression() exprs[5].isSuperExpression() exprs[6].isTrueExpression() exprs[7].isFalseExpression() exprs[8].isNullExpression() exprs[9].isEmptyStringExpression() exprs[10].isThisExpression() exprs[11].isSuperExpression() } void testIncorrectComparisons() { !exprs[0].isFalseExpression() !exprs[1].isTrueExpression() !exprs[2].isEmptyStringExpression() !exprs[3].isNullExpression() !exprs[4].isSuperExpression() !exprs[5].isThisExpression() !exprs[6].isFalseExpression() !exprs[7].isTrueExpression() !exprs[8].isEmptyStringExpression() !exprs[9].isNullExpression() !exprs[10].isSuperExpression() !exprs[11].isThisExpression() } private col(col, lastCol) { pos(idx + 2, col, idx + 2, lastCol) } private pos(line, col, lastLine, lastCol) { def expr = exprs[idx++] assertEquals([line, col, lastLine, lastCol], [expr.lineNumber, expr.columnNumber, expr.lastLineNumber, expr.lastColumnNumber]) } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/GroovyAnnotations.groovy000077500000000000000000000017361202022523300337760ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy @Retention(RetentionPolicy.SOURCE) @interface GroovyAnnotationWithSourceRetention {} @Retention(RetentionPolicy.CLASS) @interface GroovyAnnotationWithClassRetention {} @Retention(RetentionPolicy.RUNTIME) @interface GroovyAnnotationWithRuntimeRetention {}GroovyMopExploration.groovy000066400000000000000000000026761202022523300344030ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.codehaus.groovy.runtime.InvokerHelper import spock.lang.Specification class GroovyMopExploration extends Specification { def "call method that takes a String with GString through InvokerHelper"() { def target = new GroovyMopExploration() def arg = "one ${"t" + "w" + "o"} three" expect: InvokerHelper.invokeMethod(target, "foo", [arg] as Object[]) == "one two three" } def "call method that takes a String with GString through MetaMethod"() { def target = new GroovyMopExploration() def arg = "one ${"t" + "w" + "o"} three" expect: def metaClass = InvokerHelper.getMetaClass(target) def metaMethod = metaClass.pickMethod("foo", [arg.getClass()] as Class[]) metaMethod.invoke(target, [arg] as Object[]) == "one two three" } def foo(String str) { str } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/GroovyVarArgs.groovy000066400000000000000000000014441202022523300330370ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy class GroovyVarArgs { static String[] varArgMethod(int i, String... strings) { strings } static String[] arrayMethod(int i, String[] strings) { strings } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/PackageNames.groovy000066400000000000000000000021361202022523300326020ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.spockframework.util.inspector.AstInspector import spock.lang.Specification /** * @author Peter Niederwieser */ class PackageNames extends Specification { def inspector = new AstInspector() def "package names and imports end in '.'"() { inspector.load(""" package foo.bar import java.lang.Class import java.util.* """) def m = inspector.module expect: m.packageName == "foo.bar." m.starImports[0].packageName == "java.util." } }ReturnStatementSourcePositionTest.groovy000066400000000000000000000023161202022523300371160ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.codehaus.groovy.ast.stmt.ReturnStatement import org.spockframework.util.inspector.AstInspector class ReturnStatementSourcePositionTest extends GroovyTestCase { void test() { def inspector = new AstInspector() inspector.load(""" class Foo { def bar() { return } } """) def method = inspector.getMethod("bar"); def stat = method.code.statements[0] assert stat instanceof ReturnStatement assert stat.lineNumber == 4 assert stat.columnNumber == 5 assert stat.lastLineNumber == 4 assert stat.lastColumnNumber == 11 } }SourcePositionPhaseConversion.groovy000066400000000000000000000026611202022523300362230ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.expr.PropertyExpression import org.spockframework.util.inspector.AstInspector import spock.lang.Specification /** * @author Peter Niederwieser */ class SourcePositionPhaseConversion extends Specification { AstInspector inspector = new AstInspector() def "subscript operator"() { inspector.load(""" foo[0] """) expect: inspector.scriptExpressions[0].operation.startColumn == 4 } def "PropertyExpression that will become ClassExpression"() { inspector.load(""" List.class """) ASTNode expr = inspector.scriptExpressions[0] expect: expr instanceof PropertyExpression expr.lineNumber == 2 expr.columnNumber == 1 expr.lastLineNumber == 2 expr.lastColumnNumber == 11 } }SourcePositionPhaseSemanticAnalysis.groovy000066400000000000000000000063401202022523300373430ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.expr.ClassExpression import org.codehaus.groovy.control.CompilePhase import org.spockframework.util.inspector.AstInspector import spock.lang.Specification /** * A ... * @author Peter Niederwieser */ class SourcePositionPhaseSemanticAnalysis extends Specification { AstInspector inspector = new AstInspector(CompilePhase.SEMANTIC_ANALYSIS) // ConditionRewriter.visitClassExpression() relies on this def "implicit class expressions have no line/column info"() { inspector.load(""" import static java.lang.Thread.State.* NEW """) ASTNode node = inspector.scriptExpressions[0].objectExpression expect: node.lineNumber == -1 node.columnNumber == -1 node.lastLineNumber == -1 node.lastColumnNumber == -1 } // ConditionRewriter.visitClassExpression() relies on this def "explicit class expressions have line/column info"() { inspector.load(""" import java.lang.Thread.State State.NEW """) ASTNode node = inspector.scriptExpressions[0].objectExpression expect: node.lineNumber == 3 node.columnNumber == 1 node.lastLineNumber == 3 node.lastColumnNumber == 6 } def "short-form class literals have accurate line/column info"() { inspector.load(""" List List .methods println( List ) """) expect: ASTNode node1 = inspector.scriptExpressions[0] node1 instanceof ClassExpression node1.lineNumber == 2 node1.columnNumber == 1 node1.lastLineNumber == 2 node1.lastColumnNumber == 5 and: ASTNode node2 = inspector.scriptExpressions[1].objectExpression node2 instanceof ClassExpression node2.lineNumber == 3 node2.columnNumber == 1 node2.lastLineNumber == 3 node2.lastColumnNumber == 5 and: ASTNode node3 = inspector.scriptExpressions[2].arguments.expressions[0] node3 instanceof ClassExpression node3.lineNumber == 4 node3.columnNumber == 11 node3.lastLineNumber == 4 node3.lastColumnNumber == 17 // should be: 15 } def "long-form class literals have accurate line/column info"() { inspector.load(""" List.class List.class.methods """) expect: ASTNode node1 = inspector.scriptExpressions[0] node1 instanceof ClassExpression node1.lineNumber == 2 node1.columnNumber == 1 node1.lastLineNumber == 2 node1.lastColumnNumber == 11 and: ASTNode node2 = inspector.scriptExpressions[1].objectExpression node2 instanceof ClassExpression node2.lineNumber == 3 node2.columnNumber == 1 node2.lastLineNumber == 3 node2.lastColumnNumber == 11 } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/groovy/VarArgsSpec.groovy000066400000000000000000000031371202022523300324450ustar00rootroot00000000000000 /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy import org.spockframework.util.ReflectionUtil import spock.lang.* class VarArgsSpec extends Specification { def "Groovy supports vararg invocation style for vararg parameters"() { expect: JavaVarArgs.varArgMethod(0, "a", "b", "c").size() == 3 GroovyVarArgs.varArgMethod(0, "a", "b", "c").size() == 3 } def "Groovy supports vararg invocation style for array parameters"() { expect: JavaVarArgs.arrayMethod(0, "a", "b", "c").size() == 3 // note: the following invocation even works from Java (albeit not (yet) with joint compilation) GroovyVarArgs.arrayMethod(0, "a", "b", "c").size() == 3 } def "vararg reflection"() { expect: ReflectionUtil.getMethodByName(JavaVarArgs, "varArgMethod").isVarArgs() !ReflectionUtil.getMethodByName(JavaVarArgs, "arrayMethod").isVarArgs() ReflectionUtil.getMethodByName(GroovyVarArgs, "varArgMethod").isVarArgs() ReflectionUtil.getMethodByName(GroovyVarArgs, "arrayMethod").isVarArgs() } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/junit/000077500000000000000000000000001202022523300266165ustar00rootroot00000000000000DescriptionOfDerivedTestClass.groovy000066400000000000000000000033471202022523300357160ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/junit/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.junit import org.junit.runner.notification.RunListener import org.junit.runners.JUnit4 import org.spockframework.EmbeddedSpecification class DescriptionOfDerivedTestClass extends EmbeddedSpecification { Class derivedClass def setup() { def classes = compiler.compile(""" import org.junit.* class BaseTest { @Before void before() { throw new RuntimeException() } @Test void foo() {} } class DerivedTest extends BaseTest { @Test void bar() {} } """) derivedClass = classes.find { it.name == "DerivedTest" } } def "description of inherited test method has class name of derived class"() { def desc = new JUnit4(derivedClass).description expect: desc.children.size() == 2 desc.children.every { it.className == derivedClass.name } } def "description of inherited before method has class name of derived class"() { RunListener listener = Mock() runner.listeners << listener runner.throwFailure = false when: runner.runClass(derivedClass) then: 2 * listener.testFailure( { it.description.className == derivedClass.name } ) } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/junit/JUnitErrorBehavior.groovy000066400000000000000000000024121202022523300336070ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.junit import org.spockframework.EmbeddedSpecification class JUnitErrorBehavior extends EmbeddedSpecification { def "failing beforeClass method"() { runner.throwFailure = false when: def result = runner.run(""" import org.junit.* class Foo { @BeforeClass static void beforeClass() { throw new Error() } @Test void test() {} } """) then: result.runCount == 0 result.failureCount == 1 result.ignoreCount == 0 def desc = result.failures[0].description desc.isSuite() // failure description is description of the test class desc.className == "Foo" desc.children.size() == 1 } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/junit/JUnitRuleBehavior.groovy000066400000000000000000000010371202022523300334270ustar00rootroot00000000000000package org.spockframework.junit import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule import org.junit.rules.TestWatcher import org.junit.runner.Description class JUnitRuleBehavior extends Base { boolean started = false @Rule public TestRule rule = new TestWatcher() { @Override protected void starting(Description description) { started = true } } abstract static class Base { @Test public void ruleInDerivedClassAffectsTestInBaseClass() { assert this.started } } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/junit/ObservableRunner.groovy000066400000000000000000000043341202022523300333470ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.junit import org.junit.runner.notification.Failure import org.junit.runner.notification.RunNotifier import org.junit.runners.BlockJUnit4ClassRunner import org.junit.runner.* /** * A JUnit runner for observing the behavior of JUnit's default runner. * * @author Peter Niederwieser */ class ObservableRunner extends Runner { Runner delegate ObservableRunner(Class clazz) { println "INIT" delegate = new BlockJUnit4ClassRunner(clazz) } Description getDescription() { println "GET DESCRIPTION" return delegate.getDescription() } void run(RunNotifier notifier) { println "RUN" delegate.run(new ObservableNotifier(delegate: notifier)) } } class ObservableNotifier extends RunNotifier { RunNotifier delegate void fireTestRunStarted(Description description) { println "TEST RUN STARTED" delegate.fireTestRunStarted(description) } void fireTestRunFinished(Result result) { println "TEST RUN FINISHED" delegate.fireTestRunFinished(result) } void fireTestFailure(Failure failure) { println "TEST FAILURE" delegate.fireTestFailure(failure); } void fireTestAssumptionFailed(Failure failure) { println "TEST ASSUMPTION FAILED" delegate.fireTestAssumptionFailed(failure); } void fireTestStarted(Description description) { println "STARTED" delegate.fireTestStarted(description) } void fireTestFinished(Description description) { println "FINISHED" delegate.fireTestFinished(description); } void fireTestIgnored(Description description) { println "IGNORED" delegate.fireTestIgnored(description); } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/mock/000077500000000000000000000000001202022523300264165ustar00rootroot00000000000000DefaultMockFactorySpec.groovy000066400000000000000000000036231202022523300341530ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock import spock.lang.Specification import spock.lang.Issue class DefaultMockFactorySpec extends Specification { IMockFactory factory = new DefaultMockFactory() IInvocationDispatcher dummy = Mock() // needed if test fails and toString() is delegated to dispatcher def "can create mocks for interfaces"() { expect: factory.create("foo", List, dummy) instanceof List } @Issue("http://issues.spockframework.org/detail?id=227") def "can create mocks for interfaces containing nested classes"() { expect: factory.create("foo", InterfaceWithNestedClass, dummy) instanceof InterfaceWithNestedClass } def "can create mocks for classes w/ parameterless constructor"() { expect: factory.create("foo", ArrayList, dummy) instanceof ArrayList } def "can create mocks for classes wo/ parameterless constructor"() { expect: factory.create("foo", Node, dummy) instanceof Node } def "can create mocks for interfaces defined in Groovy"() { expect: factory.create("foo", IMockMe, dummy) instanceof IMockMe } def "can create mocks for classes defined in Groovy"() { expect: factory.create("foo", MockMe, dummy) instanceof MockMe } } interface IMockMe { def foo(int i) } class MockMe implements IMockMe { def foo(int i) {} }IterableResultGeneratorSpec.groovy000066400000000000000000000033051202022523300352170ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.mock import org.spockframework.util.ReflectionUtil import spock.lang.Specification class IterableResultGeneratorSpec extends Specification { IMockInvocation inv = Mock() def "generate results from non-empty list" () { def gen = new IterableResultGenerator([1,2,3]) def method = ReflectionUtil.getMethodByName(Object, "hashCode") inv.getMethod() >> method expect: gen.generate(inv) == 1 gen.generate(inv) == 2 gen.generate(inv) == 3 gen.generate(inv) == 3 } def "generate results from empty list"() { def gen = new IterableResultGenerator([]) def method = ReflectionUtil.getMethodByName(Object, "hashCode") inv.getMethod() >> method expect: gen.generate(inv) == null gen.generate(inv) == null } def "generate results from string"() { def gen = new IterableResultGenerator("abc") def method = ReflectionUtil.getMethodByName(Object, "toString") inv.getMethod() >> method expect: gen.generate(inv) == "a" gen.generate(inv) == "b" gen.generate(inv) == "c" gen.generate(inv) == "c" } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/000077500000000000000000000000001202022523300271505ustar00rootroot00000000000000ClosingOfDataProviders.groovy000077500000000000000000000027441202022523300347250ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime import spock.lang.Specification class ClosingOfDataProviders extends Specification { def runner = new ParameterizedSpecRunner(null, null) def "close one provider which potentially throws an exception"() { MyCloseable provider = Mock() when: runner.closeDataProviders(provider) then: 1 * provider.close() >> { action() } noExceptionThrown() where: action << [{}, { throw new Exception() }] } def "close multiple providers which potentially throw an exception"() { MyCloseable provider1 = Mock() java.io.Closeable provider2 = Mock() when: runner.closeDataProviders(provider1, provider2) then: 1 * provider1.close() >> { action() } 1 * provider2.close() noExceptionThrown() where: action << [{}, { throw new Exception() }] } } interface MyCloseable { void close() }ConfigurationScriptLoaderSpec.groovy000066400000000000000000000055411202022523300363030ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime import spock.lang.* import spock.config.ConfigurationException class ConfigurationScriptLoaderSpec extends Specification { private static final String PROP_KEY = "spockConfigSystemProperty" private static final String VALID_CONFIG = "org/spockframework/runtime/ValidConfig.txt" private static final String INVALID_CONFIG = "org/spockframework/runtime/InvalidConfig.txt" def "load configuration script from system property that points to class path location"() { System.setProperty(PROP_KEY, VALID_CONFIG) def loader = new ConfigurationScriptLoader(PROP_KEY, "foo", "bar") expect: loader.loadAutoDetectedScript() != null cleanup: System.clearProperty(PROP_KEY) } def "load configuration script from system property that points to file system location"() { def location = getClass().classLoader.getResource(VALID_CONFIG).path System.setProperty(PROP_KEY, location) def loader = new ConfigurationScriptLoader(PROP_KEY, "foo", "bar") expect: loader.loadAutoDetectedScript() != null cleanup: System.clearProperty(PROP_KEY) } def "system property that points to unexisting location is rejected"() { System.setProperty(PROP_KEY, "does/not/exist") def loader = new ConfigurationScriptLoader(PROP_KEY, "foo", "bar") when: loader.loadAutoDetectedScript() then: thrown(ConfigurationException) cleanup: System.clearProperty(PROP_KEY) } def "configuration script that cannot be compiled is rejected"() { System.setProperty(PROP_KEY, INVALID_CONFIG) def loader = new ConfigurationScriptLoader(PROP_KEY, "foo", "bar") when: loader.loadAutoDetectedScript() then: thrown(ConfigurationException) cleanup: System.clearProperty(PROP_KEY) } def "load configuration script from class path location"() { def loader = new ConfigurationScriptLoader("does/not/exist", VALID_CONFIG, "bar") expect: loader.loadAutoDetectedScript() != null } def "load configuration script from file system location"() { def location = getClass().classLoader.getResource(VALID_CONFIG).path def loader = new ConfigurationScriptLoader("does/not/exist", "foo", location) expect: loader.loadAutoDetectedScript() != null } } EstimatedNumberOfIterations.groovy000077500000000000000000000031471202022523300357670ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime import spock.lang.Specification class EstimatedNumberOfIterations extends Specification { def runner = new ParameterizedSpecRunner(null, null) def "w/o data provider"() { expect: "estimation is 1" runner.estimateNumIterations(new Object[0]) == 1 } def "w/ data provider that doesn't respond to size"() { expect: "estimation is 'unknown', represented as -1" runner.estimateNumIterations([1] as Object[]) == -1 } def "w/ data provider that responds to size"() { expect: "estimation is size" runner.estimateNumIterations([[1, 2, 3]] as Object[]) == 3 } def "w/ multiple data providers, all of which respond to size"() { expect: "estimation is minimum" runner.estimateNumIterations([[1], [1, 2], [1, 2, 3]] as Object[]) == 1 } def "w/ multiple data providers, one of which doesn't respond to size"() { expect: "estimation is minimum of others" runner.estimateNumIterations([1, [1, 2], [1, 2, 3]] as Object[]) == 2 } }ExtensionRegistrySpec.groovy000066400000000000000000000023471202022523300346660ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime import org.spockframework.runtime.extension.IGlobalExtension import org.spockframework.runtime.model.SpecInfo import spock.lang.Specification class ExtensionRegistrySpec extends Specification { def "registry can load extensions"() { def registry = new ExtensionRegistry([Extension1, Extension2], []) when: registry.loadExtensions() then: registry.extensions*.getClass() == [Extension1, Extension2] } } class Extension1 implements IGlobalExtension { void visitSpec(SpecInfo spec) {} } class Extension2 implements IGlobalExtension { void visitSpec(SpecInfo spec) {} }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/GroovyMethods.groovy000066400000000000000000000023121202022523300332260ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime /** * @author Peter Niederwieser */ class GroovyMethods { void voidInstanceMethod() {} def untypedInstanceMethodWithRetVal() { null } def untypedInstanceMethodWithoutRetVal() {} Object typedInstanceMethodWithRetVal() { null } Object typedInstanceMethodWithoutRetVal() {} static void voidStaticMethod() {} static untypedStaticMethodWithRetVal() { null } static untypedStaticMethodWithoutRetVal() {} static Object typedStaticMethodWithRetVal() { null } static Object typedStaticMethodWithoutRetVal() {} def methodWithStringParam(String str) { null } }GroovyRuntimeUtilIsVoidMethodSpec.groovy000066400000000000000000000071301202022523300371220ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime import spock.lang.* import static org.spockframework.util.GroovyRuntimeUtil.isVoidMethod class GroovyRuntimeUtilIsVoidMethodSpec extends Specification { def "void Java instance method"() { expect: isVoidMethod(new JavaMethods(), "voidInstanceMethod") } def "non-void Java instance method"() { expect: !isVoidMethod(new JavaMethods(), "nonVoidInstanceMethod") } def "void Java static method"() { expect: isVoidMethod(new JavaMethods(), "voidStaticMethod") isVoidMethod(JavaMethods, "voidStaticMethod") } def "non-void Java static method"() { expect: !isVoidMethod(new JavaMethods(), "nonVoidStaticMethod") !isVoidMethod(JavaMethods, "nonVoidStaticMethod") } def "void Groovy instance method"() { expect: isVoidMethod(new GroovyMethods(), "voidInstanceMethod") } def "untyped Groovy instance method"() { expect: !isVoidMethod(new GroovyMethods(), "untypedInstanceMethodWithRetVal") !isVoidMethod(new GroovyMethods(), "untypedInstanceMethodWithoutRetVal") } def "typed Groovy instance method"() { expect: !isVoidMethod(new GroovyMethods(), "typedInstanceMethodWithRetVal") !isVoidMethod(new GroovyMethods(), "typedInstanceMethodWithoutRetVal") } def "void Groovy static method"() { expect: isVoidMethod(new GroovyMethods(), "voidStaticMethod") isVoidMethod(GroovyMethods, "voidStaticMethod") } def "untyped Groovy static method"() { expect: !isVoidMethod(new GroovyMethods(), "untypedStaticMethodWithRetVal") !isVoidMethod(GroovyMethods, "untypedStaticMethodWithRetVal") !isVoidMethod(new GroovyMethods(), "untypedStaticMethodWithoutRetVal") !isVoidMethod(GroovyMethods, "untypedStaticMethodWithoutRetVal") } def "typed Groovy static method"() { expect: !isVoidMethod(new GroovyMethods(), "typedStaticMethodWithRetVal") !isVoidMethod(GroovyMethods, "typedStaticMethodWithRetVal") !isVoidMethod(new GroovyMethods(), "typedStaticMethodWithoutRetVal") !isVoidMethod(GroovyMethods, "typedStaticMethodWithoutRetVal") } def "non-void java.lang.Class method"() { expect: !isVoidMethod(int, "getSuperclass") } def "void java.lang.Class method"() { expect: synchronized(Collections) { assert isVoidMethod(Collections, "notify") } } def "void DGM method"() { expect: isVoidMethod(this, "print", [""] as Object[]) isVoidMethod(3, "times", [{}] as Object[]) } def "non-void DGM method"() { expect: !isVoidMethod("a", "find", ["b"] as Object[]) } def "void DGSM method"() { expect: isVoidMethod(this, "sleep", [1] as Object[]) isVoidMethod(Object, "sleep", [1] as Object[]) } def "non-void DGSM method"() { expect: !isVoidMethod(Thread, "start", [ {} ] as Object[]) } def "Groovy method that takes a String with a GString"() { expect: !isVoidMethod(new GroovyMethods(), "methodWithStringParam", ["one ${"t" + "w" + "o"} three"] as Object[]) } }JUnitDescriptionGeneratorSpec.groovy000066400000000000000000000030711202022523300362600ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime import org.spockframework.EmbeddedSpecification import spock.lang.Issue class JUnitDescriptionGeneratorSpec extends EmbeddedSpecification { @Issue("http://code.google.com/p/spock/issues/detail?id=54") def "derived spec has correct Description"() { def derived = compiler.compileWithImports(""" class Base extends Specification { def f1() { expect: true } } class Derived extends Base { def f2() { expect: true } } """).find { it.simpleName == "Derived" } def specInfo = new SpecInfoBuilder(derived).build() def generator = new JUnitDescriptionGenerator(specInfo) when: generator.attach() generator.aggregate() then: def desc = specInfo.description desc.displayName == "apackage.Derived" desc.children.size() == 2 desc.children.collect { it.methodName } == ["f1", "f2"] desc.children.collect { it.className } == ["apackage.Derived", "apackage.Derived"] } } SafeIterationNameProviderSpec.groovy000066400000000000000000000045011202022523300362240ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime import org.spockframework.runtime.model.NameProvider import org.spockframework.runtime.model.IterationInfo import org.spockframework.runtime.model.FeatureInfo import spock.lang.Specification class SafeIterationNameProviderSpec extends Specification { def feature = new FeatureInfo() def iteration = new IterationInfo(feature, [] as Object[], 3) def other = Mock(NameProvider) def provider = new SafeIterationNameProvider(other) def setup() { feature.name = "feature" } def "delegates to other provider"() { when: provider.getName(iteration) then: 1 * other.getName(iteration) } def "returns default if there is no other provider"() { provider = new SafeIterationNameProvider(null) expect: provider.getName(iteration) == "feature" } def "returns default if other provider returns nothing"() { other.getName(iteration) >> null expect: provider.getName(iteration) == "feature" } def "returns default if other provider blows up"() { other.getName(iteration) >> { throw new RuntimeException() } expect: provider.getName(iteration) == "feature" } def "iteration name defaults to feature name when iterations aren't reported"() { feature.reportIterations = false expect: provider.getName(iteration) == "feature" provider.getName(iteration) == "feature" provider.getName(iteration) == "feature" } def "iteration name defaults to indexed feature name when iterations are reported"() { feature.reportIterations = true expect: provider.getName(iteration) == "feature[0]" provider.getName(iteration) == "feature[1]" provider.getName(iteration) == "feature[2]" } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/SpecUtilSpec.groovy000066400000000000000000000033171202022523300327660ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime import spock.lang.* class SpecUtilSpec extends Specification { def "a regular class is not a spec"() { expect: !SpecUtil.isSpec(RegularClass) !SpecUtil.isRunnableSpec(RegularClass) } def "class Specification is not a spec"() { expect: !SpecUtil.isSpec(Specification) !SpecUtil.isRunnableSpec(Specification) } def "an abstract class extending Specification is a spec but isn't runnable"() { expect: SpecUtil.isSpec(AbstractSpec) !SpecUtil.isRunnableSpec(AbstractSpec) } def "a concrete class directly extending Specification is a spec and is runnable"() { expect: SpecUtil.isSpec(ConcreteSpec) SpecUtil.isRunnableSpec(ConcreteSpec) } def "a concrete class indirectly extending Specification is a spec and is runnable"() { expect: SpecUtil.isSpec(DerivedSpec) SpecUtil.isRunnableSpec(DerivedSpec) } static class RegularClass extends ArrayList {} } abstract class AbstractSpec extends Specification {} @Ignore class ConcreteSpec extends Specification {} @Ignore class DerivedSpec extends ConcreteSpec {} spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/condition/000077500000000000000000000000001202022523300311365ustar00rootroot00000000000000EditDistanceSpec.groovy000066400000000000000000000126571202022523300355140ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/condition/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition import spock.lang.* import static org.spockframework.runtime.condition.EditOperation.Kind.* @See(["http://en.wikipedia.org/wiki/Levenshtein_distance", "http://www.levenshtein.net/"]) class EditDistanceSpec extends Specification { @Shared Random random = new Random() @Shared chars = ('a'..'z') + ('A'..'Z') + ('0'..'9') + [' '] * 10 def "matrix for 'sitting' and 'kitten'"() { def matrix = new EditDistance("sitting", "kitten").matrix expect: matrix.size() == 8 matrix[0] == [0, 1, 2, 3, 4, 5, 6] matrix[1] == [1, 1, 2, 3, 4, 5, 6] matrix[2] == [2, 2, 1, 2, 3, 4, 5] matrix[3] == [3, 3, 2, 1, 2, 3, 4] matrix[4] == [4, 4, 3, 2, 1, 2, 3] matrix[5] == [5, 5, 4, 3, 2, 2, 3] matrix[6] == [6, 6, 5, 4, 3, 3, 2] matrix[7] == [7, 7, 6, 5, 4, 4, 3] } def "matrix for 'Sunday' and 'Saturday'"() { def matrix = new EditDistance("Sunday", "Saturday").matrix expect: matrix.size() == 7 matrix[0] == [0, 1, 2, 3, 4, 5, 6, 7, 8] matrix[1] == [1, 0, 1, 2, 3, 4, 5, 6, 7] matrix[2] == [2, 1, 1, 2, 2, 3, 4, 5, 6] matrix[3] == [3, 2, 2, 2, 3, 3, 4, 5, 6] matrix[4] == [4, 3, 3, 3, 3, 4, 3, 4, 5] matrix[5] == [5, 4, 3, 4, 4, 4, 4, 3, 4] matrix[6] == [6, 5, 4, 4, 5, 5, 5, 4, 3] } def "matrix for 'levenshtein' and 'meilenstein'"() { def matrix = new EditDistance("levenshtein", "meilenstein").matrix expect: matrix.size() == 12 matrix[0] == [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] matrix[1] == [ 1, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10] matrix[2] == [ 2, 2, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9] matrix[3] == [ 3, 3, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9] matrix[4] == [ 4, 4, 3, 3, 3, 3, 4, 5, 6, 6, 7, 8] matrix[5] == [ 5, 5, 4, 4, 4, 4, 3, 4, 5, 6, 7, 7] matrix[6] == [ 6, 6, 5, 5, 5, 5, 4, 3, 4, 5, 6, 7] matrix[7] == [ 7, 7, 6, 6, 6, 6, 5, 4, 4, 5, 6, 7] matrix[8] == [ 8, 8, 7, 7, 7, 7, 6, 5, 4, 5, 6, 7] matrix[9] == [ 9, 9, 8, 8, 8, 7, 7, 6, 5, 4, 5, 6] matrix[10] == [10, 10, 9, 8, 9, 8, 8, 7, 6, 5, 4, 5] matrix[11] == [11, 11, 10, 9, 9, 9, 8, 8, 7, 6, 5, 4] } def "path from 'sitting' to 'kitten'"() { def path = new EditDistance("sitting", "kitten").calculatePath() expect: path.size() == 5 path[0] == new EditOperation(SUBSTITUTE, 1) path[1] == new EditOperation(SKIP, 3) path[2] == new EditOperation(SUBSTITUTE, 1) path[3] == new EditOperation(SKIP, 1) path[4] == new EditOperation(DELETE, 1) } def "path from 'Sunday' to 'Saturday'"() { def path = new EditDistance("Sunday", "Saturday").calculatePath() expect: path.size() == 5 path[0] == new EditOperation(SKIP, 1) path[1] == new EditOperation(INSERT, 2) path[2] == new EditOperation(SKIP, 1) path[3] == new EditOperation(SUBSTITUTE, 1) path[4] == new EditOperation(SKIP, 3) } def "path from 'levenshtein' to 'meilenstein'"() { def path = new EditDistance("levenshtein", "meilenstein").calculatePath() expect: path.size() == 7 path[0] == new EditOperation(SUBSTITUTE, 1) path[1] == new EditOperation(SKIP, 1) path[2] == new EditOperation(SUBSTITUTE, 1) path[3] == new EditOperation(INSERT, 1) path[4] == new EditOperation(SKIP, 3) path[5] == new EditOperation(DELETE, 1) path[6] == new EditOperation(SKIP, 4) } def "compute distance"() { def dist = new EditDistance("asdf", str) expect: dist.getDistance() == d where: str << ["xsdf", "axdf", "asxf", "asdx", "", "a", "as", "asd", "asdf", "xasdf", "asdfx", "xasdfx"] d << [ 1 , 1 , 1 , 1 , 4 , 3 , 2 , 1 , 0 , 1 , 1 , 2 ] } def "computed path has correct distance"() { def dist = new EditDistance(str1, str2) expect: computeDistance(dist.calculatePath()) == dist.getDistance() where: num << (0..99) str1 = randomString(num) str2 = editedString(str1) } def computeDistance(List operations) { operations.sum 0, { it.getKind() == EditOperation.Kind.SKIP ? 0 : it.getLength() } } def randomChar() { chars[random.nextInt(chars.size())] } def randomString(int length) { def result = new StringBuilder() length.times { result.append(randomChar()) } result.toString() } def editedString(String str) { StringBuilder result = new StringBuilder() str.toCharArray().each { switch (random.nextInt(4)) { case 0: // skip result.append(it) break case 1: // substitute result.append(randomChar()) break case 2: // delete break case 3: // insert result.append(randomChar()) result.append(it) } } result.toString() } } EditPathRendererSpec.groovy000066400000000000000000000046451202022523300363430ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/condition/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.condition; import spock.lang.* import java.nio.CharBuffer class EditPathRendererSpec extends Specification { def renderer = new EditPathRenderer() def "examples"() { def dist = new EditDistance(str1, str2) expect: renderer.render(str1, str2, dist.calculatePath()) == "$out1\n$out2" where: str1 = "the quick" str2 << ["the quirk" , "quick" , "e qui" , "and now for sth. completely different"] out1 << ["the qui(c)k", "(the )quick", "(th)e qui(ck)", "(-------------)th(e) (qu----------)i(ck-----)"] out2 << ["the qui(r)k", "(----)quick", "(--)e qui(--)", "(and now for s)th(.) (completely d)i(fferent)"] } def "compared strings contain control characters"() { def dist = new EditDistance(str1, str2) expect: renderer.render(str1, str2, dist.calculatePath()) == "$out1\n$out2" where: str1 = "one\ttwothree\bfour\rfive\fsix" str2 = "onetwo\nthreefour\rfive\tsix" out1 = "one(\\t)two(-~)three(\\b)four\\rfive(\\f)six" out2 = "one(-~)two(\\n)three(-~)four\\rfive(\\t)six" } def "compared strings contain same delimiters as used by diff renderer"() { def dist = new EditDistance(str1, str2) expect: renderer.render(str1, str2, dist.calculatePath()) == "$out1\n$out2" where: str1 = "q(u)i(c)k(" str2 = "q(u)i(r)k)" out1 = "q(u)i((c))k(()" out2 = "q(u)i((r))k())" } def "compare String with other CharSequence"() { def dist = new EditDistance(str, seq) expect: renderer.render(str, seq, dist.calculatePath()) == "$out1\n$out2" where: str = "the quick brown" seq << ["${"the"} quark ${"burn"}", new StringBuilder("the quark burn"), CharBuffer.wrap("the quark burn".toCharArray())] out1 = "the qu(ic)k b(-)r(ow)n" out2 = "the qu(ar)k b(u)r(--)n" } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/extension/000077500000000000000000000000001202022523300311645ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/extension/builtin/000077500000000000000000000000001202022523300326325ustar00rootroot00000000000000UnrollNameProviderSpec.groovy000066400000000000000000000032631202022523300404300ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/runtime/extension/builtin/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime.extension.builtin import org.spockframework.runtime.model.FeatureInfo import spock.lang.* class UnrollNameProviderSpec extends Specification { @Issue("http://issues.spockframework.org/detail?id=115") def "regex-like data values are substituted correctly (i.e. literally)"() { def feature = new FeatureInfo() feature.addParameterName("dataVar") def nameGenerator = new UnrollNameProvider(feature, "foo #dataVar bar") expect: nameGenerator.nameFor(value) == name where: value | name '$' | 'foo $ bar' /#([a-zA-Z_\$][\w\$]*)/ | /foo #([a-zA-Z_\$][\w\$]*) bar/ } def "data values are converted to strings in Groovy style"() { def feature = new FeatureInfo() feature.addParameterName("dataVar") def nameGenerator = new UnrollNameProvider(feature, "foo #dataVar bar") expect: nameGenerator.nameFor(value) == name where: value | name [1, 2, 3] | 'foo [1, 2, 3] bar' [a: 1, b: 2] | 'foo [a:1, b:2] bar' } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/000077500000000000000000000000001202022523300266035ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/AccessingOldValues.groovy000066400000000000000000000046361202022523300336010ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException class AccessingOldValues extends EmbeddedSpecification { def "basic usage"() { def list = [1,2,3] when: list << 4 then: list.size() == old(list.size()) + 1 } def "multiple references to old value are possible"() { def list = [1,2,3] when: list << 4 then: old(list.size()) == 3 old(list.size()) == 3 } def "multiple references are captured individually"() { def list = [1,2,3] when: list << 4 then: old(list.remove(0)) == 1 old(list.remove(0)) == 2 } def "may occur in nested position"() { def list = [1,2,3] when: list << 4 then: (0..2).every { old(list.size()) == 3 } } def "can access data-driven value"() { when: list << "elem" then: list.size() == old(list.size()) + 1 where: list << [[], [1], [1,2,3]] } def "refers to an expression's value before entering the previous when-block"() { def list = [1,2,3] when: list << 4 then: old(list.size()) == 3 when: list << 5 then: old(list.size()) == 4 } def "works in presence of exception condition"() { def list = [1,2,3] when: list << 4 throw new Exception() then: thrown(Exception) list.size() == old(list.size()) + 1 } def "may only occur in a then-block"() { when: compiler.compileFeatureBody """ def list = [1,2,3] when: old(list.size()) == 3 then: true """ then: InvalidSpecCompileException e = thrown() e.line == 2 } def "may occur outside of a condition"() { def list = [1,2,3] when: list << 4 then: def size = old(list.size()) size == 3 } }AssertionErrorMessages.groovy000066400000000000000000000022331202022523300344440ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.runtime.SpockAssertionError import spock.lang.* @Issue("http://issues.spockframework.org/detail?id=95") class AssertionErrorMessages extends Specification { def "assertion error returns (same) message for getMessage() and toString()"() { def e = createSpockAssertionError() expect: e.message e.message.contains("1 == 2") e.message == e.toString() } def createSpockAssertionError() { try { assert 1 == 2 } catch (SpockAssertionError e) { return e } } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/Blocks.groovy000066400000000000000000000037771202022523300313050ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException import static org.spockframework.runtime.model.BlockKind.* import org.spockframework.runtime.RunContext import org.spockframework.runtime.SpecInfoBuilder class Blocks extends EmbeddedSpecification { def "labels and comments"() { def specClass = compiler.compileSpecBody(""" def m1() { setup: "setup" and: "setup2" when: "when" and: "when2" then: "then" and: "then2" where: "where" and: "where2" } def m2() { expect: "expect" and: "expect2" } def m3() { given: "given" and: def x expect: def y and: "and" where: "" and: z << 1 } """) def specInfo = new SpecInfoBuilder(specClass).build() expect: def m1 = specInfo.features[0] m1.blocks*.kind == [SETUP,WHEN,THEN,WHERE] m1.blocks*.texts.flatten() == ["setup","setup2","when","when2","then","then2","where","where2"] and: def m2 = specInfo.features[1] m2.blocks*.kind == [EXPECT] m2.blocks*.texts.flatten() == ["expect","expect2"] and: def m3 = specInfo.features[2] m3.blocks*.kind == [SETUP,EXPECT,WHERE] m3.blocks*.texts.flatten() == ["given","and",""] } def "unknown label"() { when: compiler.compileFeatureBody(""" setuppp: def a = 1 """) then: InvalidSpecCompileException e = thrown() e.line == 1 } }BuiltInMembersOfClassSpecification.groovy000066400000000000000000000036461202022523300366410ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import org.spockframework.runtime.InvalidSpecException import spock.lang.* /** * @author Peter Niederwieser */ class BuiltInMembersOfClassSpecification extends EmbeddedSpecification { def "can be referred to by simple name"() { when: runner.run """ class Foo extends spock.lang.Specification { def foo() { when: throw new Exception() then: thrown(Exception) } } """ then: noExceptionThrown() } def "can be referred to by 'this'"() { when: runner.run """ class Foo extends spock.lang.Specification { def foo() { def list = this.Mock(List) expect: list != null } } """ then: noExceptionThrown() } def "cannot be referred to by 'super' (since Groovy 1.8.1)"() { when: runner.run """ class Foo extends spock.lang.Specification { def foo() { def list = super.Mock(List) expect: list != null } } """ then: thrown(IllegalAccessError) } @Issue("http://issues.spockframework.org/detail?id=43") def "can be used in field initializers"() { when: runner.run """ class Foo extends spock.lang.Specification { def list = Mock(List) def foo() { expect: true } } """ then: notThrown(InvalidSpecException) } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/CleanupBlocks.groovy000066400000000000000000000032131202022523300325760ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import spock.lang.FailsWith import spock.lang.Specification class CleanupBlocks extends Specification { def "basic usage"() { def x setup: x = 1 expect: x == 1 cleanup: x = 0 } def "may access all previously defined local vars"() { def a setup: def b when: String c then: List d cleanup: a = 0 b = 0 c = "" d = null } @FailsWith(IllegalArgumentException) def "is executed if no exception is thrown"() { def a = 1 cleanup: a = 0 if (a == 0) throw new IllegalArgumentException() } @FailsWith(IllegalArgumentException) def "is executed if exception is thrown"() { def a = 1 throw new Exception() cleanup: a = 0 if (a == 0) throw new IllegalArgumentException() } @FailsWith(IllegalArgumentException) def "if exception is thrown, code between occurrence of exception and cleanup-block is not executed"() { def a = 1 throw new IllegalArgumentException() a = 2 cleanup: assert a == 1 } } CompileTimeErrorReporting.groovy000066400000000000000000000032451202022523300351120ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.junit.internal.runners.model.MultipleFailureException import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException class CompileTimeErrorReporting extends EmbeddedSpecification { def "multiple method declaration errors"() { when: compiler.compileSpecBody """ ASpec() {} // constructor not allowed def setUp() {} // wrong spelling def feature(arg) { // arg not allowed expect: true } """ then: MultipleFailureException e = thrown() e.failures*.class == [InvalidSpecCompileException] * 3 } def "multiple errors within a method"() { when: compiler.compileFeatureBody """ when: def x = 42 def y = old(x) // old used outside of then block then: thrown(IllegalArgumentException) thrown(IOException) // more than one thrown call thrown(AssertionError) // more than one thrown call where: println "hi" // not a parameterization """ then: MultipleFailureException e = thrown() e.failures*.class == [InvalidSpecCompileException] * 4 } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/ExpectBlocks.groovy000066400000000000000000000023531202022523300324430ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException /** * @author Peter Niederwieser */ class ExpectBlocks extends EmbeddedSpecification { def "may not contain exception conditions"() { when: compiler.compileFeatureBody(""" expect: thrown(RuntimeException) """) then: thrown(InvalidSpecCompileException) } def "may not contain interactions"() { when: compiler.compileFeatureBody(""" def l = Mock(List) expect: l.size() >> 5 """) then: InvalidSpecCompileException e = thrown() e.line == 2 } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/FeatureFiltering.groovy000066400000000000000000000050341202022523300333130ustar00rootroot00000000000000 /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.junit.runner.manipulation.Filter import org.junit.runner.Request import org.spockframework.EmbeddedSpecification import spock.lang.Issue class FeatureFiltering extends EmbeddedSpecification { def "filter selected feature methods"() { def clazz = compiler.compileSpecBody(""" static log = "" def feature1() { setup: log += "1" } def feature2() { setup: log += "2" } def feature3() { setup: log += "3" } """) def request = Request.aClass(clazz).filterWith( [shouldRun: { desc -> desc.methodName == "feature2" }, describe: { "feature2" }] as Filter) when: def result = runner.runRequest(request) then: clazz.log == "2" result.runCount == 1 result.failureCount == 0 result.ignoreCount == 0 } def "filtering all feature methods results in exception"() { def clazz = compiler.compileSpecBody(""" static log = "" def feature1() { setup: log += "1" } def feature2() { setup: log += "2" } def feature3() { setup: log += "3" } """) def request = Request.aClass(clazz).filterWith([shouldRun: { false }, describe: { "xxx" }] as Filter) when: runner.runRequest(request) then: Exception e = thrown() e.message.contains "xxx" clazz.log == "" } @Issue("http://issues.spockframework.org/detail?id=76") def "filtering across inheritance chain"() { def derived = compiler.compileWithImports(""" abstract class Base extends Specification { def feature1() { expect: true } def feature2() { expect: true } } class Derived extends Base { def feature3() { expect: true } def feature4() { expect: true } } """)[0] def request = Request.aClass(derived).filterWith( [shouldRun: { desc -> desc.methodName in ["feature1", "feature3"] }, describe: { "xxx" }] as Filter) when: def result = runner.runRequest(request) then: result.runCount == 2 result.failureCount == 0 result.ignoreCount == 0 } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/FeatureMethods.groovy000066400000000000000000000043541202022523300327770ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.junit.runner.notification.RunListener import spock.lang.Specification import spock.util.EmbeddedSpecRunner import spock.lang.Issue /** * * @author Peter Niederwieser */ class FeatureMethods extends Specification { def "cannot be called from user code"() { when: featureMethod() then: thrown(MissingMethodException) } @Issue("http://issues.spockframework.org/detail?id=229") def "don't make it into the class file with their original name"() { expect: !getClass().getDeclaredMethods().any { it.name == "featureMethod" } } def "are nevertheless reported with their original name"() { def runner = new EmbeddedSpecRunner() RunListener listener = Mock() runner.listeners << listener when: runner.runSpecBody(""" def "original name"() { expect: true } """) then: 1 * listener.testStarted({it.methodName == "original name"}) 1 * listener.testFinished({it.methodName == "original name"}) } def "can.have?names#con/tain!ing~any`char(act \\ers?!"() { expect: true } def "can have names containing any characters in embedded specs"() { def runner = new EmbeddedSpecRunner() RunListener listener = Mock() runner.listeners << listener when: runner.runSpecBody(""" def "can.have?names#con/tain!ing~any`char(act \\\\ers?!"() { expect: true } """) then: 1 * listener.testStarted({it.methodName == "can.have?names#con/tain!ing~any`char(act \\ers?!"}) 1 * listener.testFinished({it.methodName == "can.have?names#con/tain!ing~any`char(act \\ers?!"}) } def featureMethod() { expect: true } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/FeatureSorting.groovy000066400000000000000000000056451202022523300330250ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.junit.runner.Request import org.junit.runner.Description import org.spockframework.EmbeddedSpecification import spock.lang.* import spock.util.EmbeddedSpecCompiler class FeatureSorting extends EmbeddedSpecification { @Shared List clazzes = new EmbeddedSpecCompiler().compileWithImports(""" class Base extends Specification { def aaa() { expect: true } def bbb() { expect: true } def ccc() { expect: true } } class Derived extends Base { def abc() { expect: true } def bcd() { expect: true } def cde() { expect: true } } """) @Shared Class base = clazzes.find { it.simpleName == "Base" } @Shared Class derived = clazzes.find { it.simpleName == "Derived" } def "features are initially sorted in declaration order"() { when: // need to open new context to guard against reordering from outside (OptimizeRunOrderExtension etc.) def description = runner.withNewContext { Request.aClass(clazz).runner.description } then: description.children*.methodName == methodOrder where: clazz | methodOrder base | ["aaa", "bbb", "ccc"] derived | ["aaa", "bbb", "ccc", "abc", "bcd", "cde"] } def "sort in lexicographical order"() { when: def description = runner.withNewContext { Request.aClass(clazz).sortWith(new LexicographicalComparator()).runner.description } then: description.children*.methodName == methodOrder where: clazz | methodOrder base | ["aaa", "bbb", "ccc"] derived | ["aaa", "abc", "bbb", "bcd", "ccc", "cde"] } def "sort in reverse lexicographical order"() { when: def description = runner.withNewContext { Request.aClass(clazz).sortWith(new ReverseLexicographicalComparator()).runner.description } then: description.children*.methodName == methodOrder where: clazz | methodOrder base | ["ccc", "bbb", "aaa"] derived | ["cde", "ccc", "bcd", "bbb", "abc", "aaa"] } static class LexicographicalComparator implements Comparator { int compare(Description d1, Description d2) { d1.methodName <=> d2.methodName } } static class ReverseLexicographicalComparator implements Comparator { int compare(Description d1, Description d2) { d2.methodName <=> d1.methodName } } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/FixtureMethods.groovy000066400000000000000000000050721202022523300330300ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException import spock.lang.Issue class FixtureMethods extends EmbeddedSpecification { static log def setup() { log = [] } def "are run in correct order"() { when: runner.runSpecBody """ def getLog() { org.spockframework.smoke.FixtureMethods.log } def setup() { log << "s" } def cleanup() { log << "c" } def setupSpec() { log << "ss" } def cleanupSpec() { log << "cs" } def feature() { expect: true } """ then: log == ["ss", "s", "c", "cs"] } def "are run in correct order across class hierarchy"() { when: runner.runWithImports """ @Ignore class Base extends Specification { def getLog() { org.spockframework.smoke.FixtureMethods.log } def setup() { log << "s1" } def cleanup() { log << "c1" } def setupSpec() { log << "ss1" } def cleanupSpec() { log << "cs1" } } class Derived extends Base { def getLog() { org.spockframework.smoke.FixtureMethods.log } def setup() { log << "s2" } def cleanup() { log << "c2" } def setupSpec() { log << "ss2" } def cleanupSpec() { log << "cs2" } def feature() { expect: true } } """ then: log == ["ss1", "ss2", "s1", "s2", "c2", "c1", "cs2", "cs1"] } @Issue("http://issues.spockframework.org/detail?id=139") def "setupSpec() may not access instance fields (only @Shared and static fields)"() { when: compiler.compileSpecBody """ def x = 42 def setupSpec() { println x } """ then: InvalidSpecCompileException e = thrown() e.message.contains("@Shared") } @Issue("http://issues.spockframework.org/detail?id=139") def "cleanupSpec() may not access instance fields (only @Shared and static fields)"() { when: compiler.compileSpecBody """ def x = 42 def cleanupSpec() { 3.times { x = 0 } } """ then: InvalidSpecCompileException e = thrown() e.message.contains("@Shared") } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/GroovyCallChain.groovy000066400000000000000000000022121202022523300330730ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke /** * Important: This file needs to be exact copy of JavaCallChain.java. * * @author Peter Niederwieser */ public class GroovyCallChain { public void a() { b(); } private int b() { new Inner().inner() return 0; } static void c(String foo, String bar) { throw new CallChainException(); } class Inner { def inner() { new StaticInner().staticInner() } } static class StaticInner { def staticInner() { c("foo", "bar") } } } InteractionsAndExceptionConditions.groovy000066400000000000000000000022551202022523300367750ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import spock.lang.Specification /** * * @author Peter Niederwieser */ class InteractionsAndExceptionConditions extends Specification { def "interaction followed by exception condition"() { List list = Mock() when: list.add(1) throw new RuntimeException() then: 1 * list.add(1) thrown(RuntimeException) } def "exception condition followed by interaction"() { List list = Mock() when: list.add(1) throw new RuntimeException() then: thrown(RuntimeException) 1 * list.add(1) } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/MethodAccessibility.groovy000077500000000000000000000020621202022523300340050ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import spock.lang.Shared import spock.lang.Specification /** * A ... * @author Peter Niederwieser */ class MethodAccessibility extends Specification { @Shared numCalls = 0 private setup() { numCalls++ } protected cleanup() { numCalls++ } private setupSpec() { numCalls++ } def cleanupSpec() { assert numCalls == 4 } private "a feature"() { numCalls++ expect: true } }MethodExecutionOrder.groovy000077500000000000000000000033471202022523300341050ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import spock.lang.* /** * @author Peter Niederwieser */ @Stepwise class MethodExecutionOrder extends Specification { @Shared order = [] def cleanup() { getOrder() << "c" } def cleanupSpec() { assert getOrder() == ["ss","s",3,"c","s",4,"c","s",5,"c","s",6,"c","s",7,"c","s",8,"c","s",9,"c","s",10,"c"] } def "help, I need somebody"() { order << "h" } def "first feature"() { order << 3 expect: true } def secondFeatureWithStandardName() { getOrder() << 4 expect: true } def "just helping out"() { getOrder() << "h" } def "strangely named feature"() { getOrder() << 5 expect: 1 } def "very very long name but still nothing but a feature"() { getOrder() << 6 expect: 1 } def "short one"() { getOrder() << 7 def x = "blah" when: x = x.reverse() then: x == "halb" } def setup() { getOrder() << "s" } def "helpless"() { getOrder() << "h" } def setupSpec() { getOrder() << "ss" } def "parameterized feature"() { getOrder() << x expect: 1 where : x << [8, 9, 10] } }MisspelledFixtureMethods.groovy000066400000000000000000000033221202022523300347670ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException /** * @author Peter Niederwieser */ class MisspelledFixtureMethods extends EmbeddedSpecification { def "misspelled setup causes compile error"() { when: compiler.compileSpecBody(""" def setUp() {} """) then: thrown(InvalidSpecCompileException) } def "misspelled cleanup causes compile error"() { when: compiler.compileSpecBody(""" def cLeanup() {} """) then: thrown(InvalidSpecCompileException) } def "misspelled setupSpec causes compile error"() { when: compiler.compileSpecBody(""" def setupspec() {} """) then: thrown(InvalidSpecCompileException) } def "misspelled cleanupSpec causes compile error"() { when: compiler.compileSpecBody(""" def CleanupSpec() {} """) then: thrown(InvalidSpecCompileException) } def "correctly spelled setup compiles successfully"() { when: compiler.compileSpecBody(""" def setup() {} """) then: noExceptionThrown() } }MixingExpectAndWhenThenBlocks.groovy000066400000000000000000000015521202022523300356240ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import spock.lang.Specification class MixingExpectAndWhenThenBlocks extends Specification { def x = 0 def mix() { expect: x == 0 when: x++ then: x == old(x) + 1 expect: x == 1 } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/SetupBlocks.groovy000077500000000000000000000034521202022523300323170ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException /** * * @author Peter Niederwieser */ class SetupBlocks extends EmbeddedSpecification { def "implicit"() { def a = 1 } def "explicit"() { setup: def a = 1 } def "implicit and explicit"() { def a = 1 setup: def b = 2 } def "named"() { setup: "an a" def a = 1 } def "and-ed"() { setup: def a = 1 and: def b = 2 } def "full house"() { def a = 1 def b = 2 setup: "c" def c = 3 and: "d" def d = 4 and: def e = 5 } def "consecutive setup's"() { when: compiler.compileFeatureBody """ setup: a = 1 setup: b = 2 """ then: InvalidSpecCompileException e = thrown() e.line == 2 } def "multiple setup's"() { when: compiler.compileFeatureBody """ setup: a = 1 expect: true setup: b = 2 """ then: thrown(InvalidSpecCompileException) } def "blocks are executed"() { def a = 1 setup: a += 1 and: "blah"; a += 2 expect: a == 4 } def "given is alias for setup"() { def a given: a = 1 expect: a == 1 } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/SharedFields.groovy000066400000000000000000000026101202022523300324060ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import spock.lang.Issue class SharedFields extends EmbeddedSpecification { def "can be accessed from subclass"() { when: runner.runWithImports """ class Foo extends Specification { @Shared x = "abc" } class Bar extends Foo { def bar() { expect: x.size() == 3 } } """ then: noExceptionThrown() } @Issue("http://issues.spockframework.org/detail?id=112") def 'can have name that starts with $'() { when: runner.runWithImports ''' class Foo extends Specification { def $unshared = 0 @Shared $shared = 0 def test() { expect: ++$unshared == 1 ++$shared == count where: count << [1,2,3] } } ''' then: noExceptionThrown() } }SharedFieldsInSuperclass.groovy000066400000000000000000000015311202022523300346640ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smokepackage org.spockframework.smoke import spock.lang.* abstract class SharedFieldsInSuperclassBase extends Specification { @Shared private String sharedPrivate = "sharedPrivate" @Shared protected String sharedProtected = "sharedProtected" @Shared public String sharedPublic = "sharedPublic" @Shared String sharedProperty = "sharedProperty" @Issue("http://issues.spockframework.org/detail?id=151") def "can access shared private field"() { expect: sharedPrivate == "sharedPrivate" } def "can access shared protected field"() { expect: sharedProtected == "sharedProtected" } def "can access shared public field"() { expect: sharedPublic == "sharedPublic" } def "can access shared property"() { expect: sharedProperty == "sharedProperty" } } class SharedFieldsInSuperclass extends SharedFieldsInSuperclassBase {} SharedVsStaticFields.groovy000077500000000000000000000040101202022523300340070ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.junit.ComparisonFailure import org.spockframework.EmbeddedSpecification class SharedVsStaticFields extends EmbeddedSpecification { def "shared fields are not shared between subsequent runs"() { setup: def clazzes = compiler.compileWithImports(""" import org.junit.runner.RunWith import org.junit.runners.Suite import org.junit.runners.Suite.SuiteClasses class SharedField extends Specification { @Shared x = 42 def "increment"() { x++ expect: x == 43 } def "increment again"() { x++ expect: x == 44 } } @RunWith(Suite) @SuiteClasses([SharedField, SharedField]) class SharedFieldSuite {} """) when: runner.runClass(clazzes.find { it.simpleName == "SharedFieldSuite" }) then: noExceptionThrown() } def "static fields are shared between subsequent runs"() { setup: def clazzes = compiler.compileWithImports(""" import org.junit.runner.RunWith import org.junit.runners.Suite import org.junit.runners.Suite.SuiteClasses class StaticField extends Specification { static x = 42 def "increment"() { x++ expect: x == 43 } def "increment again"() { x++ expect: x == 44 } } @RunWith(Suite) @SuiteClasses([StaticField, StaticField]) class StaticFieldSuite {} """) when: runner.runClass(clazzes.find { it.simpleName == "StaticFieldSuite" }) then: thrown(ComparisonFailure) } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/SpecFields.groovy000077500000000000000000000067541202022523300321120ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import spock.lang.Shared import spock.lang.Specification import spock.lang.Stepwise /** * @author Peter Niederwieser */ class InitializationOfUnsharedFields extends Specification { def a def b = 1 int c int d = 1 def setup() { assert a == null assert b == 1 assert c == 0 assert d == 1 b = 2 } def "feature 1"() { expect: a == null b == 2 c == 0 d == 1 cleanup: // should have no effect on subsequent execution a = b = c = d = 11111 } def "feature 2"() { expect: a == null b == 2 c == 0 d == 1 } } @Stepwise class InitializationOfSharedFields extends Specification { @Shared def a @Shared def b = 1 @Shared int c @Shared int d = 1 def setupSpec() { assert a == null assert b == 1 assert c == 0 assert d == 1 b = 2 } def setup() { assert a == null assert b == 2 assert c == 0 || c == 2 // changed by setup assert d == 1 || d == 2 // changed by feature 1 c = 2 } def "feature 1"() { expect: a == null b == 2 c == 2 d == 1 cleanup: d = 2 } def "feature 2"() { expect: a == null b == 2 c == 2 d == 2 } } class DefaultValuesOfUnsharedFields extends Specification { boolean f1 char f2 byte f3 short f4 int f5 long f6 float f7 double f8 Boolean ff1 Character ff2 Byte ff3 Short ff4 Integer ff5 Long ff6 Float ff7 Double ff8 def ff9 Map ff10 def "primitive types"() { expect: f1 == false f2 == (char)0 f3 == (byte)0 f4 == (short)0 f5 == 0 f6 == 0l f7 == 0f f8 == 0d } def "wrapper types"() { expect: ff1 == null ff2 == null ff3 == null ff4 == null ff5 == null ff6 == null ff7 == null ff8 == null } def "reference types"() { expect: ff9 == null ff10 == null } } class DefaultValuesOfSharedFields extends Specification { @Shared boolean f1 @Shared char f2 @Shared byte f3 @Shared short f4 @Shared int f5 @Shared long f6 @Shared float f7 @Shared double f8 // shared fields that differ only in their capitalization are not allowed, so we add another 'F' @Shared Boolean FF1 @Shared Character FF2 @Shared Byte FF3 @Shared Short FF4 @Shared Integer FF5 @Shared Long FF6 @Shared Float FF7 @Shared Double FF8 @Shared def FF9 @Shared Map FF10 def "primitive types"() { expect: f1 == false f2 == (char)0 f3 == (byte)0 f4 == (short)0 f5 == 0 f6 == 0l f7 == 0f f8 == 0d } def "wrapper types"() { expect: FF1 == null FF2 == null FF3 == null FF4 == null FF5 == null FF6 == null FF7 == null FF8 == null } def "reference types"() { expect: FF9 == null FF10 == null } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/SpecInheritance.groovy000066400000000000000000000121721202022523300331210ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import spock.lang.* import org.spockframework.compiler.InvalidSpecCompileException class SpecInheritance extends EmbeddedSpecification { def "fixture methods are run in correct order"() { def classes = compiler.compileWithImports(""" class Base extends Specification { static log = [] def setupSpec() { log << "ss1" } def setup() { log << "s1" } def cleanup() { log << "c1" } def cleanupSpec() { log << "cs1" } } class Derived extends Base { def setupSpec() { log << "ss2" } def setup() { log << "s2" } def cleanup() { log << "c2" } def cleanupSpec() { log << "cs2" } def "some feature method"() { expect: true } } """) def derived = classes.find { it.simpleName == "Derived" } when: runner.runClass(derived) then: derived.log == ["ss1", "ss2", "s1", "s2", "c2", "c1", "cs2", "cs1"] } def "cannot call super method from fixture method"() { when: compiler.compileWithImports(""" class Base extends Specification { def $method() {} } class Derived extends Base { def $method() { super.$method() } def feature() { expect: true } } """) then: thrown(InvalidSpecCompileException) where: method << ["setup", "cleanup", "setupSpec", "cleanupSpec"] } def "feature methods are run in correct order"() { def classes = compiler.compileWithImports(""" class Base extends Specification { static log = [] def "1"() { log << 1 expect: true } def "2"() { log << 2 expect: true } } class Derived extends Base { def "3"() { log << 3 expect: true } def "4"() { log << 4 expect: true } } """) def derived = classes.find { it.simpleName == "Derived" } when: runner.runClass(derived) then: derived.log == [1, 2, 3, 4] } def "exception in base class fixture method causes failure"() { def classes = compiler.compileWithImports(""" class Base extends Specification { def ${fixtureMethod}() { throw new IOException() } } class Derived extends Base { def ${fixtureMethod}() {} def feature() { expect: true } } """) def derived = classes.find { it.simpleName == "Derived" } when: runner.runClass(derived) then: thrown(IOException) where: fixtureMethod << ["setup", "cleanup", "setupSpec", "cleanupSpec"] } def "junit reports correct run/failure/ignore counts"() { def classes = compiler.compileWithImports(""" class Base extends Specification { def f1() { expect: true } def f2() { expect: false } @Ignore def f3() { expect: false } } class Derived extends Base { def f4() { expect: false } def f5() { expect: true } } """) def derived = classes.find { it.simpleName == "Derived" } runner.throwFailure = false when: def result = runner.runClass(derived) then: result.runCount == 4 result.failureCount == 2 result.ignoreCount == 1 } @Issue("http://code.google.com/p/spock/issues/detail?id=53") def "feature methods cannot be overridden"() { def classes = compiler.compileWithImports(""" class Base extends Specification { static log = [] def foo() { setup: log << 1 } } class Derived extends Base { def foo() { setup: log << 2 } } """) def derived = classes.find { it.simpleName == "Derived" } when: def result = runner.runClass(derived) then: derived.log == [1, 2] result.runCount == 2 } def "private feature methods with same name can coexist peacefully in inheritance chain"() { def classes = compiler.compileWithImports(""" class Base extends Specification { static log = [] private foo() { setup: log << 1 } } class Derived extends Base { private foo() { setup: log << 2 } } """) def derived = classes.find { it.simpleName == "Derived" } when: def result = runner.runClass(derived) then: derived.log == [1, 2] result.runCount == 2 } def "can invoke super.helperMethod()"() { def classes = compiler.compileWithImports(""" class Base extends Specification { def helperMethod() { return "helper invoked" } } class Derived extends Base { def helperMethod() { super.helperMethod() } def feature() { expect: helperMethod() == "helper invoked" } } """) def derived = classes.find { it.simpleName == "Derived" } when: runner.runClass(derived) then: noExceptionThrown() } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/SpecRecognition.groovy000066400000000000000000000046331202022523300331530ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.runtime.SpockAssertionError import spock.lang.* import org.spockframework.EmbeddedSpecification /** * @author Peter Niederwieser */ class SpecRecognition extends EmbeddedSpecification { @Unroll def "is properly recognized"() { when: runner.run """ $importStat class Foo extends $baseClass { def foo() { expect: false } } """ then: thrown(SpockAssertionError) where: [importStat , baseClass ] << [ ["import spock.lang.Specification" , "Specification" ], ["" , "spock.lang.Specification" ], ["import org.spockframework.smoke.Intermediary1", "Intermediary1" ], ["" , "org.spockframework.smoke.Intermediary2" ], ["" , "org.spockframework.smoke.AbstractIntermediary"] ] } def "is properly recognized when inheriting from Specification base class through intermediary in same compilation unit"() { def classes = compiler.compile(""" import spock.lang.Specification class MyCustomBaseClass extends Specification {} class Foo extends MyCustomBaseClass { def foo() { expect: false } } """) def clazz = classes.find { it.name == "Foo" } when: runner.runClass(clazz) then: thrown(SpockAssertionError) } } class MySpecification extends Specification {} class MyMySpecification extends MySpecification {} class Intermediary1 extends Specification {} class Intermediary2 extends spock.lang.Specification {} abstract class AbstractIntermediary extends Specification {}spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/SpecWithoutFeatures.groovy000066400000000000000000000021221202022523300340240ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.runtime.ConditionNotSatisfiedError import spock.lang.FailsWith import spock.lang.Specification /** * @author Peter Niederwieser */ class SpecWithoutFeatures extends Specification { @FailsWith(ConditionNotSatisfiedError) def setupSpec() { assert false } @FailsWith(ConditionNotSatisfiedError) def cleanupSpec() { assert false } def setup() { assert false } def cleanup() { assert false } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/StackTraceFiltering.groovy000066400000000000000000000133341202022523300337460ustar00rootroot00000000000000/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.spockframework.EmbeddedSpecification import org.spockframework.runtime.ConditionNotSatisfiedError import spock.lang.Issue import spock.lang.Unroll import org.spockframework.util.Identifiers import org.spockframework.runtime.WrongExceptionThrownError /** * @author Peter Niederwieser */ @Issue("http://issues.spockframework.org/detail?id=21") class StackTraceFiltering extends EmbeddedSpecification { def "unsatisfied implicit condition"() { when: runner.runFeatureBody """ expect: false """ then: ConditionNotSatisfiedError e = thrown() stackTraceLooksLike(e, """ apackage.ASpec|a feature|1 """) } def "unsatisfied explicit condition"() { when: runner.runFeatureBody """ expect: assert false """ then: ConditionNotSatisfiedError e = thrown() stackTraceLooksLike(e, """ apackage.ASpec|a feature|1 """) } @Unroll("exception in #displayName") def "exception in call chain"() { when: runner.runFeatureBody """ setup: new $chain().a() """ then: CallChainException e = thrown() stackTraceLooksLike(e, """ $chain|c|35 $chain\$StaticInner|staticInner|46 $chain\$Inner|inner|40 $chain|b|30 $chain|a|26 apackage.ASpec|a feature|2 """) where: chain << ["org.spockframework.smoke.GroovyCallChain", "org.spockframework.smoke.JavaCallChain"] displayName << ["Groovy call chain", "Java call chain"] } def "exception in closure"() { when: runner.runFeatureBody """ setup: def x // need some statement between label and closure (otherwise Groovy would consider the following a block) { -> assert false }() """ then: ConditionNotSatisfiedError e = thrown() stackTraceLooksLike e, """ apackage.ASpec|a feature_closure1|- apackage.ASpec|a feature|3 """ } def "exception in closure in field initializer"() { when: runner.runSpecBody """ def x = { assert false }() def foo() { expect: true } """ then: ConditionNotSatisfiedError e = thrown() // no idea why setup_closure1 appears twice stackTraceLooksLike e, """ apackage.ASpec|\$spock_initializeFields_closure1|- apackage.ASpec|\$spock_initializeFields_closure1|- apackage.ASpec|\$spock_initializeFields|1 """ } @Issue("http://issues.spockframework.org/detail?id=80") def "stack trace is truncated below invocation of fixture method"() { when: runner.runSpecBody """ def ${fixtureMethod}() { assert false } def feature() { expect: true } """ then: ConditionNotSatisfiedError e = thrown() stackTraceLooksLike e, """ apackage.ASpec|$fixtureMethod|- """ where: fixtureMethod << Identifiers.FIXTURE_METHODS } @Issue("http://issues.spockframework.org/detail?id=75") def "feature method names are also restored for base specs"() { when: runner.runWithImports """ abstract class Base extends Specification { def "let me fail"() { expect: false } } class Derived extends Base {} """ then: ConditionNotSatisfiedError e = thrown() stackTraceLooksLike e, """ apackage.Base|let me fail|3 """ } @Issue("http://issues.spockframework.org/detail?id=33") def "when creation of data provider fails, stack trace points to corresponding parameterization"() { when: runner.runSpecBody """ def foo() { expect: true where: x << [1] y << { throw new RuntimeException() }() z << [1] } """ then: RuntimeException e = thrown() stackTraceLooksLike e, """ apackage.ASpec|foo_closure1|7 apackage.ASpec|foo_closure1|- apackage.ASpec|foo|7 """ } @Issue("http://issues.spockframework.org/detail?id=33") def "when data processor fails, stack trace source position points to corresponding parameterization"() { when: runner.runSpecBody """ def foo(int x, Class y, int z) { expect: true where: x << [1] $parameterization z << [1] } """ then: RuntimeException e = thrown() stackTraceLooksLike e, """ apackage.ASpec|foo|7 """ where: parameterization << ["y << [1]", "y = 1", "[_, y, _] << [[1], [1], [1]]"] } @Issue("http://issues.spockframework.org/detail?id=90") def "stack trace for explicit condition in setup block has line number"() { when: runner.runSpecBody """ def setup() { assert 1 > 2 } def foo() { expect: true } """ then: ConditionNotSatisfiedError e = thrown() e.stackTrace[0].lineNumber == 2 } @Issue("http://issues.spockframework.org/detail?id=90") def "stack trace for nested explicit condition has line number"() { when: runner.runFeatureBody """ setup: 1.times { assert 1 > 2 } """ then: ConditionNotSatisfiedError e = thrown() e.stackTrace[0].lineNumber == 2 } @Issue("http://issues.spockframework.org/detail?id=156") def "causes get filtered as well"() { when: runner.runFeatureBody """ when: throw new IOException() then: thrown(RuntimeException) """ then: WrongExceptionThrownError e = thrown() stackTraceLooksLike e, """ spock.lang.Specification|thrown|- apackage.ASpec|a feature|5 """ stackTraceLooksLike e.cause, """ apackage.ASpec|a feature|2 """ } }StaticMethodsInSpecifications.groovy000066400000000000000000000031141202022523300357200ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import org.junit.ComparisonFailure import org.spockframework.EmbeddedSpecification import spock.lang.Issue class StaticMethodsInSpecifications extends EmbeddedSpecification { def "may contain conditions"() { when: runner.runSpecBody """ def foo() { expect: bar() } static void bar() { assert 1 + 1 == 3 } """ then: thrown(ComparisonFailure) } @Issue("http://issues.spockframework.org/detail?id=35") def "may not contain interactions"() { when: runner.runSpecBody """ def foo() { List list = Mock() when: list.add("elem") then: interaction { elementAdded(list) } } static bar(list) { 1 * list.add() } """ then: thrown(VerifyError) } @Issue("http://issues.spockframework.org/detail?id=35") def "may not create mocks"() { when: runner.runSpecBody """ def foo() { setup: bar() } static bar() { List list = Mock() } """ then: thrown(VerifyError) } }VoidGroovyStaticMethod.groovy000066400000000000000000000013501202022523300344120ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke /** * @author Peter Niederwieser */ class VoidGroovyStaticMethod { static void foo() {} }VoidMethodCallsInExpectBlocks.groovy000066400000000000000000000035661202022523300356240ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import spock.lang.Issue import spock.lang.Specification import static java.util.Collections.reverse import static org.spockframework.smoke.VoidGroovyStaticMethod.foo /** * @author Peter Niederwieser */ @Issue("http://issues.spockframework.org/detail?id=25") class VoidMethodCallsInExpectBlocks extends Specification { def "invocation of void Groovy instance method"() { expect: voidGroovyInstanceMethod() this.voidGroovyInstanceMethod() } def "invocation of void Groovy static method"() { expect: voidGroovyStaticMethod() VoidMethodCallsInExpectBlocks.voidGroovyStaticMethod() } def "invocation of void Java instance method"() { expect: [].clear() } def "invocation of void Java static method"() { expect: Collections.shuffle([]) } def "invocation of void default Groovy method"() { expect: print "" } def "invocation of void default Groovy static method"() { expect: sleep(1) Object.sleep(1) } def "invocation of statically imported void Groovy method"() { expect: foo() } def "invocation of statically imported void Java method"() { expect: reverse([]) } void voidGroovyInstanceMethod() {} static void voidGroovyStaticMethod() {} }VoidMethodCallsInThenBlocks.groovy000066400000000000000000000037121202022523300352630ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import spock.lang.Issue import spock.lang.Specification import static java.util.Collections.reverse import static org.spockframework.smoke.VoidGroovyStaticMethod.foo /** * @author Peter Niederwieser */ @Issue("http://issues.spockframework.org/detail?id=25") class VoidMethodCallsInThenBlocks extends Specification { def "invocation of void Groovy instance method"() { when: "" then: voidGroovyInstanceMethod() this.voidGroovyInstanceMethod() } def "invocation of void Groovy static method"() { when: "" then: voidGroovyStaticMethod() VoidMethodCallsInThenBlocks.voidGroovyStaticMethod() } def "invocation of void Java instance method"() { when: "" then: [].clear() } def "invocation of void Java static method"() { when: "" then: Collections.shuffle([]) } def "invocation of void default Groovy method"() { when: "" then: print "" } def "invocation of void default Groovy static method"() { when: "" then: sleep(1) Object.sleep(1) } def "invocation of statically imported void Groovy method"() { when: "" then: foo() } def "invocation of statically imported void Java method"() { when: "" then: reverse([]) } void voidGroovyInstanceMethod() {} static void voidGroovyStaticMethod() {} } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/WhenThenBlocks.groovy000077500000000000000000000031771202022523300327430ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke import spock.lang.Specification /** * @author Peter Niederwieser */ class WhenThenBlocks extends Specification { def "basic usage"() { def x when: x = 1 then: x == 1 } def "named blocks"() { def x when: "x is assigned 1" x = 1 then: "x is 1" x == 1 } def "and-ed blocks"() { def x, y when: x = 1 and: y = 2 then: x == 1 and: "y is 2" y == 2 } def "chained blocks"() { def x, y when: x = 1 and: y = 2 then: x == 1 then: "y is 2" y == 2 } def "combination of and-ed and chained block"() { def x, y, z when: x = 1; y = 2; z = 3 then: x == 1 and: y == 2 then: z == 3 } def "multiple when-thens"() { def x when: x = 1 then: x == 1 when: x = 2 then: x == 2 } def "full house"() { def x, y when: "blah" x = 1 and: "blah" y = 2 then: "blah" x == 1 and: "blah" y == 2 when: x = 42 then: x == 42 and: y == 2 } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/000077500000000000000000000000001202022523300305715ustar00rootroot00000000000000ConditionEvaluation.groovy000066400000000000000000000157451202022523300357530ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition import org.spockframework.runtime.ConditionNotSatisfiedError import spock.lang.Issue import spock.lang.FailsWith import spock.lang.Specification import static java.lang.Math.max import static java.lang.Math.min import static java.lang.Integer.MAX_VALUE import static java.lang.Thread.State.BLOCKED /** * Checks that: * - condition transformation succeeds w/o compilation error (checked implicitly) * - condition evaluation succeeds w/o runtime error (checked explicitly) * - condition evaluation has the expected result (checked explicitly) * * @author Peter Niederwieser */ class ConditionEvaluation extends Specification { def "multi-line condition"() { expect: 2 * 3 == 6 } @FailsWith(ConditionNotSatisfiedError) def "failing multi-line condition"() { expect: 2 * 3 == 7 } def "MethodCallExpression"() { expect: [1, 2, 3].size() == 3 [1, 2, 3].getClass().getMethod("size", null).parameterTypes.length == 0 Integer.valueOf(String.valueOf(10)) == 10 } def "MethodCallExpression with spread-dot operator"() { expect: ["1", "22"]*.size() == [1, 2] } def "MethodCallExpression with safe operator"() { def a = null expect: a?.foo() == null } def "MethodCallExpression with named arguments"() { expect: new Person().eat(what: "steak", where: "tokyo") == [what: "steak", where: "tokyo"] } def "MethodCallExpression with named arguments passed as map"() { expect: new Person().eat([what: "steak", where: "tokyo"]) == [what: "steak", where: "tokyo"] } def "StaticMethodCallExpression"() { expect: max(1, 2) == 2 max(min(1, 2), 3) == 3 } def "ConstructorCallExpression"() { expect: new ArrayList().empty new String("abc") == "abc" new String(new String("abc")) == "abc" } def "ConstructorCallExpression with named arguments"() { expect: new Person(name: "fred", age: 25).name == "fred" new Person(name: "fred", age: 25).age == 25 } def "ConstructorCallExpression with named arguments passed as map"() { expect: new Person([name: "fred", age: 25]).name == "fred" new Person([name: "fred", age: 25]).age == 25 } def "TernaryExpression"() { expect: 1 ? 1 : 0 "abc".size() == 0 ? 0 : 1 } def "ShortTernaryExpression"() { expect: 1 ?: 0 "".size() ?: 1 } def "BinaryExpression"() { expect: 1 == 1 2 > 1 && 1 < 2 1 * 1 / 1 + 1 - 1 ** 1 == 1 1 == [[[[[1]]]]][0][0][0][0][0] } def "PrefixExpression"() { def x = 0 expect: ++x == 1 --x == 0 x == 0 } def "PostfixExpression"() { def x = 0 expect: x++ == 0 x-- == 1 x == 0 } def "BooleanExpression"() { expect: 1 "abc" [1, 2, 3] 1 + 2 + 3 } def "ClosureExpression"() { def x = 0 when: def test = {it -> assert ++x == 1; {it2 -> assert ++x == 2 }(); {it3 -> assert ++x == 3 } }() then: x == 2 when: test() then: x == 3 } def "TupleExpression"() { def a, b expect: ((a, b) = [1, 2]) == [1, 2] } def "MapExpression"() { expect: ![:] [a: 1] + [b: 2] == [a: 1, b: 2] } def "ListExpression"() { expect: [1, 2, 3].size() == 3 [] + [1] + [2, 3] == [1, 2, 3] } def "RangeExpression"() { expect: (1..3).contains(3) !((1..<3).contains(3)) } def "PropertyExpression"() { expect: [1, 2, 3].size == 3 (new Properties().next.next.next.x = 10) == 10 Integer.MIN_VALUE < Integer.MAX_VALUE } def "AttributeExpression"() { def attrs = new Attributes() attrs.x = 1 attrs.y = attrs expect: attrs.x == attrs.@x attrs.@y.@x == 1 } def "MethodPointerExpression"() { def pointers = new MethodPointers() expect: pointers.&inc [1, 2, 3].collect(pointers.&inc) == [2, 3, 4] } def "ConstantExpression"() { expect: 1 1 == 1.0 "abc".reverse() == "cba" } def "ClassExpression"() { expect: ConditionEvaluation == getClass() ConditionEvaluation.getClass() == Class.class } def "VariableExpression"() { def x = 1 def y = 2 expect: x < y x + y == 2 * y - x Math.max(x, y) == 2 } def "RegexExpression"() { expect: (~"ab*a").matcher("abbba") !(~"ab*a").matcher("abcba") } def "GStringExpression"() { def x = 1 def y = [1, 2, 3] expect: "$x and ${y.size()}" == "1 and 3" } def "ArrayExpression"() { expect: ([1, 2, 3] as int[]).size() == 3 } private add(x, y) { x + y } def "SpreadExpression"() { expect: add(* [1, 2]) == 3 [1, * [2, * [3, * [4]]]] == [1, 2, 3, 4] } private sub(args) { args.x - args.y } def "SpreadMapExpression"() { expect: sub(*: [y: 1, x: 2]) == 1 [a: 1, b: 2, c: 3] == [c: 3, *: [b: 2, a: 1]] } def "NotExpression"() { expect: !false !!true !(true && false) } def "UnaryMinusExpression"() { expect: -(-1) == 1 -1 + -2 == -3 } def "UnaryPlusExpression"() { expect: +(+2) == 2 +1 + +2 == +3 } def "BitwiseNegationExpression"() { expect: ~1 == -2 ~~1 == 1 } def "CastExpression"() { expect: (List) [1, 2, 3] ([1, 2, 3] as int[]).getClass().isArray() } def "ArgumentListExpression"() { expect: 3.toString() == "3" Arrays.asList(1, 2, 3) == [1, 2, 3] } // as of Groovy 1.7.3, represented as FieldExpression @Issue("http://issues.spockframework.org/detail?id=106") def "statically imported field"() { expect: MAX_VALUE == 2147483647 } // as of Groovy 1.7.3, represented as PropertyExpression def "statically imported enum value"() { expect: BLOCKED instanceof Thread.State } /* def "MapEntryExpression"() { // tested as part of testMapExpression } def "DeclarationExpression"() { // cannot occur in condition } def "RegexExpression"() { // unused AST node } def "ClosureListExpression"() { // cannot occur in condition } def "BytecodeExpression"() { // cannot occur in condition } */ static class Properties { def getNext() { this } def x } static class Attributes { def x def y } static class MethodPointers { def inc(x) { x + 1 } } static class Person { def name def age def height def eat(args) { args } } } ConditionRendering.groovy000066400000000000000000000277261202022523300355630ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition import spock.lang.Issue import static java.lang.Math.min import static java.lang.Integer.MAX_VALUE import static java.lang.Thread.State.BLOCKED /** * Describes rendering of whole conditions. * * @author Peter Niederwieser */ class ConditionRendering extends ConditionRenderingSpec { def "simple condition"() { expect: isRendered """ x == 1 | | 2 false """, { def x = 2 assert x == 1 } } def "multi-line condition"() { expect: isRendered """ 1 + 2 == 4 - 2 | | | 3 | 2 false """, { assert 1 + 2 == 4 - 2 } } private one(x) { 0 } def "MethodCallExpression with implicit target"() { expect: isRendered """ one(a) | | 0 1 """, { def a = 1 assert one(a) } } def "MethodCallExpression with explicit target"() { expect: isRendered """ a.get(b) == null | | | | | 1 0 false [1] """, { def a = [1] def b = 0 assert a.get(b) == null } } void "MethodCallExpression with GString method"() { expect: isRendered """ [1]."\$x"(0) == null | | | 1 get false """, { def x = "get" assert [1]."$x"(0) == null } } def "MethodCallExpression invoking static method"() { expect: isRendered """ Math.max(a,b) == null | | | | 2 1 2 false """, { def a = 1 def b = 2 assert Math.max(a,b) == null } } def "MethodCallExpression with spread-dot operator"() { expect: isRendered """ ["1", "22"]*.size() == null | | [1, 2] false """, { assert ["1", "22"]*.size() == null } } def "MethodCallExpression with safe operator"() { expect: isRendered """ a?.foo() | | | null null """, { def a = null assert a?.foo() } } // checks that ConditionRewriter.convertConditionNullAware() records values correctly def "top-level MethodCallExpression"() { expect: isRendered """ a.get(b) | | | | 0 0 [0] """, { def a = [0] def b = 0 assert a.get(b) } } def "MethodCallExpression with named arguments"() { expect: isRendered """ person.eat(what: steak, where: tokyo) | | | | p null steak tokyo """, { def person = new Person2() def steak = "steak" def tokyo = "tokyo" assert person.eat(what: steak, where: tokyo) } } def "MethodCallExpression with named arguments passed as map"() { expect: isRendered """ person.eat([what: steak, where: tokyo]) | | | | p null steak tokyo """, { def person = new Person2() def steak = "steak" def tokyo = "tokyo" assert person.eat([what: steak, where: tokyo]) } } def "StaticMethodCallExpression"() { expect: isRendered """ min(a,b) == null | | | | 1 1 2 false """, { def a = 1 def b = 2 assert min(a,b) == null } } // checks that ConditionRewriter.convertConditionNullAware() records values correctly def "top-level StaticMethodCallExpression"() { expect: isRendered """ min(a,b) | | | 0 0 0 """, { def a = 0 def b = 0 assert min(a,b) } } def "ConstructorCallExpression"() { expect: isRendered """ new ArrayList(a) == null | | | [] 1 false """, { def a = 1 assert new ArrayList(a) == null } } def "ConstructorCallExpression with named arguments"() { expect: isRendered """ new Person2(name: fred, age: fredsAge) == null | | | | p fred 25 false """, { def fred = "fred" def fredsAge = 25 assert new Person2(name: fred, age: fredsAge) == null } } def "ConstructorCallExpression with named arguments passed as map"() { expect: isRendered """ new Person2([name: fred, age: fredsAge]) == null | | | | p fred 25 false """, { def fred = "fred" def fredsAge = 25 assert new Person2([name: fred, age: fredsAge]) == null } } def "TernaryExpression"() { expect: isRendered """ a ? b : c | | 1 0 """, { def a = 1 def b = 0 def c = 1 assert a ? b : c } isRendered """ a ? b : c | | 0 0 """, { def a = 0 def b = 1 def c = 0 assert a ? b : c } } def "ShortTernaryExpression"() { expect: isRendered """ (a ?: b) == null | | 1 false """, { def a = 1 def b = 2 assert (a ?: b) == null } isRendered """ a ?: b | | 0 0 """, { def a = 0 def b = 0 assert a ?: b } } def "BinaryExpression"() { expect: isRendered """ a * b | | | 0 0 1 """, { def a = 0 def b = 1 assert a * b } isRendered """ a[b] ||| ||0 |false [false] """, { def a = [false] def b = 0 assert a[b] } } def "PrefixExpression"() { expect: isRendered """ ++x == null | | 1 false """, { def x = 0 assert ++x == null } } def "PostfixExpression"() { expect: isRendered """ x++ == null | | 0 false """, { def x = 0 assert x++ == null } } def "BooleanExpression"() { expect: isRendered """ a | null """, { def a = null assert a } } def "ClosureExpression"() { expect: isRendered """ { -> 1 + 2 } == null | false """, { assert { -> 1 + 2 } == null } } def "TupleExpression"() { // TupleExpression is only used on LHS of (multi-)assignment, // but LHS of assignment is not rewritten expect: isRendered """ ((a,b) = [1,2]) && false | | [1, 2] false """, { def a def b assert ((a,b) = [1,2]) && false } } def "MapExpression"() { expect: isRendered """ [a:b, c:d] == null | | | 2 4 false """, { def b = 2 def d = 4 assert [a:b, c:d] == null } isRendered """ [(a):b, (c):d] == null | | | | | 1 2 3 4 false """, { def a = 1 def b = 2 def c = 3 def d = 4 assert [(a):b, (c):d] == null } } def "ListExpression"() { expect: isRendered """ [a,b,c] == null | | | | 1 2 3 false """, { def a = 1 def b = 2 def c = 3 assert [a,b,c] == null } } def "RangeExpression"() { expect: isRendered """ (a..b) == null | | | 1 2 false """, { def a = 1 def b = 2 assert (a..b) == null } isRendered """ (a.. assert false }() } } @FailsWith(ConditionNotSatisfiedError) def "at top level of helper method"() { setup: topLevel() } @FailsWith(ConditionNotSatisfiedError) def "nested in helper method"() { setup: nested() } @FailsWith(ConditionNotSatisfiedError) def "deeply nested in helper method"() { setup: deeplyNested() } }ExplicitConditionsInNestedPositions.groovy000066400000000000000000000027651202022523300411500ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition import org.spockframework.runtime.ConditionNotSatisfiedError import spock.lang.FailsWith import spock.lang.Specification /** * @author Peter Niederwieser */ class ExplicitConditionsInNestedPositions extends Specification { @FailsWith(ConditionNotSatisfiedError) def "in for loop"() { setup: for (i in 1..3) assert false } @FailsWith(ConditionNotSatisfiedError) def "in closure"() { setup: [1, 2, 3].each { assert false } } @FailsWith(ConditionNotSatisfiedError) def "in implicit condition"() { expect: [1, 2, 3].every { assert false } } @FailsWith(ConditionNotSatisfiedError) def "in void method in expect block"() { expect: [1, 2, 3].each { assert false } } @FailsWith(ConditionNotSatisfiedError) def "deeply nested"() { expect: [1, 2, 3].every { if (true) [1].any { assert false } } } }ExplicitConditionsWithMessage.groovy000066400000000000000000000043011202022523300377330ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition import org.spockframework.runtime.ConditionNotSatisfiedError import spock.lang.FailsWith import spock.lang.Issue /** * @author Peter Niederwieser */ @Issue("http://issues.spockframework.org/detail?id=22") class ExplicitConditionsWithMessage extends ConditionRenderingSpec { def "evaluation of satisfied condition"() { expect: assert 1 + 2 == 3, "need to brush up my math" } @FailsWith(ConditionNotSatisfiedError) def "evaluation of unsatisfied condition"() { expect: assert 1 + 2 == 2, "need to brush up my math" } def "rendering of simple message"() { expect: isRendered """ 1 + 2 == 2 need to brush up my math """, { assert 1 + 2 == 2, "need to brush up my math" } } def "rendering of GString message"() { expect: isRendered """ a + b == 2 a: 1 b: 2 """, { def a = 1 def b = 2 assert a + b == 2, "a: $a b: ${b * 2 / 2}" } } def "rendering of object message"() { expect: isRendered """ map.a + map.b == 2 [a:1, b:2] """, { def map = [a: 1, b: 2] assert map.a + map.b == 2, map } } // null message and no message have same representation in AST def "rendering of null message"() { expect: isRendered """ 1 + 2 == 2 | | 3 false """, { assert 1 + 2 == 2, null } } // null message and no message currently have same representation (null) in SpockRuntime def "rendering of indirect null message"() { expect: isRendered """ 1 + 2 == 2 """, { def x = null assert 1 + 2 == 2, x } } }ImplicitClosureCallRendering.groovy000066400000000000000000000052551202022523300375310ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition /** * Describes rendering of conditions that contain a closure call * with the implicit "foo(args)" syntax instead of the explicit * "foo.call(args)" syntax. * * @author Peter Niederwieser */ class ImplicitClosureCallRendering extends ConditionRenderingSpec { def "with local variable"() { expect: isRendered """ func(42) == null | | 42 false """, { def func = { it } assert func(42) == null } } def assertFunc(func) { assert func(42) == null } def "with method argument"() { expect: isRendered """ func(42) == null | | 42 false """, { assertFunc { it } } } private funcField = { it } def "with field"() { expect: isRendered """ funcField(42) == null | | 42 false """, { assert funcField(42) == null } } def func = { it } def "with property"() { expect: isRendered """ func(42) == null | | 42 false """, { assert func(42) == null } } def "with qualified property"() { def holder = new FuncHolder() expect: isRendered """ holder.func(42) == null | | | | 42 false ${holder.toString()} """, { assert holder.func(42) == null } } // for implicit closure calls that don't // look like method calls, we don't currently // render the return value (little practical value, // complicates implementation, unclear how to // render in an intuitive way) def "with method call"() { expect: isRendered """ getFunc()(42) == null | | | false ${getFunc().toString()} """, { assert getFunc()(42) == null } } def "with qualified method call"() { def holder = new FuncHolder() expect: isRendered """ holder.getFunc()(42) == null | | | | | false | ${holder.func.toString()} ${holder.toString()} """, { assert holder.getFunc()(42) == null } } static class FuncHolder { def func = { it } } } InvalidConditions.groovy000066400000000000000000000034541202022523300354070ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition import org.codehaus.groovy.syntax.SyntaxException import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException class InvalidConditions extends EmbeddedSpecification { def "assignments are not allowed in expect-blocks"() { when: compiler.compileFeatureBody(""" def x = 0 expect: x $op 0 """) then: InvalidSpecCompileException e = thrown() e.message.contains("assignment") where: op << ["=", "+=", "-="] } def "assignments are not allowed in then-blocks"() { when: compiler.compileFeatureBody(""" def x = 42 when: true then: x $op 42 """) then: InvalidSpecCompileException e = thrown() e.message.contains("assignment") where: op << ["=", "+=", "-="] } def "assignments are not allowed in explicit conditions"() { when: compiler.compileFeatureBody(""" def x = 42 setup: assert x $op 42 """) then: SyntaxException e = thrown() e.message.contains(op) where: op << ["=", "+=", "-="] } def "assignments are allowed if they are part of a variable declaration"() { expect: def x = 42 x == 42 } } IsRenderedExtension.groovy000066400000000000000000000024761202022523300357130ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/conditionpackage org.spockframework.smoke.condition import java.lang.annotation.RetentionPolicy import java.lang.annotation.Retention import org.junit.ComparisonFailure import org.spockframework.runtime.extension.IMethodInterceptor import org.spockframework.runtime.ConditionNotSatisfiedError import org.spockframework.runtime.extension.IMethodInvocation import org.spockframework.runtime.model.FeatureInfo import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension import org.spockframework.runtime.extension.ExtensionAnnotation @Retention(RetentionPolicy.RUNTIME) @ExtensionAnnotation(IsRenderedExtension) @interface IsRendered { String value() } class IsRenderedExtension extends AbstractAnnotationDrivenExtension { @Override void visitFeatureAnnotation(IsRendered annotation, FeatureInfo feature) { feature.featureMethod.interceptors.add({ IMethodInvocation invocation -> try { invocation.proceed() assert "@IsRendered only works for failing conditions (but no condition failed)" } catch (ConditionNotSatisfiedError e) { def expected = annotation.value().trim() def actual = e.condition.rendering.trim() if (expected != actual) throw new ComparisonFailure("Condition rendered incorrectly", expected, actual) } } as IMethodInterceptor) } }MatcherConditionRendering.groovy000066400000000000000000000016641202022523300370600ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/conditionpackage org.spockframework.smoke.condition import static org.hamcrest.CoreMatchers.equalTo import static spock.util.matcher.HamcrestSupport.that class MatcherConditionRendering extends ConditionRenderingSpec { @IsRendered(""" x equalTo(43) | | | false 42 Expected: <43> but: was <42> """) def "short syntax"() { def x = 42 expect: x equalTo(43) } @IsRendered(""" that x, equalTo(43) | | | 42 false Expected: <43> but: was <42> """) def "long syntax"() { def x = 42 expect: that x, equalTo(43) } @IsRendered(""" that(x, equalTo(43)) | | | 42 false Expected: <43> but: was <42> """) def "explicit condition"() { def x = 42 expect: assert that(x, equalTo(43)) } @IsRendered(""" that(x, equalTo(43)) oops! Expected: <43> but: was <42> """) def "custom message"() { def x = 42 expect: assert that(x, equalTo(43)), "oops!" } } MatcherConditions.groovy000066400000000000000000000105541202022523300354030ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition import spock.lang.* import org.hamcrest.BaseMatcher import org.hamcrest.Description import org.spockframework.EmbeddedSpecification import org.spockframework.runtime.InvalidSpecException import org.spockframework.runtime.ConditionNotSatisfiedError import static org.hamcrest.CoreMatchers.* import static spock.util.matcher.HamcrestSupport.that class MatcherConditions extends EmbeddedSpecification { def "work in expect-blocks"() { def x = 42 expect: x equalTo(42) } def "work in then-blocks"() { when: def x = 42 then: x equalTo(42) } def "have an alternative 'that' syntax"() { def x = 42 expect: that x, equalTo(42) } def "can be explicit conditions (but only with 'that' syntax)"() { setup: def x = 42 assert that(x, equalTo(42)) } def "can provide a custom message"() { def x = 42 expect: assert that(x, equalTo(42)), "a custom message" } def "work with custom matcher implementations"() { def x = "otto" expect: x palindrome() } @FailsWith(ConditionNotSatisfiedError) def "fail when matcher doesn't match (1)"() { def x = 21 expect: x equalTo(42) } @FailsWith(ConditionNotSatisfiedError) def "fail when matcher doesn't match (2)"() { when: def x = 21 then: x equalTo(42) } @FailsWith(ConditionNotSatisfiedError) def "fail when matcher doesn't match (3)"() { def x = 21 expect: that x, equalTo(42) } @FailsWith(ConditionNotSatisfiedError) def "fail when matcher doesn't match (4)"() { setup: def x = 21 assert that(x, equalTo(42)) } @FailsWith(MissingMethodException) def "can only be used where a condition is expected (1)"() { setup: def x = 42 x equalTo(42) } @FailsWith(InvalidSpecException) def "can only be used where a condition is expected (2)"() { setup: def x = 42 that x, equalTo(42) } def "can have a numeric literal as actual"() { def x = 42 expect: 42 equalTo(x) } @FailsWith(MissingMethodException) def "cannot have a string literal as actual (because matcher expression gets parsed as a method call)"() { def x = "fred" expect: "fred" equalTo(x) } def "can have a string literal as actual if 'that' syntax is used"() { def x = "fred" expect: that "fred", equalTo(x) } class Foo { String method() { "method" } String property = "property" } @FailsWith(MissingMethodException) def "cannot have a method expression as actual in Groovy 1.8 (because matcher expression gets parsed as a chained method call)"() { def foo = new Foo() expect: foo.method() equalTo("method") } def "can have a method expression as actual if 'that' syntax is used"() { def foo = new Foo() expect: that foo.method(), equalTo("method") } @FailsWith(MissingMethodException) def "cannot have a property expression as actual (because matcher expression gets parsed as a method call)"() { def foo = new Foo() expect: foo.property equalTo("property") } def "can have a property expression as actual if 'that' syntax is used"() { def foo = new Foo() expect: that foo.property, equalTo("property") } def "hamcrest matchers are also supported as constraints in interactions"() { def list = Mock(List) when: list.add(42) then: 0 * list.add(equalTo(21)) 1 * list.add(equalTo(42)) } private static palindrome() { new IsPalindrome() } static class IsPalindrome extends BaseMatcher { boolean matches(Object value) { value instanceof String && value.reverse() == value } void describeTo(Description description) { description.appendText("a palindrome") } } } MethodConditionEvaluation.groovy000066400000000000000000000032061202022523300371010ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition import spock.lang.* /** * Conditions that are method calls are treated specially * by Spock. Such calls are dispatched through SpockRuntime * rather than directly by Groovy. This spec checks that * arguments passed to condition methods are received correctly. * * Example for a condition that qualifies as method condition: * foo.bar(1, 2, 3) * * Counter example: * foo.bar(1, 2, 3) == 42 */ class MethodConditionEvaluation extends Specification { Object[] expected def "pass object array with one 'regular' element"() { expected = [1] as Object[] expect: foo(expected) } def "pass object array with one null element"() { expected = [null] as Object[] expect: foo(expected) } def "pass object array with one list element"() { expected = [[1, 2, 3]] as Object[] expect: foo(expected) } private void foo(Object[] actual) { assert actual == expected } private void foo(Collection args) { assert false, "should never be called" } } PartialConditionEvaluation.groovy000077500000000000000000000017471202022523300372700ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition import spock.lang.Specification /** * Tests whether we are able to handle the situation where some expressions * are not evaluated and hence have no value recorded. * * @author Peter Niederwieser */ class PartialConditionEvaluation extends Specification { def "test"() { expect: ((false && true) ^ (true || bar(x, y, z))) } }ValueRendering.groovy000066400000000000000000000123121202022523300346720ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/condition/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.condition import spock.lang.Issue import static java.lang.Thread.State.NEW /** * Describes rendering of individual values. * * @author Peter Niederwieser */ class ValueRendering extends ConditionRenderingSpec { def "null value"() { expect: isRendered """ x | null """, { def x = null assert x } } def "char value"() { expect: isRendered """ x == null | | c false """, { def x = "c" as char assert x == null } } def "string value"() { expect: isRendered """ x == null | | | false foo """, { def x = "foo" assert x == null } } @Issue("http://issues.spockframework.org/detail?id=17") def "empty string value"() { isRendered """ x == null | | | false "" """, { def x = "" assert x == null } } def "multi-line string value"() { expect: isRendered """ null == x | | | one | two | three | four false """, { def x = "one\ntwo\rthree\r\nfour" assert null == x } } def "primitive array value"() { expect: isRendered """ x == null | | | false [1, 2] """, { def x = [1, 2] as int[] assert x == null } } def "object array value"() { expect: isRendered """ x == null | | | false [one, two] """, { def x = ["one", "two"] as String[] assert x == null } } def "list value"() { expect: isRendered """ x == null | | | false [1, 2, 3] """, { def x = [1,2,3] assert x == null } } def "map value"() { expect: isRendered """ x == null | | | false [a:1, b:2] """, { def x = [a: 1, b: 2] assert x == null } } def "single-line toString"() { expect: isRendered """ x == null | | | false single line """, { def x = new SingleLineToString() assert x == null } } def "multi-line toString"() { expect: isRendered """ x == null | | | false mul tiple lines """, { def x = new MultiLineToString() assert x == null } } def "null toString"() { expect: def x = new NullToString() isRendered """ x == null | | | false ${x.objectToString()} """, { assert x == null } } def "empty toString"() { def x = new EmptyToString() expect: isRendered """ x == null | | | false ${x.objectToString()} """, { assert x == null } } def "exception-throwing toString"() { def x = new ThrowingToString() expect: isRendered """ x == null | | | false ${x.objectToString()} (renderer threw UnsupportedOperationException) """, { assert x == null } } def "enum literal"() { expect: isRendered """ Thread.State.NEW == null | false """, { assert Thread.State.NEW == null } } def "statically imported enum literal"() { expect: isRendered """ NEW == null | false """, { assert NEW == null } } def "enum literal with toString"() { expect: isRendered """ EnumWithToString.VALUE == null | | | false I'm a value """, { assert EnumWithToString.VALUE == null } } def "variable with enum value"() { expect: isRendered """ x == null | | | false NEW """, { def x = NEW assert x == null } } def "string comparison"() { expect: isRendered """ "the quick" == "the quirk" | false 1 difference (88% similarity) the qui(c)k the qui(r)k """, { assert "the quick" == "the quirk" } } def "string comparison where one string is null"() { expect: isRendered """ "foo" == null | false """, { assert "foo" == null } isRendered """ null == "foo" | false """, { assert null == "foo" } } static class SingleLineToString { String toString() { "single line" } } static class MultiLineToString { String toString() { "mul\ntiple\n lines" } } static class NullToString { String objectToString() { super.toString() } String toString() { null } } static class EmptyToString { String objectToString() { super.toString() } String toString() { "" } } static class ThrowingToString { String objectToString() { super.toString() } String toString() { throw new UnsupportedOperationException() } } enum EnumWithToString { VALUE; String toString() { "I'm a value" } } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/000077500000000000000000000000001202022523300306175ustar00rootroot00000000000000AutoCleanupExtension.groovy000066400000000000000000000067421202022523300361350ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import org.spockframework.EmbeddedSpecification class AutoCleanupExtension extends EmbeddedSpecification { static closable static disposable static boom1 static boom2 def setup() { closable = new MyClosable() disposable = new MyDisposable() boom1 = new Boom() boom2 = new Boom() } def "@AutoCleanup resources are cleaned up after cleanup()"() { assert !closable.called when: runner.runSpecBody(""" @AutoCleanup closable = org.spockframework.smoke.extension.AutoCleanupExtension.closable def feature() { expect: !closable.called cleanup: !closable.called } def cleanup() { assert !closable.called } """) then: closable.called } def "@Shared @AutoCleanup resources are cleaned up after cleanupSpec()"() { assert !closable.called when: runner.runSpecBody(""" @Shared @AutoCleanup closable = org.spockframework.smoke.extension.AutoCleanupExtension.closable def feature() { expect: !closable.called cleanup: !closable.called } def cleanup() { assert !closable.called } def cleanupSpec() { assert !closable.called } """) then: closable.called } def "may specify custom method to be called for cleanup"() { when: runner.runSpecBody(""" @AutoCleanup("dispose") disposable = org.spockframework.smoke.extension.AutoCleanupExtension.disposable def feature() { expect: true } """) then: disposable.called } def "error during cleanup will fail feature"() { when: runner.runSpecBody(""" @AutoCleanup boom = new org.spockframework.smoke.extension.AutoCleanupExtension.Boom() def feature() { expect: true } """) then: thrown(BoomException) } def "error during cleanup won't fail feature if 'quiet' option is used"() { when: runner.runSpecBody(""" @AutoCleanup(quiet = true) boom = new org.spockframework.smoke.extension.AutoCleanupExtension.Boom() def feature() { expect: true } """) then: noExceptionThrown() } def "resources are cleaned up independently"() { runner.throwFailure = false when: def result = runner.runSpecBody(""" @AutoCleanup boom1 = org.spockframework.smoke.extension.AutoCleanupExtension.boom1 @AutoCleanup boom2 = org.spockframework.smoke.extension.AutoCleanupExtension.boom2 def feature() { expect: true } """) then: boom1.called boom2.called and: result.failures.size() == 2 result.failures[0].exception instanceof BoomException result.failures[1].exception instanceof BoomException } static class MyClosable { def called = false def close() { called = true } } static class MyDisposable { def called = false def dispose() { called = true } } static class Boom { def called = false def close() { called = true; throw new BoomException() } } static class BoomException extends Exception {} } ConditionallyIgnoreFeature.groovy000066400000000000000000000031701202022523300373000ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import spock.lang.* class ConditionallyIgnoreFeature extends Specification { @Shared log = [] @IgnoreIf({ 1 < 2 }) def "should be ignored"() { log << 1 expect: false } @IgnoreIf({ 1 > 2 }) def "should be run"() { log << 2 expect: true } @IgnoreIf({ [1,2,3] }) def "should be ignored according to Groovy truth"() { log << 3 expect: false } @IgnoreIf({ [] }) def "should be run according to Groovy truth"() { log << 4 expect: true } @IgnoreIf({ javaVersion < 1.5 }) def "provides convenient access to Java version"() { log << 5 expect: true } @IgnoreIf({ env."PATH" != env["PATH"] }) def "provides convenient access to environment variables"() { log << 6 expect: true } @IgnoreIf({ properties."os.name" != properties["os.name"] }) def "provides convenient access to system properties"() { log << 7 expect: true } def cleanupSpec() { assert log as Set == [2, 4, 5, 6, 7] as Set } } FailsWithExtension.groovy000077500000000000000000000024561202022523300356100ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import spock.lang.FailsWith import spock.lang.Specification /** * * @author Peter Niederwieser */ class FailsWithOnMethod extends Specification { @FailsWith(IndexOutOfBoundsException) def ex1() { given: def foo = [] foo.get(0) } @FailsWith(Exception) def ex2() { given: def foo = [] foo.get(0) } def ex3() { expect: true } } @FailsWith(IndexOutOfBoundsException) class FailsWithOnSpec extends Specification { def ex1() { given: def foo = [] foo.get(0) } def ex2() { given: def foo = [] foo.get(1) } @FailsWith(NullPointerException) def ex3() { given: null.foo() } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/Fast.groovy000066400000000000000000000016401202022523300327640ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import java.lang.annotation.Target import java.lang.annotation.ElementType import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy @Target([ElementType.TYPE, ElementType.METHOD]) @Retention(RetentionPolicy.RUNTIME) public @interface Fast {}IgnoreExtension.groovy000066400000000000000000000054671202022523300351430ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import org.spockframework.EmbeddedSpecification import org.spockframework.runtime.InvalidSpecException import spock.lang.Issue /** * Spock's @Ignore semantics are the same as JUnit's. * * @author Peter Niederwieser */ @Issue("http://issues.spockframework.org/detail?id=12") class IgnoreExtension extends EmbeddedSpecification { def "ignore spec"() { when: def result = runner.runWithImports(""" @Ignore class Foo extends Specification { def foo() { expect: false } def bar() { expect: false } } """) then: result.runCount == 0 result.failureCount == 0 result.ignoreCount == 1 } def "ignored feature methods"() { when: def result = runner.runSpecBody(""" @Ignore def "ignored"() { expect: false } def "not ignored"() { expect: true } @Ignore def "also ignored"() { expect: false } """) then: result.runCount == 1 result.failureCount == 0 result.ignoreCount == 2 } def "fixture methods cannot be ignored"() { when: runner.runSpecBody """ @Ignore def setup() {} """ then: thrown(InvalidSpecException) } def "ignore methods in base and derived class"() { def classes = compiler.compileWithImports(""" class Base extends Specification { @Ignore def feature1() { expect: false } def feature2() { expect: true } } class Derived extends Base { def feature3() { expect: true } @Ignore def feature4() { expect: false } } """) def derived = classes.find { it.simpleName == "Derived" } when: def result = runner.runClass(derived) then: result.runCount == 2 result.failureCount == 0 result.ignoreCount == 2 } def "ignoring base class has no effect on running derived class"() { def classes = compiler.compileWithImports(""" @Ignore class Base extends Specification { def feature1() { expect: true } } class Derived extends Base { def feature2() { expect: true } } """) def derived = classes.find { it.simpleName == "Derived" } when: def result = runner.runClass(derived) then: result.runCount == 2 result.failureCount == 0 result.ignoreCount == 0 } } IgnoreIfExtension.groovy000066400000000000000000000014461202022523300354130ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import spock.lang.* @IgnoreIf({ 1 < 2 }) class IgnoreIfExtension extends Specification { def "should be ignored"() { expect: false } } IgnoreRestExtension.groovy000066400000000000000000000046061202022523300357730ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import org.spockframework.EmbeddedSpecification import spock.lang.Unroll /** * @author Peter Niederwieser */ class IgnoreRestExtension extends EmbeddedSpecification { @Unroll("Ignore #ignored methods") def "ignore some methods"() { when: def result = runner.runSpecBody(""" $first def foo() { expect: "$first" // true if @IgnoreRest is set, false otherwise } $second def bar() { expect: "$second" } $third def baz() { expect: "$third" } """) then: result.runCount == run result.failureCount == 0 result.ignoreCount == ignored where: first << ["", "@IgnoreRest", "@IgnoreRest"] second << ["@IgnoreRest", "@IgnoreRest", "@IgnoreRest"] third << ["" , "" , "@IgnoreRest"] run << [1 , 2 , 3 ] ignored << [2 , 1 , 0 ] } @Unroll def "@IgnoreRest in base and/or derived class"() { def classes = compiler.compileWithImports(""" class Base extends Specification { $first def feature1() { expect: "$first" } def feature2() { expect: true } } class Derived extends Base { def feature3() { expect: true } $second def feature4() { expect: "$second" } } """) def derived = classes.find { it.simpleName == "Derived" } when: def result = runner.runClass(derived) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == ignoreCount where: first << ["@IgnoreRest", "" , "@IgnoreRest"] second << ["" , "@IgnoreRest", "@IgnoreRest"] runCount << [1 , 1 , 2 ] ignoreCount << [3 , 3 , 2 ] } } IncludeExcludeFeatures.groovy000066400000000000000000000051631202022523300364100ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import org.spockframework.EmbeddedSpecification class IncludeExcludeFeatures extends EmbeddedSpecification { Class spec def setup() { compiler.addPackageImport(getClass().package) spec = compiler.compileSpecBody(""" @Slow def feature1() { expect: true } @Fast def feature2() { expect: true } def feature3() { expect: true } """) } def "include methods based on annotations"() { runner.configurationScript = { runner { include(*annotationTypes) } } when: def result = runner.runClass(spec) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == 0 where: annotationTypes << [[Slow], [Fast], [Slow, Fast]] runCount << [1, 1, 2 ] } def "exclude methods based on annotations"() { runner.configurationScript = { runner { exclude(*annotationTypes) } } when: def result = runner.runClass(spec) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == 0 where: annotationTypes << [[Slow], [Fast], [Slow, Fast]] runCount << [2, 2, 1 ] } def "include and exclude features based on annotations"() { runner.configurationScript = { runner { include(*annTypes1) exclude(*annTypes2) } } when: def result = runner.runClass(spec) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == (runCount == 0 ? 1 : 0) // cannot prevent JUnit from running excluded specs, so they get ignored where: annTypes1 << [[Slow], [Slow], [Slow], [Fast], [Fast], [Fast], [Slow, Fast], [Slow, Fast], [Slow, Fast]] annTypes2 << [[Slow], [Fast], [Slow, Fast], [Slow], [Fast], [Slow, Fast], [Slow], [Fast], [Slow, Fast]] runCount << [0, 1, 0, 1, 0, 0, 1, 1, 0 ] } } IncludeExcludeFeaturesWithInheritance.groovy000066400000000000000000000037631202022523300414220ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import org.spockframework.EmbeddedSpecification class IncludeExcludeFeaturesWithInheritance extends EmbeddedSpecification { List specs def setup() { compiler.addPackageImport(getClass().package) specs = compiler.compileWithImports(""" class Spec1 extends Specification { @Slow def feature1() { expect: true } def feature2() { expect: true } } class Spec2 extends Spec1 { @Fast def feature3() { expect: true } } """) } def "include methods based on annotations"() { runner.configurationScript = { runner { include(*annotationTypes) } } when: def result = runner.runClasses(specs) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == ignoreCount where: annotationTypes << [[Slow], [Fast], [Slow, Fast]] runCount << [2, 1, 3 ] ignoreCount << [0, 1, 0 ] } def "exclude methods based on annotations"() { runner.configurationScript = { runner { exclude(*annotationTypes) } } when: def result = runner.runClasses(specs) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == 0 where: annotationTypes << [[Slow], [Fast], [Slow, Fast]] runCount << [3, 4, 2 ] } }IncludeExcludeSpecs.groovy000066400000000000000000000056211202022523300357060ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import org.spockframework.EmbeddedSpecification class IncludeExcludeSpecs extends EmbeddedSpecification { List specs def setup() { compiler.addPackageImport(getClass().package) specs = compiler.compileWithImports(""" @Slow class Spec1 extends Specification { def feature() { expect: true } } @Fast class Spec2 extends Specification { def feature() { expect: true } } class Spec3 extends Specification { def feature() { expect: true } } """) } def "include specs based on annotations"() { runner.configurationScript = { runner { include(*annotationTypes) } } when: def result = runner.runClasses(specs) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == 3 - runCount // cannot prevent JUnit from running excluded specs, so they get ignored where: annotationTypes << [[Slow], [Fast], [Slow, Fast]] runCount << [1, 1, 2 ] } def "exclude specs based on annotations"() { runner.configurationScript = { runner { exclude(*annotationTypes) } } when: def result = runner.runClasses(specs) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == 3 - runCount // cannot prevent JUnit from running excluded specs, so they get ignored where: annotationTypes << [[Slow], [Fast], [Slow, Fast]] runCount << [2, 2, 1 ] } def "include and exclude specs based on annotations"() { runner.configurationScript = { runner { include(*annTypes1) exclude(*annTypes2) } } when: def result = runner.runClasses(specs) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == 3 - runCount // cannot prevent JUnit from running excluded specs, so they get ignored where: annTypes1 << [[Slow], [Slow], [Slow], [Fast], [Fast], [Fast], [Slow, Fast], [Slow, Fast], [Slow, Fast]] annTypes2 << [[Slow], [Fast], [Slow, Fast], [Slow], [Fast], [Slow, Fast], [Slow], [Fast], [Slow, Fast]] runCount << [0, 1, 0, 1, 0, 0, 1, 1, 0 ] } } IncludeExcludeSpecsAndFeatures.groovy000066400000000000000000000036511202022523300400310ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import org.spockframework.EmbeddedSpecification class IncludeExcludeSpecsAndFeatures extends EmbeddedSpecification { List specs def setup() { compiler.addPackageImport(getClass().package) specs = compiler.compileWithImports(""" @Slow class Spec extends Specification { @Fast def feature1() { expect: true } def feature2() { expect: true } } """) } def "include specs and features base on annotations"() { runner.configurationScript = { runner { include(*annTypes1) exclude(*annTypes2) } } when: def result = runner.runClasses(specs) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == ignoreCount // cannot prevent JUnit from running excluded specs, so they get ignored where: annTypes1 << [[Slow], [Slow], [Slow], [Fast], [Fast], [Fast], [Slow, Fast], [Slow, Fast], [Slow, Fast]] annTypes2 << [[Slow], [Fast], [Slow, Fast], [Slow], [Fast], [Slow, Fast], [Slow], [Fast], [Slow, Fast]] runCount << [0, 1, 0, 1, 0, 0, 1, 1, 0 ] ignoreCount << [1, 0, 1, 0, 1, 1, 0, 0, 1 ] } }IncludeExcludeSpecsWithInheritance.groovy000066400000000000000000000042241202022523300407120ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import org.spockframework.EmbeddedSpecification class IncludeExcludeSpecsWithInheritance extends EmbeddedSpecification { List specs def setup() { compiler.addPackageImport(getClass().package) specs = compiler.compileWithImports(""" @Slow class Spec1 extends Specification { def feature1() { expect: true } } @Fast class Spec2 extends Spec1 { def feature2() { expect: true } } """) } def "include specs based on annotations"() { runner.configurationScript = { runner { include(*annotationTypes) } } when: def result = runner.runClasses(specs) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == ignoreCount // cannot prevent JUnit from running excluded specs, so they get ignored where: annotationTypes << [[Slow], [Fast], [Slow, Fast]] runCount << [1, 2, 3 ] ignoreCount << [1, 1, 0 ] } def "exclude specs based on annotations"() { runner.configurationScript = { runner { exclude(*annotationTypes) } } when: def result = runner.runClasses(specs) then: result.runCount == runCount result.failureCount == 0 result.ignoreCount == ignoreCount // cannot prevent JUnit from running excluded specs, so they get ignored where: annotationTypes << [[Slow], [Fast], [Slow, Fast]] runCount << [2, 1, 0 ] ignoreCount << [1, 1, 2 ] } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/Slow.groovy000066400000000000000000000016401202022523300330130ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import java.lang.annotation.Target import java.lang.annotation.ElementType import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy @Target([ElementType.TYPE, ElementType.METHOD]) @Retention(RetentionPolicy.RUNTIME) public @interface Slow {}StepwiseExtension.groovy000066400000000000000000000031131202022523300355050ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import org.junit.runner.Request import org.spockframework.EmbeddedSpecification class StepwiseExtension extends EmbeddedSpecification { def "basic usage"() { runner.throwFailure = false when: def result = runner.runWithImports(""" @Stepwise class Foo extends Specification { def step1() { expect: true } def step2() { expect: false } def step3() { expect: true } } """) then: result.runCount == 2 result.failureCount == 1 result.ignoreCount == 1 } def "automatically runs excluded methods that lead up to an included method"() { def clazz = compiler.compileWithImports(""" @Stepwise class Foo extends Specification { def step1() { expect: true } def step2() { expect: true } def step3() { expect: true } } """)[0] when: def result = runner.runRequest(Request.method(clazz, "step3")) then: result.runCount == 3 result.failureCount == 0 result.ignoreCount == 0 } } TimeoutExtension.groovy000077500000000000000000000101541202022523300353360ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/extension/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.extension import java.util.concurrent.TimeUnit import org.spockframework.runtime.SpockTimeoutError import org.spockframework.EmbeddedSpecification import spock.lang.* import static java.util.concurrent.TimeUnit.* /** * @author Peter Niederwieser */ class TimeoutExtension extends EmbeddedSpecification { @Shared Thread testFrameworkThread = Thread.currentThread() def setup() { runner.addClassMemberImport TimeUnit } @Timeout(1) def "method that completes in time"() { setup: Thread.sleep 500 } @FailsWith(SpockTimeoutError) @Timeout(1) def "method that doesn't complete in time"() { setup: Thread.sleep 1100 } @Timeout(value = 500, unit = MILLISECONDS) def "method that completes in time (millis)"() { setup: Thread.sleep 250 } @FailsWith(SpockTimeoutError) @Timeout(value = 250, unit = MILLISECONDS) def "method that doesn't complete in time (millis)"() { setup: Thread.sleep 300 } @Issue("http://issues.spockframework.org/detail?id=230") def "stack trace shows where thread is hung"() { when: runner.runSpecBody """ @Timeout(value = 250, unit = MILLISECONDS) def foo() { setup: helper() } def helper() { Thread.sleep 300 } """ then: SpockTimeoutError e = thrown() stackTraceLooksLike e, """ apackage.ASpec|helper|7 apackage.ASpec|foo|3 """ } def "annotating spec class has same effect as annotating every feature method not already annotated with @Timeout"() { runner.throwFailure = false when: def result = runner.runWithImports(""" @Timeout(value = 250, unit = MILLISECONDS) class Foo extends Specification { def foo() { expect: true } def bar() { setup: Thread.sleep 300 } @Timeout(value = 100, unit = MILLISECONDS) def baz() { setup: Thread.sleep 150 } } """) then: result.failures.size() == 2 def e1 = result.failures[0].exception e1 instanceof SpockTimeoutError e1.timeoutValue == 250 def e2 = result.failures[1].exception e2 instanceof SpockTimeoutError e2.timeoutValue == 100 } @Issue("issues.spockframework.org/detail?id=181") @Timeout(1) def "method invocation occurs on regular test framework thread"() { expect: Thread.currentThread() == testFrameworkThread } def "SpockTimeoutError indicates timeout settings"() { when: runner.runSpecBody """ @Timeout(value = 100, unit = MILLISECONDS) def foo() { setup: Thread.sleep 250 } """ then: SpockTimeoutError e = thrown() e.timeoutValue == 100 e.timeoutUnit == MILLISECONDS } def "repeatedly interrupts timed out method until it returns"() { when: runner.runSpecBody """ @Timeout(value = 100, unit = MILLISECONDS) def foo() { when: Thread.sleep 99999999999 then: thrown InterruptedException when: Thread.sleep 99999999999 then: thrown InterruptedException when: Thread.sleep 99999999999 then: thrown InterruptedException } """ then: thrown SpockTimeoutError } @Timeout(1) def "watcher thread has descriptive name"() { def group = Thread.currentThread().threadGroup def threads = new Thread[group.activeCount()] group.enumerate(threads) expect: threads.find { it.name == "[spock.lang.Timeout] Watcher for method 'watcher thread has descriptive name'" } } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/000077500000000000000000000000001202022523300277345ustar00rootroot00000000000000HandlingOfAssumptionViolatedException.groovy000066400000000000000000000051221202022523300405670ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.spockframework.EmbeddedSpecification import org.junit.runner.notification.RunListener import org.junit.Assume class HandlingOfAssumptionViolatedException extends EmbeddedSpecification { RunListener listener = Mock() def setup() { runner.listeners << listener runner.addClassMemberImport(Assume) } def "reported in regular feature method"() { when: runner.runSpecBody """ def foo() { setup: assumeTrue(false) } """ then: 1 * listener.testStarted(_) then: 1 * listener.testAssumptionFailure(_) then: 1 * listener.testFinished(_) 0 * listener.testFailure(_) } def "reported in data-driven unrolled feature method"() { when: runner.runSpecBody """ @Unroll def foo() { setup: assumeTrue(false) where: i << (1..2) } """ then: 2 * listener.testStarted(_) 2 * listener.testAssumptionFailure(_) 2 * listener.testFinished(_) 0 * listener.testFailure(_) } def "ignored in data-driven feature method that isn't unrolled"() { when: runner.runSpecBody """ def foo() { setup: assumeTrue(false) where: i << (1..2) } """ then: 1 * listener.testStarted(_) 0 * listener.testAssumptionFailure(_) 1 * listener.testFinished(_) 0 * listener.testFailure(_) } def "reported in setup"() { when: runner.runSpecBody """ def setup() { assumeTrue(false) } def foo() { expect: true } def bar() { expect: false } """ then: 2 * listener.testStarted(_) 2 * listener.testAssumptionFailure(_) 2 * listener.testFinished(_) 0 * listener.testFailure(_) } def "reported in @Before"() { when: runner.runSpecBody """ @org.junit.Before void before() { assumeTrue(false) } def foo() { expect: true } def bar() { expect: true } """ then: 2 * listener.testStarted(_) 2 * listener.testAssumptionFailure(_) 2 * listener.testFinished(_) 0 * listener.testFailure(_) } } JUnitClassRules.groovy000066400000000000000000000047701202022523300341660ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.junit.rules.TestName import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement import org.junit.ClassRule import org.spockframework.EmbeddedSpecification import org.spockframework.runtime.InvalidSpecException import spock.lang.Shared class JUnitClassRules extends EmbeddedSpecification { @ClassRule @Shared MyRule rule1 @ClassRule @Shared MyRule rule2 = new MyRule(42) def setup() { runner.addClassImport(ClassRule) runner.addClassImport(TestName) } def "are instantiated automatically by default"() { expect: rule1 != null rule1.num == 0 } def "can be instantiated manually"() { expect: rule2 != null rule2.num == 42 } def "must declare a type"() { when: runner.runSpecBody """ @ClassRule @Shared testName = new TestName() """ then: InvalidSpecException e = thrown() e.message.contains("does not have a declared type") } def "must declare a type that implements TestRule"() { when: runner.runSpecBody """ @ClassRule @Shared String rule = "rule" """ then: InvalidSpecException e = thrown() e.message.contains("does not appear to be a rule type") } def "must be @Shared"() { when: runner.runSpecBody """ @ClassRule TestName testName = new TestName() """ then: InvalidSpecException e = thrown() e.message.contains("must be @Shared") } static @ClassRule TestName staticRule def "static class rules are not detected"() { expect: staticRule == null } static class MyRule implements TestRule { int num = 0 MyRule() {} MyRule(int num) { this.num = num } Statement apply(Statement base, Description description) { new Statement() { @Override void evaluate() { base.evaluate() } } } } } JUnitCompliance.groovy000066400000000000000000000113661202022523300341570ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.junit.runner.Request import org.junit.runner.notification.RunListener import org.spockframework.EmbeddedSpecification import spock.lang.Issue import spock.util.EmbeddedSpecCompiler public class JUnitCompliance extends EmbeddedSpecification { @Issue("http://issues.spockframework.org/detail?id=13") def "failing setupSpec method"() { runner.throwFailure = false when: def result = runner.runSpecBody(""" def setupSpec() { throw new Exception() } def feature() { expect: true } """) then: result.runCount == 0 // we don't currently call notifier.fireTestStarted()/fireTestFinished() for setupSpec() result.failureCount == 1 result.ignoreCount == 0 def desc = result.failures[0].description desc.isSuite() // failure description is description of the test class desc.className == "apackage.ASpec" } def "failing cleanupSpec method"() { runner.throwFailure = false when: def result = runner.runSpecBody(""" def cleanupSpec() { throw new Exception() } def feature() { expect: true } """) then: result.runCount == 1 // we don't currently call notifier.fireTestStarted()/fireTestFinished() for cleanupSpec() result.failureCount == 1 result.ignoreCount == 0 } def "ignoring a Spec"() { def compiler = new EmbeddedSpecCompiler() def clazz = compiler.compileWithImports(""" @Ignore class Foo extends Specification { static log = "" // needs to be static rather than @Shared s.t. we can access it from outside def feature1() { setup: log += "1" } def feature2() { setup: log += "2" } } """)[0] when: def result = runner.runClass(clazz) then: clazz.log == "" result.runCount == 0 result.failureCount == 0 result.ignoreCount == 1 // one Spec } @Issue("http://issues.spockframework.org/detail?id=20") def "ignoring feature methods"() { def clazz = compiler.compileSpecBody(""" static log = "" @Ignore def feature1() { setup: log += "1" } def feature2() { setup: log += "2" } @Ignore def feature3() { setup: log += "3" } """) when: def result = runner.runClass(clazz) then: clazz.log == "2" result.runCount == 1 result.failureCount == 0 result.ignoreCount == 2 } def "sorting feature methods"() { def clazz = compiler.compileSpecBody(""" static log = "" def feature1() { setup: log += "1" } def feature2() { setup: log += "2" } def feature3() { setup: log += "3" } """) def request = Request.aClass(clazz).sortWith( { desc1, desc2 -> desc2.methodName.compareTo(desc1.methodName) } as Comparator) when: def result = runner.runRequest(request) then: clazz.log == "321" result.runCount == 3 result.failureCount == 0 result.ignoreCount == 0 } def "running a data-driven feature"() { runner.throwFailure = false RunListener listener = Mock() runner.listeners << listener when: def result = runner.runSpecBody(""" def "foo"() { expect: a == b where: a << [1, 2, 3] b << [2, 1, 3] } """) then: 1 * listener.testRunStarted(_) 1 * listener.testRunFinished(_) 1 * listener.testStarted { it.methodName == "foo" } 1 * listener.testFinished { it.methodName == "foo" } 2 * listener.testFailure { it.description.methodName == "foo" } 0 * listener._ result.runCount == 1 result.failureCount == 2 result.ignoreCount == 0 } def "testStarted/testFinished not called for @Ignore'd spec method"() { RunListener listener = Mock() runner.listeners << listener when: runner.runSpecBody """ @Ignore def foo() { expect: true } """ then: 1 * listener.testIgnored(_) 0 * listener.testStarted(_) 0 * listener.testFinished(_) } def "testStarted/testFinished not called for spec methods of @Ignore'd spec"() { RunListener listener = Mock() runner.listeners << listener when: runner.runWithImports """ @Ignore class Foo extends Specification { def foo() { expect: true } def bar() { expect: true } } """ then: 1 * listener.testIgnored(_) 0 * listener.testStarted(_) 0 * listener.testFinished(_) } }JUnitComplianceIgnoredTestClass.groovy000066400000000000000000000027151202022523300373130ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.junit.Test import org.junit.runner.Request import spock.lang.Specification import spock.lang.Issue @Issue("http://issues.spockframework.org/detail?id=77") class JUnitComplianceIgnoredTestClass extends org.spockframework.EmbeddedSpecification { def "a priori description of ignored test class has no method descriptions"() { Request request = Request.aClass(base) def desc = request.runner.description expect: desc.className == base.name desc.displayName == base.name desc.children.size() == 0 where: base << [Bar, BarSpec] } } class Foo { @Test void m1() {} } @org.junit.Ignore class Bar extends Foo { @Test void m2() {} } class FooSpec extends Specification { def m1() { expect: true } } @spock.lang.Ignore class BarSpec extends FooSpec { def m2() { expect: true } }JUnitFixtureMethods.groovy000066400000000000000000000122441202022523300350530ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.spockframework.EmbeddedSpecification import spock.lang.* class JUnitFixtureMethods extends EmbeddedSpecification { static invocations = [] static RECORD_INVOCATION_METHOD = "static record(methodName) { JUnitFixtureMethods.invocations << methodName }" def setup() { invocations.clear() } def "lifecycle"() { when: runSpecBody """ ${beforeClass()} def setupSpec() { record("setupSpec") } ${before()} def setup() { record("setup") } def feature1() { expect: true } def feature2() { expect: true } def cleanup() { record("cleanup") } ${after()} def cleanupSpec() { record("cleanupSpec") } ${afterClass()} """ then: invocations == [ "beforeClass", "setupSpec", "before", "setup" , "cleanup", "after", "before", "setup" , "cleanup", "after", "cleanupSpec", "afterClass" ] } @Unroll("multiple of #fixtureType") def "multiple of same type"() { when: runSpecBody """ ${this."$fixtureType"("m1")} ${this."$fixtureType"("m2")} def feature1() { expect: true } """ then: invocations.contains("m1") invocations.contains("m2") where: fixtureType << ["beforeClass", "before", "after", "afterClass"] } @Unroll("inheritance for #fixtureType") def "inheritance"() { when: run """ abstract class Parent extends Specification { $RECORD_INVOCATION_METHOD ${this."$fixtureType"("parent")} } class Child extends Parent { ${this."$fixtureType"("child")} def feature1() { expect: true } } """ then: invocations == order where: fixtureType | order "beforeClass" | ["parent", "child"] "before" | ["parent", "child"] "after" | ["child", "parent"] "afterClass" | ["child", "parent"] } @Unroll("invalid signature ignored because - #invalidBecause") def "invalid signatures are ignored"() { when: run "$prefix method($params) { record('method') }" then: invocations.empty where: prefix | params | invalidBecause "@BeforeClass void" | "" | "non static class method" "@Before static void" | "" | "static non class method" "@Before def" | "" | "non void return" "@Before void" | "a" | "non zero-arg" } def "same method with more than one fixture annotation"() { when: runSpecBody """ static mode = "before" @Before @After void f() { record mode } def feature() { when: mode = "after"; then: true } @BeforeClass @AfterClass static void sf() { record mode + "Class" } """ then: invocations == ["beforeClass", "before", "after", "afterClass"] } def "exceptions thrown by fixture methods are handled correctly"() { runner.throwFailure = false when: def result = runSpecBody(""" $declaration void $name() { throw new RuntimeException("$name") } def foo() { expect: !$failFeature } """) then: def e = result.failures[exceptionPos].exception e instanceof RuntimeException e.message == name where: name | declaration | failFeature | exceptionPos "beforeClass" | "@BeforeClass static" | true | 0 "beforeClass" | "@BeforeClass static" | false | 0 "before" | "@Before" | true | 0 "before" | "@Before" | false | 0 "after" | "@After" | true | 1 "after" | "@After" | false | 0 "afterClass" | "@AfterClass static" | true | 1 "afterClass" | "@AfterClass static" | false | 0 } protected beforeClass(name = "beforeClass") { "@BeforeClass static void $name() { record('$name') }" } protected before(name = "before") { "@Before void $name() { record('$name') }" } protected after(name = "after") { "@After void $name() { record('$name') } "} protected afterClass(name = "afterClass") { "@AfterClass static void $name() { record('$name') } "} protected addImports() { runner.addPackageImport(getClass().package) runner.addPackageImport(org.junit.Before.package) } protected runSpecBody(String specBody) { addImports() runner.runSpecBody """ $RECORD_INVOCATION_METHOD $specBody """ } protected run(String source) { addImports() runner.runWithImports(source) } }JUnitMethodRuleOrder.groovy000066400000000000000000000027151202022523300351470ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.junit.rules.MethodRule import org.junit.runners.model.Statement import org.junit.runners.model.FrameworkMethod import org.junit.Rule import spock.lang.Specification class JUnitMethodRuleOrder extends Specification { List log = [] @Rule LoggingRule rule1 = new LoggingRule(log: log, msg: "rule1") @Rule LoggingRule rule2 = new LoggingRule(log: log, msg: "rule2") def "rules declared later wrap around rules declared earlier"() { expect: log == ["rule2", "rule1"] } @SuppressWarnings("deprecation") static class LoggingRule implements MethodRule { List log String msg Statement apply(Statement base, FrameworkMethod method, Object target) { new Statement() { @Override void evaluate() { log << msg base.evaluate() } } } } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/JUnitRules.groovy000066400000000000000000000046461202022523300332610ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.junit.Rule import org.junit.rules.TestRule import org.junit.runners.model.Statement import org.junit.runner.Description import org.junit.rules.TestName import org.spockframework.EmbeddedSpecification import org.spockframework.runtime.InvalidSpecException class JUnitRules extends EmbeddedSpecification { @Rule MyRule rule1 @Rule MyRule rule2 = new MyRule(42) def setup() { runner.addClassImport(Rule) runner.addClassImport(TestName) } def "are instantiated automatically by default"() { expect: rule1 != null rule1.num == 0 } def "can be instantiated manually"() { expect: rule2 != null rule2.num == 42 } def "must declare a type"() { when: runner.runSpecBody """ @Rule testName = new TestName() """ then: InvalidSpecException e = thrown() e.message.contains("does not have a declared type") } def "must declare a type that implements MethodRule or TestRule"() { when: runner.runSpecBody """ @Rule String rule = "rule" """ then: InvalidSpecException e = thrown() e.message.contains("does not appear to be a rule type") } def "cannot be @Shared"() { when: runner.runSpecBody """ @Rule @Shared TestName testName = new TestName() """ then: InvalidSpecException e = thrown() e.message.contains("cannot be @Shared") } static @Rule TestName staticRule def "static rules are not detected"() { expect: staticRule == null } static class MyRule implements TestRule { int num = 0 MyRule() {} MyRule(int num) { this.num = num } Statement apply(Statement base, Description description) { new Statement() { @Override void evaluate() { base.evaluate() } } } } } JUnitTestRuleOrder.groovy000066400000000000000000000026121202022523300346420ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.junit.Rule import org.junit.runners.model.Statement import org.junit.rules.TestRule import org.junit.runner.Description import spock.lang.Specification class JUnitTestRuleOrder extends Specification { List log = [] @Rule LoggingRule rule1 = new LoggingRule(log: log, msg: "rule1") @Rule LoggingRule rule2 = new LoggingRule(log: log, msg: "rule2") def "rules declared later wrap around rules declared earlier"() { expect: log == ["rule2", "rule1"] } static class LoggingRule implements TestRule { List log String msg Statement apply(Statement base, Description description) { new Statement() { @Override void evaluate() { log << msg base.evaluate() } } } } } RulesAndInheritance.groovy000066400000000000000000000034101202022523300350110ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.junit.Rule import org.junit.rules.TestName import spock.lang.* @Issue("http://issues.spockframework.org/detail?id=98") class RulesAndInheritance extends RulesAndInheritanceBase { @Rule TestName name2 = new TestName() def setup() { checkNameInFixtureMethod() } def cleanup() { checkNameInFixtureMethod() } def "derived feature"() { expect: name.methodName == "derived feature" name2.methodName == "derived feature" } } abstract class RulesAndInheritanceBase extends Specification { @Rule TestName name = new TestName() @Shared int count = 0 def setup() { count++ checkNameInFixtureMethod() } def cleanup() { checkNameInFixtureMethod() } def "base feature"() { expect: name.methodName == "base feature" name2.methodName == "base feature" // check rule in superclass too } void checkNameInFixtureMethod() { if (count == 1) { assert name.methodName == "base feature" assert name2.methodName == "base feature" } else { assert name.methodName == "derived feature" assert name2.methodName == "derived feature" } } } UseJUnitClassRule.groovy000066400000000000000000000014541202022523300344540ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junitpackage org.spockframework.smoke.junit import org.junit.rules.TemporaryFolder import spock.lang.Shared import spock.lang.Specification import org.junit.ClassRule class UseJUnitClassRule extends Specification { @ClassRule @Shared TemporaryFolder folder1 = new TemporaryFolder() @ClassRule static TemporaryFolder folder2 = new TemporaryFolder() @Shared File root1 @Shared File root2 def setupSpec() { root1 = folder1.root //root2 = folder2.root assert root1.exists() //assert root2.exists() } def feature() { expect: root1 == folder1.root //root2 == folder2.root root1.exists() //root2.exists() } def cleanupSpec() { assert root1 == folder1.root //assert root2 == folder2.root assert root1.exists() //assert root2.exists() } } UseJUnitTestNameRule.groovy000066400000000000000000000032511202022523300351240ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import spock.lang.* import org.junit.Rule import org.junit.rules.TestName @Issue("http://issues.spockframework.org/detail?id=108") class UseJUnitTestNameRule extends Specification { @Rule TestName name = new TestName() def "not data-driven"() { expect: name.methodName == "not data-driven" } def "data-driven, not unrolled"() { expect: name.methodName == "data-driven, not unrolled" where: i << (1..3) } @Unroll def "data-driven, unrolled w/o name pattern"() { expect: name.methodName == "data-driven, unrolled w/o name pattern[${i-1}]" where: i << (1..3) } @Unroll def "data-driven, unrolled w/ name pattern #pattern"() { expect: name.methodName == "data-driven, unrolled w/ name pattern $pattern" where: pattern << ["foo", "bar", "baz"] } @Unroll("data-driven, unrolled w/ closure pattern #pattern") def foo() { expect: name.methodName == "data-driven, unrolled w/ closure pattern $pattern" where: pattern << ["foo", "bar", "baz"] } } UseJUnitTimeoutRule.groovy000066400000000000000000000025521202022523300350350ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/junit/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.junit import org.spockframework.EmbeddedSpecification import org.junit.runner.Result class UseJUnitTimeoutRule extends EmbeddedSpecification { def timeout def "feature method that completes in time"() { timeout = 500 when: runFeatureMethodThatSleeps(0) then: noExceptionThrown() } def "feature method that does not complete in time"() { timeout = 250 when: runFeatureMethodThatSleeps(500) then: Exception e = thrown() e.message.contains "timed out" } private Result runFeatureMethodThatSleeps(delay) { runner.runSpecBody """ @org.junit.Rule org.junit.rules.Timeout timeout = new org.junit.rules.Timeout($timeout) def foo() { setup: Thread.sleep($delay) } """ } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/000077500000000000000000000000001202022523300275345ustar00rootroot00000000000000ArgumentMatching.groovy000077500000000000000000000042731202022523300341720ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.Specification import spock.lang.FailsWith import org.spockframework.mock.TooFewInvocationsError class ArgumentMatching extends Specification { def "match identical argument"() { List list = Mock() when: list.add(arg) then: 1 * list.add(arg) where: arg << [1, "foo", new Object()] } def "match equal argument"() { List list = Mock() when: list.add(arg1) then: 1 * list.add(arg2) where: arg1 << [1, [1,2,3] as Set, null] arg2 << [1.0, [3,2,1] as Set, null] } def "match empty argument list"() { List list = Mock() when: list.size() then: 1 * list.size() } @FailsWith(TooFewInvocationsError) def "expect fewer arguments than are provided"() { Overloads overloads = Mock() when: overloads.m("one") then: 1 * overloads.m() } @FailsWith(TooFewInvocationsError) def "expect more arguments than are provided"() { Overloads overloads = Mock() when: overloads.m() then: 1 * overloads.m("one") } @FailsWith(TooFewInvocationsError) def "expect fewer arguments than are provided (w/ varargs)"() { Varargs2 varargs = Mock() when: varargs.m("one") then: 1 * varargs.m() } @FailsWith(TooFewInvocationsError) def "expect more arguments than are provided (w/ varargs)"() { Varargs2 varargs = Mock() when: varargs.m() then: 1 * varargs.m("one") } interface Overloads { void m() void m(String one) } interface Varargs2 { void m(String... strings) } } ChainedResultGenerators.groovy000066400000000000000000000052601202022523300355130ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.Specification import spock.lang.Issue @Issue("http://issues.spockframework.org/detail?id=235") class ChainedResultGenerators extends Specification { Queue queue = Mock() def "implicit default result"() { expect: queue.poll() == null queue.poll() == null } def "explicit default result"() { queue.poll() >> _ >> _ expect: queue.poll() == null queue.poll() == null queue.poll() == null } def "chaining constant results"() { queue.poll() >> 1 >> 2 >> 3 expect: queue.poll() == 1 queue.poll() == 2 queue.poll() == 3 queue.poll() == 3 } def "chaining iterable results"() { queue.poll() >>> [1, 2] >>> 3 >>> "45" expect: queue.poll() == 1 queue.poll() == 2 queue.poll() == 3 queue.poll() == "4" queue.poll() == "5" queue.poll() == "5" } def "chaining code results"() { def count = 0 queue.poll() >> { throw new UnsupportedOperationException() } >> { throw new IllegalArgumentException() } >> { count++ } when: queue.poll() then: thrown(UnsupportedOperationException) when: queue.poll() then: thrown(IllegalArgumentException) expect: queue.poll() == 0 queue.poll() == 1 } def "chaining different results"() { queue.poll() >> 1 >> _ >> { throw new UnsupportedOperationException() } >> [2, 3] >>> [4, 5] expect: queue.poll() == 1 queue.poll() == null when: queue.poll() then: thrown(UnsupportedOperationException) expect: queue.poll() == [2, 3] queue.poll() == 4 queue.poll() == 5 queue.poll() == 5 } def "chaining in then-block"() { when: def res1 = queue.poll() def res2 = queue.poll() def res3 = queue.poll() def res4 = queue.poll() def res5 = queue.poll() then: queue.poll() >> 1 >>> [2, 3] >> { throw new UnsupportedOperationException() } res1 == 1 res2 == 2 res3 == 3 res4 == null res5 == null thrown(UnsupportedOperationException) } } DefaultInteractions.groovy000066400000000000000000000042771202022523300347050ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.* class DefaultInteractions extends Specification { def "by default, a mock is only equal to itself"() { def mock = Mock(Foo) def anotherMockOfSameType = Mock(Foo) def mockOfDifferentType = Mock(Bar) expect: mock == mock mock != anotherMockOfSameType mock != mockOfDifferentType and: mock.equals(mock) !mock.equals(anotherMockOfSameType) !mock.equals(mockOfDifferentType) } def "by default, a mock returns System.identityHashCode() for its hash code"() { def mock = Mock(Foo) expect: mock.hashCode() == System.identityHashCode(mock) } def "default toString() output for named mock"() { def myMock = Mock(Foo) expect: myMock.toString() == "Mock for type 'Foo' named 'myMock'" } def "default toString() output for unnamed mock"() { expect: Mock(Foo).toString() == "Mock for type 'Foo'" } def "default equals() behavior can be overridden"() { def foo = Mock(Foo) def bar = Mock(Bar) foo.equals(_) >> { it[0].is(bar) } bar.equals(_) >> false expect: !foo.equals(foo) foo.equals(bar) !bar.equals(bar) } def "default hashCode() behavior can be overridden"() { def foo = Mock(Foo) def bar = Mock(Bar) _.hashCode() >> 42 expect: foo.hashCode() == 42 bar.hashCode() == 42 } def "default toString() behavior can be overridden"() { def foo = Mock(Foo) foo.toString() >> "mock around the clock" expect: foo.toString() == "mock around the clock" } interface Foo {} interface Bar {} } DefaultReturnValues.groovy000066400000000000000000000056711202022523300347010ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.Specification class DefaultReturnValues extends Specification { IMockable imock = Mock() Mockable cmock = Mock() def "return values for unmatched invocations on interface-based mocks"() { expect: imock.getBoolean() == false imock.getByte() == 0 imock.getShort() == 0 imock.getInt() == 0 imock.getLong() == 0 imock.getFloat() == 0f imock.getDouble() == 0d imock.getObject() == null imock.getVoid() == null imock.getDynamic() == null } def "types of return values for unmatched invocations on interface-based mocks"() { expect: imock.getBoolean().getClass() == Boolean.class imock.getByte().getClass() == Byte.class imock.getShort().getClass() == Short.class imock.getInt().getClass() == Integer.class imock.getLong().getClass() == Long.class imock.getFloat().getClass() == Float.class imock.getDouble().getClass() == Double.class } def "return values for unmatched invocations on class-based mocks"() { expect: cmock.getBoolean() == false cmock.getByte() == 0 cmock.getShort() == 0 cmock.getInt() == 0 cmock.getLong() == 0 cmock.getFloat() == 0f cmock.getDouble() == 0d cmock.getObject() == null cmock.getVoid() == null cmock.getDynamic() == null } def "types of return values for unmatched invocations on class-based mocks"() { expect: cmock.getBoolean().getClass() == Boolean.class cmock.getByte().getClass() == Byte.class cmock.getShort().getClass() == Short.class cmock.getInt().getClass() == Integer.class cmock.getLong().getClass() == Long.class cmock.getFloat().getClass() == Float.class cmock.getDouble().getClass() == Double.class } interface IMockable { boolean getBoolean() byte getByte() short getShort() int getInt() long getLong() float getFloat() double getDouble() Object getObject() void getVoid() def getDynamic() } static class Mockable { boolean getBoolean() { true } byte getByte() { 42 as byte } short getShort() { 42 as short } int getInt() { 42 as int } long getLong() { 42 as long } float getFloat() { 42 as float } double getDouble() { 42 as double } Object getObject() { new Object() } void getVoid() {} def getDynamic() { 42 } } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/ErrorReporting.groovy000066400000000000000000000036511202022523300337730ustar00rootroot00000000000000 /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.* import org.spockframework.mock.TooFewInvocationsError import org.spockframework.mock.TooManyInvocationsError import org.spockframework.mock.WrongInvocationOrderError class ErrorReporting extends Specification { Collaborator collaborator = Mock() def swallower = new Swallower(collaborator: collaborator) @FailsWith(TooFewInvocationsError) def "error 'too few invocations' is reported even if object under test swallows exception"() { when: swallower.swallow() then: 3 * collaborator.work() } @FailsWith(TooManyInvocationsError) def "error 'too many invocations' is reported even if object under test swallows exception"() { when: swallower.swallow() then: 1 * collaborator.work() } @FailsWith(WrongInvocationOrderError) def "error 'wrong invocation order' is reported even if object under test swallows exception"() { when: swallower.swallow() then: 1 * collaborator.work() then: 1 * collaborator.welcome() } static class Swallower { Collaborator collaborator def swallow() { try { collaborator.welcome() collaborator.work() collaborator.work() } catch (Throwable swallowed) {} } } interface Collaborator { def welcome() def work() } } ExplicitInteractions.groovy000066400000000000000000000033351202022523300350740ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.Specification /** * * @author Peter Niederwieser */ class ExplicitInteractions extends Specification { List list = Mock() def "basic usage"() { when: list.add(1) then: interaction { elementAdded() } } def elementAdded() { 1 * list.add(1) } def "with helper variables"() { when: list.add(42) then: interaction { def x = 1 def y = 42 x * list.add(y) } } def "multiple"() { when: list.add(42) list.remove(0) then: interaction { 1 * list.add(_) } interaction { 1 * list.remove(_) } } def "in and'ed blocks"() { when: list.add(42) list.remove(0) then: interaction { 1 * list.add(_) } and: interaction { 1 * list.remove(_) } } def "followed by implicit interaction"() { when: list.add(42) list.remove(0) then: interaction { 1 * list.add(_) } 1 * list.remove(_) } def "followed by condition"() { when: list.add(42) def x = 10 then: interaction { 1 * list.add(_) } x == 10 } }GlobalInteractions.groovy000066400000000000000000000027731202022523300345200ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import org.spockframework.mock.TooFewInvocationsError import spock.lang.FailsWith import spock.lang.Specification /** * @author Peter Niederwieser */ class GlobalInteractions extends Specification { def "optional interaction"() { def m = Mock(List) m.size() >> 1 expect: m.size() == 1 } @FailsWith(TooFewInvocationsError) def "required interaction"() { def m = Mock(List) 2 * m.get(_) >> "foo" expect: m.get(3) == "foo" } def "optional interaction defined in helper method"() { def m = optional() expect: m.size() == 1 } @FailsWith(TooFewInvocationsError) def "required interaction defined in helper method"() { def m = required() expect: m.get(3) == "foo" } def optional() { def m = Mock(List) m.size() >> 1 m } def required() { def m = Mock(List) 2 * m.get(_) >> "foo" m } }GroovyClassBasedMocks.groovy000066400000000000000000000025541202022523300351410ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import org.spockframework.mock.TooFewInvocationsError import spock.lang.FailsWith import spock.lang.Specification /** * * @author Peter Niederwieser */ class GroovyClassBasedMocks extends Specification { MockMe mockMe = Mock() def "mock declared method"() { when: mockMe.foo(42) then: 1 * mockMe.foo(42) } @FailsWith(value=TooFewInvocationsError, reason="not yet implemented") def "mock GDK method"() { when: mockMe.any() then: 1 * mockMe.any() } @FailsWith(value=TooFewInvocationsError, reason="not yet implemented") def "mock dynamic method"() { when: mockMe.someMethod() then: 1 * mockMe.someMethod() } static class MockMe { def foo(int i) {} } } InteractionScopes.groovy000066400000000000000000000032461202022523300343650ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.Specification /** * * @author Peter Niederwieser */ class InteractionScopes extends Specification { List list = Mock() def obj1 = new Object() def "local interactions are valid during execution of associated when-block"() { assert list.get(0) == null helper2() when: assert list.get(0) == obj1 helper1() then: list.get(0) >> obj1 list.get(0) == null expect: list.get(0) == null helper2() when: assert list.get(0) == null then: list.get(0) == null } def helper1() { assert list.get(0) == obj1 true } def helper2() { assert list.get(0) == null true } def "global interactions are valid from the point of their definition to the end of the iteration"() { assert list.get(0) == null list.get(0) >> obj1 assert list.get(0) == obj1 expect: list.get(0) == obj1 helper1() when: assert list.get(0) == obj1 then: list.get(0) == obj1 cleanup: assert list.get(0) == obj1 } }InteractionsReferencingFieldsAndProperties.groovy000066400000000000000000000024041202022523300413650ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.Specification class InteractionsReferencingFieldsAndProperties extends Specification { private aField = 1 def aProperty = "abc" def "interactions can reference fields"() { def oracle = Mock(Oracle) when: def result = oracle.askQuestion(aField) then: oracle.askQuestion(aField) >> aField result == aField } def "interactions can reference properties"() { def oracle = Mock(Oracle) when: def result = oracle.askQuestion(aProperty) then: oracle.askQuestion(aProperty) >> aProperty result == aProperty } } interface Oracle { def askQuestion(q) }InteractionsWithPropertySyntax.groovy000066400000000000000000000037561202022523300372110ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import org.spockframework.mock.TooManyInvocationsError import spock.lang.* class InteractionsWithPropertySyntax extends Specification { def "stubbing properties"() { def props = Mock(HasProperties) props.length >> 10 expect: props.length == 10 } def "mocking properties"() { def props = Mock(HasProperties) when: props.length props.length then: 2 * props.length } def "stubbing/mocking boolean properties"() { def props = Mock(HasProperties) props.empty >> true props.full >> false expect: props.empty !props.full } @FailsWith(TooManyInvocationsError) def "setting a property cannot be mocked with property syntax"() { def props = Mock(HasProperties) when: props.length = 10 then: 1 * (props.length = 10) 0 * _ // fails because previous line isn't considered an interaction } def "setting a property can be mocked with method syntax"() { def props = Mock(HasProperties) when: props.length = 10 then: 1 * props.setLength(10) 0 * _ } def "property names patterns are supported"() { def props = Mock(HasProperties) when: props.empty then: 1 * props./length|empty/ 0 * _ } interface HasProperties { int getLength() void setLength(int length) boolean isEmpty() boolean getFull() } } InvalidInteractions.groovy000066400000000000000000000024431202022523300347000ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.* import org.spockframework.EmbeddedSpecification import org.codehaus.groovy.syntax.SyntaxException class InvalidInteractions extends EmbeddedSpecification { @Unroll def "stubbing/mocking static methods and properties is not supported"() { when: compiler.compile(""" class Foo { static void getFoo() {} } class Bar extends spock.lang.Specification { def bar() { setup: $interaction } } """) then: SyntaxException e = thrown() e.message.toLowerCase().contains("static") where: interaction << ["1 * System.exit()", "Foo.getFoo() >> true", "Foo.foo >> true", "Foo.getBar() >> true", "Foo.bar >> true"] } } InvalidMockCreation.groovy000066400000000000000000000045111202022523300346120ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import org.codehaus.groovy.runtime.typehandling.GroovyCastException import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException import spock.lang.FailsWith import spock.lang.Specification /** * * @author Peter Niederwieser */ class InvalidMockCreation extends EmbeddedSpecification { def "field w/ missing type"() { when: compiler.compileSpecBody(""" def list = Mock() """) then: thrown(InvalidSpecCompileException) } // for "field w/ incompatible type" and "field w/ wrong argument" see Specs below def "local w/ missing type"() { when: compiler.compileFeatureBody(""" setup: def list = Mock() """) then: thrown(InvalidSpecCompileException) } def "local w/ incompatible type"() { when: List list = Mock(Map) then: thrown(GroovyCastException) } def "local w/ wrong argument"() { when: def list = Mock(1) then: thrown(MissingMethodException) } def "expr w/ missing type"() { when: compiler.compileFeatureBody(""" setup: Mock() """) then: thrown(InvalidSpecCompileException) } def "expr w/ wrong argument"() { when: Mock(1) then: thrown(MissingMethodException) } } class InvalidMockCreation2 extends EmbeddedSpecification { def "field w/ incompatible type"() { when: runner.runSpecBody(""" List list = Mock(Map) def foo() { expect: true } """) then: thrown(GroovyCastException) } } class InvalidMockCreation3 extends EmbeddedSpecification { def "field w/ wrong argument"() { when: runner.runSpecBody(""" List list = Mock(1) def foo() { expect: true } """) then: thrown(MissingMethodException) } }InvokingMocksFromMultipleThreads.groovy000066400000000000000000000052711202022523300373650ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import org.spockframework.mock.TooFewInvocationsError import org.spockframework.mock.TooManyInvocationsError import spock.lang.* class InvokingMocksFromMultipleThreads extends Specification { def numThreads = 10 def list = Mock(List) def latch = new CountDownLatch(10) def "invoking a mock from multiple threads"() { when: numThreads.times { threadId -> Thread.start { try { 100.times { count -> list.add(count) Thread.sleep(1) } } finally { latch.countDown() } } } latch.await(10, TimeUnit.SECONDS) then: interaction { 100.times { count -> numThreads * list.add(count) } } } @FailsWith(TooManyInvocationsError) def "invoking a mock from multiple threads - too many invocations"() { when: numThreads.times { threadId -> Thread.start { try { 100.times { count -> list.add(count) if (threadId == 0 && count == 99) list.add(count) Thread.sleep(1) } } catch(TooManyInvocationsError ignored) { // catching this avoids irritating build output } finally { latch.countDown() } } } latch.await(10, TimeUnit.SECONDS) then: interaction { 100.times { numThreads * list.add(it) } } } @FailsWith(TooFewInvocationsError) def "invoking a mock from multiple threads - too few invocations"() { when: numThreads.times { threadId -> Thread.start { try { 100.times { count -> if (!(threadId == 0 && count == 99)) list.add(count) Thread.sleep(1) } } catch(TooFewInvocationsError ignored) { // catching this avoids irritating build output } finally { latch.countDown() } } } latch.await(10, TimeUnit.SECONDS) then: interaction { 100.times { count -> numThreads * list.add(count) } } } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/MethodMatching.groovy000077500000000000000000000025471202022523300337110ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import org.spockframework.mock.TooFewInvocationsError import spock.lang.FailsWith import spock.lang.Specification class MethodMatching extends Specification { List list = Mock() def "match equal method name"() { when: list.add(1) then: 1 * list.add(1) } @FailsWith(TooFewInvocationsError) def "doesn't match unequal method name"() { when: list.add(1) then: 1 * list.remove(1) } def "match any method name"() { when: list.add(1) then: 1 * list._(1) } def "match method name pattern"() { when: list.add(1) then: 1 * list./a.\w/(1) } @FailsWith(TooFewInvocationsError) def "doesn't match method name pattern"() { when: list.add(1) then: 1 * list./b.\w/(1) } }MockNamesAndStringRepresentations.groovy000066400000000000000000000035011202022523300375200ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.* import org.spockframework.mock.IMockInvocation class MockNamesAndStringRepresentations extends Specification { def fieldMock = Mock(List) def fieldMock2 def setup() { fieldMock2 = Mock(List) } def "a mock's name is inferred from the variable it is assigned to at the point of its creation"() { def variableMock = Mock(List) def variableMock2 variableMock2 = Mock(List) // need a dummy interaction to get to mock's name when: fieldMock.get(0) fieldMock2.get(0) variableMock.get(0) variableMock2.get(0) then: 1 * fieldMock._ >> { IMockInvocation inv -> assert inv.mockObject.name == "fieldMock" } 1 * fieldMock2._ >> { IMockInvocation inv -> assert inv.mockObject.name == "fieldMock2" } 1 * variableMock._ >> { IMockInvocation inv -> assert inv.mockObject.name == "variableMock" } 1 * variableMock2._ >> { IMockInvocation inv -> assert inv.mockObject.name == "variableMock2" } } def "if a mock isn't assigned to a variable at the point of its creation, it doesn't have a name"() { when: Mock(List).get(0) then: 1 * _ >> { IMockInvocation inv -> assert inv.mockObject.name == null } } } MockingClosures.groovy000066400000000000000000000006171202022523300340370ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mockpackage org.spockframework.smoke.mock import spock.lang.Specification class MockingClosures extends Specification { def "can mock call() method"() { given: Closure c = Mock() when: c.call() then: 1 * c.call() when: c.call("one") then: 1 * c.call("one") when: c.call("one", "two") then: 1 * c.call("one", "two") } } MockingMethodsWithVarArgParameters.groovy000066400000000000000000000077471202022523300376410ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.* import org.spockframework.mock.TooFewInvocationsError @Issue("http://issues.spockframework.org/detail?id=55") class MockingMethodsWithVarArgParameters extends Specification { def "interactions of methods callable in vararg-style can be written in vararg-style"() { def mock = Mock(clazz) when: mock.foo(1, "one", "two", "three") // irrelevant which style is used here (i.e. by subject) then: 1 * mock.foo(1, "one", "two", "three") where: clazz << [GroovyVarArgParameter, GroovyArrayParameter] } def "interactions of methods callable in vararg-style can be written in array-style"() { def mock = Mock(clazz) when: mock.foo(1, "one", "two", "three") // irrelevant which style is used here (i.e. by subject) then: 1 * mock.foo(1, ["one", "two", "three"] as String[]) where: clazz << [GroovyVarArgParameter, GroovyArrayParameter] } def "interactions of methods callable in vararg-style can be written in list-style"() { def mock = Mock(clazz) when: mock.foo(1, "one", "two", "three") // irrelevant which style is used here (i.e. by subject) then: 1 * mock.foo(1, ["one", "two", "three"]) // works because Groovy equality covers comparison between array and list where: clazz << [GroovyVarArgParameter, GroovyArrayParameter] } @FailsWith(TooFewInvocationsError) def "interactions of methods not callable in vararg-style cannot be written in vararg-style"() { def mock = Mock(NoVarArgParameter) when: mock.foo(1, ["one", "two"] as String[]) then: 1 * mock.foo(1, "one", "two") } def "one more argument than constraints - passing example"() { def mock = Mock(GroovyVarArgParameter) when: mock.foo(1, [] as String[]) then: 1 * mock.foo(1) } @FailsWith(TooFewInvocationsError) def "one more argument than constraints - failing example"() { def mock = Mock(GroovyVarArgParameter) when: mock.foo(1, ["one"] as String[]) then: 1 * mock.foo(1) } def "equal number of arguments and constraints - passing example"() { def mock = Mock(GroovyVarArgParameter) when: mock.foo(1, ["one"] as String[]) then: 1 * mock.foo(1, "one") } @FailsWith(TooFewInvocationsError) def "equal number of arguments and constraints - failing example"() { def mock = Mock(GroovyVarArgParameter) when: mock.foo(1, ["one", "two"] as String[]) then: 1 * mock.foo(1, "one") } def "fewer arguments than constraints - passing example"() { def mock = Mock(GroovyVarArgParameter) when: mock.foo(1, ["one", "two"] as String[]) then: 1 * mock.foo(1, "one", "two") } @FailsWith(TooFewInvocationsError) def "fewer arguments than constraints - failing example"() { def mock = Mock(GroovyVarArgParameter) when: mock.foo(1, ["one"] as String[]) then: 1 * mock.foo(1, "one", "two") } @FailsWith(TooFewInvocationsError) def "vararg constraint satisfied but other constraint fails"() { def mock = Mock(GroovyVarArgParameter) when: mock.foo(1, "one", "two") then: 1 * mock.foo(2, "one", "two") } interface GroovyVarArgParameter { def foo(int i, String... strings) } interface GroovyArrayParameter { def foo(int i, String[] strings) } interface NoVarArgParameter { def foo(int i, strings) } } MockingOfVarArgParametersUserContributedSpec.groovy000066400000000000000000000025761202022523300416160ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.* @Issue("http://issues.spockframework.org/detail?id=55") class MockingOfVarArgParametersUserContributedSpec extends Specification { def methodWasCalled = false TargetClass target = Mock() def "1-arg call on method supporting >= 1 params is matched with (_)"() { given: target.oneOrGreater(_) >> { methodWasCalled = true } when: target.oneOrGreater("one") then: methodWasCalled } def "1-arg call on method supporting >= 0 params is matched with (_)"() { given: target.zeroOrGreater(_) >> { methodWasCalled = true } when: target.zeroOrGreater("one") then: methodWasCalled } interface TargetClass { void oneOrGreater(String first, String... rest) void zeroOrGreater(String... all) } } OrderedInteractions.groovy000066400000000000000000000047571202022523300347100ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import org.spockframework.mock.WrongInvocationOrderError import spock.lang.* import org.spockframework.mock.TooFewInvocationsError import org.spockframework.mock.TooManyInvocationsError class OrderedInteractions extends Specification { def "basic passing example"() { def list = Mock(List) when: list.add(1) list.add(2) then: 1 * list.add(1) then: 1 * list.add(2) } @FailsWith(WrongInvocationOrderError) def "basic failing example"() { def list = Mock(List) when: list.add(1) list.add(2) then: 1 * list.add(2) then: 1 * list.add(1) } def "order of invocations belonging to interactions in same then-block is undefined"() { def list = Mock(List) when: list.add(1) list.subList(3, 5) list.add(2) list.clear() then: 2 * list.add(_) 1 * list.subList(3, 5) then: 1 * list.clear() } @FailsWith(TooManyInvocationsError) def "'too many invocations' wins over 'wrong invocation order'"() { def list = Mock(List) when: list.add("foo") list.add("bar") list.add("foo") then: 1 * list.add("foo") then: 1 * list.add("bar") } } class RemainingBehaviorSameAsForUnorderedInteractions extends Specification { @FailsWith(TooFewInvocationsError) def "too few invocations for one of the when-blocks"() { def list = Mock(List) when: list.add("foo") list.add("bar") then: m * list.add("foo") then: n * list.add("bar") where: m | n 1 | 2 2 | 1 } @FailsWith(TooManyInvocationsError) def "too many invocations for one of the when-blocks"() { def list = Mock(List) when: list.add("foo") list.add("foo") list.add("bar") list.add("bar") then: m * list.add("foo") then: n * list.add("bar") where: m | n 1 | 2 2 | 1 } } ResultGenerators.groovy000066400000000000000000000111531202022523300342350ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import java.util.concurrent.Callable import spock.lang.* class ResultGenerators extends Specification { def "return simple result"() { List list = Mock() when: def x0 = list.get(0) def x1 = list.get(0) then: _ * list.get(0) >> 42 x0 == 42 x1 == 42 } def "return calculated result"() { List list = Mock() when: def x0 = list.get(0) def x1 = list.get(0) then: _ * list.get(0) >> { if(true) 42; else 0 } x0 == 42 x1 == 42 } def "return closure"() { List list = Mock() when: def x0 = list.get(0) then: _ * list.get(0) >> (Closure){ if(true) 42; else 0 } x0 instanceof Closure } def "return iterable result"() { List list = Mock() when: def x0 = list.get(0) def x1 = list.get(0) def x2 = list.get(0) def x3 = list.get(0) then: _ * list.get(0) >>> [0,1,2] x0 == 0 x1 == 1 x2 == 2 x3 == 2 } @Issue("http://issues.spockframework.org/detail?id=83") def "auto-coercion of GString return value to String (as in plain Groovy)"() { def fred = "Fred" def flintstone = "Flintstone" def named = Mock(Named) named.getName() >> "${fred} ${flintstone}" expect: named.getName() instanceof String } @Issue("http://issues.spockframework.org/detail?id=83") def "auto-coercion of Integer return value to BigDecimal (as in plain Groovy)"() { def calculator = Mock(Calculator) calculator.calculate() >> 5 expect: calculator.calculate() instanceof BigDecimal } @Issue("http://issues.spockframework.org/detail?id=83") def "auto-coercion for multi-results"() { def calculator = Mock(Calculator) calculator.calculate() >>> [1, 2, 3] expect: calculator.calculate() instanceof BigDecimal calculator.calculate() instanceof BigDecimal calculator.calculate() instanceof BigDecimal } @Issue("http://issues.spockframework.org/detail?id=83") def "auto-coercion for computed results"() { def calculator = Mock(Calculator) calculator.calculate() >> { 1 } expect: calculator.calculate() instanceof BigDecimal } def "auto-coercion from List to Set"() { def producer = Mock(SetProducer) producer.produce() >> [1,2,3] expect: producer.produce() instanceof Set } def "access args with 'it' variable"() { List list = Mock() when: list.subList(3, 5) then: 1 * list.subList(_, _) >> { assert it[0] == 3; assert it[1] == 5 } } def "access args with named variable"() { List list = Mock() when: list.subList(3, 5) then: 1 * list.subList(_, _) >> { args -> assert args.size() == 2 } } def "access args with destructuring"() { List list = Mock() when: list.subList(3, 5) then: 1 * list.subList(_, _) >> { from, to -> assert from == 3; assert to == 5 } } def "access single arg without destructuring"() { List list = Mock() when: list.remove(3) then: 1 * list.remove(_) >> { foo -> assert foo == [3] } } def "access single arg with destructuring"() { List list = Mock() when: list.remove(5) then: 1 * list.remove(_) >> { int foo -> assert foo == 5 } } @Issue("http://issues.spockframework.org/detail?id=166") def "exceptions thrown from code result generators aren't wrapped"() { def callable = Mock(Callable) callable.call() >> { throw exception } when: def caughtException = caller.call(callable) then: caughtException.is(exception) where: [caller, exception] << [ [new JavaCaller(), new GroovyCaller()], [new RuntimeException(), new IOException()] ].combinations() } interface Named { String getName() } interface Calculator { BigDecimal calculate() } interface SetProducer { Set produce() } static class GroovyCaller { Throwable call(Callable callable) { try { callable.call() return null } catch (Throwable t) { return t } } } } SpreadWildcardUsage.groovy000066400000000000000000000043241202022523300346040ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.Specification import spock.lang.FailsWith import org.spockframework.runtime.InvalidSpecException class SpreadWildcardUsage extends Specification { def "match any arguments"() { Overloads overloads = Mock() when: overloads.m() overloads.m("one") overloads.m("one", "two") then: 3 * overloads.m(*_) } def "match any remaining arguments"() { Overloads overloads = Mock() when: overloads.m("one") overloads.m("one", "two") overloads.m("one", "two", "three") then: 3 * overloads.m("one", *_) } def "mach any remaining arguments (w/ varargs)"() { Varargs varargs = Mock() when: varargs.m("one", "two", "three") then: 1 * varargs.m(*_) when: varargs.m("one", "two", "three") then: 1 * varargs.m("one", *_) when: varargs.m("one", "two", "three") then: 1 * varargs.m("one", "two", *_) when: varargs.m("one", "two", "three") then: 1 * varargs.m("one", "two", "three", *_) when: varargs.m("one", "two", "three") then: 0 * varargs.m("one", "two", "three", "four", *_) } @FailsWith(InvalidSpecException) def "may only be used at the end of an argument list"() { Overloads overloads = Mock() when: overloads.m("one", "two", "three") then: 1 * overloads.m("one", *_, "three") } interface Overloads { def m() def m(String one) def m(String one, String two) def m(String one, String two, String three) } interface Varargs { def m(String one, String... remaining) } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/TargetMatching.groovy000077500000000000000000000017731202022523300337170ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.Specification class TargetMatching extends Specification { Runnable runner1 = Mock() Runnable runner2 = Mock() def "match equally named collaborator" () { when: runner1.run() then: 1 * runner1.run() } def "match any collaborator"() { when: runner1.run() runner2.run() then: 2 * _.run() } } TreatmentOfJavaLangObjectMethods.groovy000066400000000000000000000023201202022523300372300ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.* @Ignore class TreatmentOfJavaLangObjectMethods extends Specification { Object mock = Mock() def "equals()"() { expect: !mock.equals(mock) } @FailsWith(value = NullPointerException, reason = "equals() is dispatched to GDK.equals(List, List), which calls methods like iterator(); not sure how to solve this problem") def "GDK equals()"() { List list = Mock() expect: !list.equals(list) } def "hashCode()"() { expect: mock.hashCode() == 0 } def "toString()"() { expect: mock.toString() == null } } ValidMockCreation.groovy000066400000000000000000000034351202022523300342670ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.Specification class ValidMockCreation extends Specification { List list1 = Mock() def "field typed w/ mock untyped"() { expect: list1 instanceof List } List list2 = Mock(ArrayList) def "field typed w/ mock typed"() { expect: list2 instanceof ArrayList } def list3 = Mock(List) def "field untyped w/ mock typed"() { expect: list3 instanceof List } def "local typed w/ mock untyped"() { List list = Mock() expect: list instanceof List } def "local typed w/ mock typed"() { List list = Mock(ArrayList) expect: list instanceof ArrayList } def "local untyped w/ mock typed"() { def list = Mock(List) expect: list instanceof List } def "expr typed"() { expect: Mock(List) instanceof List } def "creation in nested expr"() { def list = null if (1) list = id(id(Mock(List))) expect: list instanceof List } def "creation in closure"() { // a closure preceded by a label is parsed as block by Groovy, // so we use "assert" instead of "expect:" here assert { it -> { it2 -> Mock(List) }() }() instanceof List } private id(arg) { arg } }ValidMockCreationInDerivedClass.groovy000066400000000000000000000006021202022523300370400ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mockpackage org.spockframework.smoke.mock import spock.lang.Specification class ValidMockCreationInDerivedClass extends ValidMockCreationInDerivedClassBase { def map = Mock(Map) def "all mocks have been created"() { expect: list instanceof List map instanceof Map } } abstract class ValidMockCreationInDerivedClassBase extends Specification { List list = Mock() } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/mock/WildcardUsages.groovy000066400000000000000000000054761202022523300337200ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.mock import spock.lang.* class WildcardUsages extends Specification { def "match any argument"() { def list = Mock(List) when: list.subList(1, 1) list.subList(2, 1) list.subList(3, 2) then: 2 * list.subList(_, 1) } def "match any argument that has a certain type"() { def list = Mock(List) when: list.add(new HashMap()) list.add(new TreeMap()) list.add("string") then: 2 * list.add(_ as Map) } def "match any target"() { def list1 = Mock(List) def list2 = Mock(List) when: list1.get(1) list2.add("abc") then: 1 * _.add("abc") 1 * _.get(1) } def "match any method name"() { def list1 = Mock(List) def list2 = Mock(List) when: list1.get(1) list1.add(1) list1.get(2) list2.add(2) then: 2 * list1._(1) } def "match any method name and argument list"() { def list = Mock(List) when: list.clear() list.get(1) list.subList(3, 5) then: 3 * list._ } def "match any invocation on a mock object"() { when: Mock(XYZ).get(1) Mock(XYZ).get(2) Mock(XYZ).get(3) then: 3 * _._ } def "match any invocation on a mock object (short syntax)"() { when: Mock(XYZ).get(1) Mock(XYZ).get(2) Mock(XYZ).get(3) then: 3 * _ } def "wildcard method name doesn't match Object's equals(), hashCode(), and toString() methods"() { def list = Mock(List) when: list.equals(new Object()) list.hashCode() list.toString() then: 0 * list._() 0 * list._ 0 * _ } def "wildcard method name matches overloaded equals(), hashCode(), and toString() methods"() { def overloaded = Mock(Overloaded) when: overloaded.equals("me") overloaded.hashCode([]) overloaded.toString(true) then: 3 * overloaded._ } def "usage in interaction doesn't interfer with usage in where-block"() { def list = Mock(type) when: list.add(1) then: 1 * _._(_) where: [_, type] << [[123, List]] } } interface XYZ { void get(int i) } interface Overloaded { boolean equals(String str) int hashCode(List list) String toString(boolean verbose) }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/000077500000000000000000000000001202022523300321615ustar00rootroot00000000000000DataProviders.groovy000077500000000000000000000072061202022523300361300ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.parameterization import org.spockframework.EmbeddedSpecification import org.spockframework.runtime.SpockExecutionException /** * @author Peter Niederwieser */ class DataProviders extends EmbeddedSpecification { def "null value"() { when: runner.runFeatureBody """ expect: true where: x << null """ then: thrown(SpockExecutionException) } def "literal"() { expect: x == 1 where : x << 1 } def "empty list"() { when: runner.runFeatureBody """ expect: true where : x << [] """ then: thrown(SpockExecutionException) } def "single-element list"() { expect: x == 1 where : x << [1] } def "multi-element list"() { expect: [1, 2, 3].contains x where : x << [3, 2, 1] } def "array"() { expect: [1, 2, 3].contains x where : x << ([3, 2, 1] as int[]) } def "map"() { expect: x.value == x.key.toUpperCase() where : x << ["vienna":"VIENNA", "tokyo":"TOKYO"] } def "matcher"() { expect: x.startsWith "a" where : x << ("a1a2a3" =~ /a./) } def "string"() { expect: "abc".contains x where : x << "cba" } def "iterator"() { expect: [1, 2, 3].contains x where : x << new MyIterator() } def "iterable"() { expect: [1, 2, 3].contains x where : x << new MyIterable() } def "disguised iterable"() { expect: [1, 2, 3].contains x where : x << new MyDisguisedIterable() } def "enumeration"() { expect: ["a", "b", "c"].contains x where : x << new StringTokenizer("b c a") } def "data providers with same number of values"() { expect: x == y where : x << [1, 2, 3]; y << [1, 2, 3] } def "data providers with different number of values"() { when: runner.runFeatureBody """ expect: x == y where : $providers """ then: thrown(SpockExecutionException) where: providers << [ "x << [1, 2]; y << [1]", "x << [1]; y << [1, 2]", "x << [1]; y << [1, 2]; z << [1]", "x << [1, 2]; y << [1]; z << [1, 2]" ] } def "data providers one of which has no values"() { when: runner.runFeatureBody """ expect: true where: x << (1..3) y << [] """ then: thrown(SpockExecutionException) } def "different kinds of data providers used together"() { expect: a + b + c + d + e == "abcde" where : a << "a" b << ["b"] c << ("c" =~ /./) d << (["d"] as String[]) e << "YES".toLowerCase()[1] } def "computed"() { expect: a == b where: a << { def x = 0 def y = 1 [x, y] }() b << [0, 1] } static class MyIterator implements Iterator { def elems = [1, 2, 3] boolean hasNext() { elems.size() > 0 } Object next() { elems.pop() } void remove() {} } static class MyIterable implements Iterable { Iterator iterator() { [3, 2, 1].iterator() } } // doesn't implement Iterable static class MyDisguisedIterable { Iterator iterator() { [3, 2, 1].iterator() } } } DataTables.groovy000066400000000000000000000105601202022523300353570ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.parameterization import org.junit.internal.runners.model.MultipleFailureException import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException import org.spockframework.runtime.SpockExecutionException import spock.lang.* class DataTables extends EmbeddedSpecification { static staticField = 42 @Shared def sharedField = 42 def instanceField = 42 def "basic usage"() { expect: Math.max(a, b) == c where: a | b | c 5 | 7 | 7 3 | 1 | 3 9 | 9 | 9 } def "table must have at least two columns"() { when: compiler.compileFeatureBody """ expect: true where: a 1 """ then: MultipleFailureException e = thrown() e.failures*.class == [InvalidSpecCompileException] * 2 } def "can use wildcards to effectively turn one-column table into two-column"() { expect: a == 1 _ == _ // won't use this in practice where: a | _ 1 | _ } def "table with just a header are not allowed"() { when: runner.runFeatureBody """ expect: true where: a | b """ then: thrown(SpockExecutionException) } def "header may only contain variable names"() { when: compiler.compileFeatureBody """ expect: true where: a | 1 | b 1 | 1 | 1 """ then: thrown(InvalidSpecCompileException) } def "header variable names must not clash with local variables"() { when: compiler.compileFeatureBody """ def local = 1 expect: true where: a | local 1 | 1 """ then: thrown(InvalidSpecCompileException) } def "header variable names must not clash with each other"() { when: compiler.compileFeatureBody """ expect: true where: a | a 1 | 1 """ then: thrown(InvalidSpecCompileException) } def "columns may be declared as parameters"(a, String b) { expect: a == 3 b == "wow" where: a | b 3 | "wow" } def "tables can be mixed with other parameterizations"() { expect: [a, b, c, d] == [1, 2, 3, 4] where: a << [1] b | c 2 | 3 d = c + 1 } def "cells may contain arbitrary expressions"() { expect: a == "oo" b.age == 23 c == 5 where: a | b | c "foo"[1..2] | new Person(age: 23) | Math.max(4, 5) } def "cells can reference shared and static fields"() { expect: a == 42 b == 42 where: a | b staticField | sharedField } @Issue("http://issues.spockframework.org/detail?id=139") def "cells cannot reference instance fields"() { when: compiler.compileSpecBody """ def instanceField def foo() { expect: true where: a | b instanceField | 1 } """ then: InvalidSpecCompileException e = thrown() e.message.contains("@Shared") } def "cells cannot reference local variables (won't be found)"() { when: runner.runFeatureBody """ def local = 42 expect: true where: a | b local | 1 """ then: thrown(MissingPropertyException) } def "cells cannot reference other cells"() { when: runner.runFeatureBody """ expect: true where: a | b 1 | a """ then: thrown(MissingPropertyException) } def "rows must have same number of elements as header"() { when: compiler.compileFeatureBody """ expect: true where: a | b | c 1 | 2 | 3 4 | 5 """ then: thrown(InvalidSpecCompileException) } def "cells can be separated with single or double pipe operator"() { expect: a + b == c where: a | b || c 1 | 2 || 3 4 | 5 || 9 } def "consistent use of cell separators is not enforced"() { expect: a + b == c where: a | b || c 1 | 2 || 3 4 || 5 | 9 } static class Person { def age } } InvalidWhereBlocks.groovy000066400000000000000000000053561202022523300371010ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.parameterization import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException import spock.lang.Issue /** * @author Peter Niederwieser */ class InvalidWhereBlocks extends EmbeddedSpecification { def "data variable collides with local variable"() { when: compiler.compileFeatureBody """ def x = 0 expect: x == y where: x << [1, 2] y << [1, 2] """ then: thrown(InvalidSpecCompileException) } def "data variable hides (but doesn't collide with) instance field"() { when: compiler.compileSpecBody """ def x = 1 def foo() { expect: x == 2 where: x << 2 } """ then: noExceptionThrown() } def "data variable hides (but doesn't collide with) static field"() { when: compiler.compileSpecBody """ static String x = 1 def foo() { expect: x == 2 where: x << 2 } """ then: noExceptionThrown() } def "duplicate data variable"() { when: compiler.compileFeatureBody """ expect: true where: x << 1 x << 2 """ then: thrown(InvalidSpecCompileException) } @Issue("http://issues.spockframework.org/detail?id=163") def "duplicate explicit data variable"() { when: compiler.compileSpecBody """ def foo(x) { expect: true where: x << 1 x << 2 } """ then: thrown(InvalidSpecCompileException) } @Issue("http://issues.spockframework.org/detail?id=14") def "duplicate data variable in multi-parameterization"() { when: compiler.compileFeatureBody """ expect: true where: [x, x] << [[1, 1]] """ then: thrown(InvalidSpecCompileException) } @Issue("http://issues.spockframework.org/detail?id=139") def "right-hand side of parameterization may not reference instance fields (only @Shared and static fields)"() { when: compiler.compileSpecBody """ def instanceField def foo() { expect: x == 1 where: x << $rhs } """ then: InvalidSpecCompileException e = thrown() e.message.contains("@Shared") where: rhs |_ "[1, instanceField, 2]" |_ "{ -> { -> [instanceField] }() }()" |_ } }MethodParameters.groovy000066400000000000000000000063051202022523300366210ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.parameterization import org.codehaus.groovy.runtime.typehandling.GroovyCastException import org.spockframework.EmbeddedSpecification import org.spockframework.compiler.InvalidSpecCompileException /** * @author Peter Niederwieser */ class MethodParameters extends EmbeddedSpecification { def "no parameters"() { expect: x == y where: x << [1, 2] y << [1, 2] } def "parameters but no where block"() { when: compiler.compileSpecBody """ def foo(int x, String y) { expect: true } """ then: thrown(InvalidSpecCompileException) } def "typed parameters"(Integer x, Integer y) { expect: x == y where: x << [1, 2] y << [1, 2] } def "typed primitive parameters"(int x, int y) { expect: x == y where: x << [1, 2] y << [1, 2] } def "untyped parameters"(x, y) { expect: x == y where: x << [1, 2] y << [1, 2] } def "partly typed parameters"(x, Integer y) { expect: x == y where: x << [1, 2] y << [1, 2] } def "parameters in different order"(y, x) { expect: x == y where: x << [1, 2] y << [1, 2] } def "fewer parameters than data variables"() { when: compiler.compileSpecBody """ def foo(x) { expect: x == y where: x << [1, 2] y << [1, 2] } """ then: thrown(InvalidSpecCompileException) } def "more parameters than data variables"() { when: compiler.compileSpecBody """ def foo(x, y, z) { expect: x == y where: x << [1, 2] y << [1, 2] } """ then: thrown(InvalidSpecCompileException) } def "parameter that is not a data variable"() { when: compiler.compileSpecBody """ def foo(x, a) { expect: x == x where: x << [1, 2] } """ then: thrown(InvalidSpecCompileException) } def "data variable that is not a parameter"() { when: compiler.compileSpecBody """ def foo(x) { expect: x == y where: $parameterizations } """ then: thrown(InvalidSpecCompileException) where: parameterizations << [ "x << [1,2]; y << [1, 2]", "[x, y] << [[1, 2], [1, 2]]", "x << [1, 2]; y = x" ] } def "data value type can be coerced to parameter type"(x, String y) { expect: x.toString() == y where: x << [1, 2] y << [1, 2] } def "data value type can not be coerced to parameter type"() { when: runner.runSpecBody """ def foo(x, ClassLoader y) { expect: x == y where: x << [1, 2] y << [1, 2] } """ then: thrown(GroovyCastException) } }ParameterizationScopes.groovy000077500000000000000000000025131202022523300400500ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.parameterization import spock.lang.Issue import spock.lang.Specification class ParameterizationScopes extends Specification { def "in outer scope"() { expect: x == 1 where: x << 1 } def "in inner scope"() { def sum = 0 when: for (i in 1..3) { sum += inc } then: sum == 6 where: inc << 2 } def "in closure scope"() { def sum = 0 when: (1..3).each { sum += inc } then: sum == 6 where: inc << 2 } @Issue("http://issues.spockframework.org/detail?id=63") def "in nested closure scope"() { expect: 1.every { 1.every { { -> val }() == 1 } } where: val = 1 } }Parameterizations.groovy000077500000000000000000000061201202022523300370540ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.parameterization import spock.lang.* class Parameterizations extends Specification { def "multi-parameterization"() { expect: a == b where : [a, b] << [[1, 1], [2, 2], [3, 3]] } def "multi-parameterization with placeholder in first position"() { expect: a == b where : [_, a, b] << [[9, 1, 1], [9, 2, 2], [9, 3, 3]] } def "multi-parameterization with placeholder in second position"() { expect: a == b where : [a, _, b] << [[1, 9, 1], [2, 9, 2], [3, 9, 3]] } def "multi-parameterization with placeholder in last position"() { expect: a == b where : [a, b, _] << [[1, 1, 9], [2, 2, 9], [3, 3, 9]] } @FailsWith(org.spockframework.runtime.ConditionNotSatisfiedError) def "multi-parameterization with placeholder in wrong position"() { expect: a == b where : [a, b, _] << [[1, 9, 1]] } def "multi-parameterization with multiple placeholders"() { expect: a == b where: [_, a] << [["foo", 3]] [b, _] << [[3, "bar"]] [_, _] << [["baz", "baz"]] } def "derived parameterization"() { expect: a == b.toUpperCase() where: a << ["A", "B", "C"] b = a.toLowerCase() } def "dependent derived parameterizations"() { expect: d == a where: a << [1, 2, 3] b = a c = b * 2 d = c / 2 } @Ignore("""argument computer fails with groovy.lang.MissingPropertyException, which is expected but cannot be easily tested; should check for this at compile-time""") def "arguments may not be used before they have been assigned"() { expect: true where: b = a a = 1 } def "simple, multi- and derived parameterizations used together"() { expect: d == a * 3 where: a << [1, 2, 3] [b, _, c] << [[1, 9, 1], [2, 9, 2], [3, 9, 3]] d = a + b + c } @Ignore("we should either support this or disallow it") def "simple parameterization whose value is accessed from closure within other parameterization"() { expect: a == 1 b == 1 where: a << 1 b << {a}() } @Issue("http://code.google.com/p/spock/issues/detail?id=149") def "can use data variables named p0, p1, etc."() { expect: p1 == p0 * 2 where: p0 | p1 1 | 2 2 | 4 3 | 6 } def "can use data variables named like special @Unroll variables"() { expect: iterationCount == featureName * 2 where: featureName << [1, 2, 3] iterationCount << [2, 4, 6] } }SqlDataSource.groovy000066400000000000000000000031211202022523300360600ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.parameterization import groovy.sql.Sql import spock.lang.Shared import spock.lang.Specification class SqlDataSource extends Specification { @Shared Sql sql = Sql.newInstance("jdbc:h2:mem:", "org.h2.Driver") def setupSpec() { sql.execute("create table data (id int primary key, a int, c int, b int)") // intentionally use "strange" order sql.execute("insert into data values (1, 3, 7, 7), (2, 5, 5, 4), (3, 9, 9, 9)") } def "simple parameterization"() { expect: Math.max(a, b) == c where: row << sql.rows("select * from data") a = row["a"] b = row["b"] c = row["c"] } def "multi-parameterization"() { expect: Math.max(a, b) == c where: [a, b, c] << sql.rows("select a, b, c from data") } def "multi-parameterization with wildcard"() { expect: Math.max(a, b) == c where: [_, a, c, b] << sql.rows("select * from data") } }UnrolledFeatureMethods.groovy000066400000000000000000000153741202022523300400070ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/smoke/parameterization/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke.parameterization import org.junit.runner.notification.RunListener import org.spockframework.EmbeddedSpecification import org.spockframework.runtime.SpockExecutionException import spock.lang.Issue /** * @author Peter Niederwieser */ class UnrolledFeatureMethods extends EmbeddedSpecification { RunListener listener = Mock() def setup() { runner.listeners << listener runner.addClassImport(Actor) } def "iterations of an unrolled feature count as separate tests"() { when: def result = runner.runSpecBody(""" @Unroll def foo() { expect: true where: x << [1, 2, 3] } """) then: result.runCount == 3 result.failureCount == 0 result.ignoreCount == 0 } def "iterations of an unrolled feature foo are named foo[0], foo[1], etc."() { when: runner.runSpecBody """ @Unroll def foo() { expect: true where: x << [1, 2, 3] } """ then: interaction { def count = 0 3 * listener.testStarted { it.methodName == "foo[${count++}]" } } } def "a feature with an empty data provider causes the same error regardless if it's unrolled or not"() { when: runner.runSpecBody """ $annotation def foo() { expect: true where: x << [] } """ then: SpockExecutionException e = thrown() where: annotation << ["", "@Unroll"] } def "if creation of a data provider fails, feature isn't unrolled"() { runner.throwFailure = false when: def result = runner.runSpecBody(""" @Unroll def foo() { expect: true where: x << [1] y << { throw new Exception() }() } """) then: 1 * listener.testFailure { it.description.methodName == "foo" } // it's OK for runCount to be zero here; mental model: method "foo" // would have been invisible if it had not failed (cf. Spec JUnitErrorBehavior) result.runCount == 0 result.failureCount == 1 result.ignoreCount == 0 } def "naming pattern may refer to data variables"() { when: runner.runSpecBody(""" @Unroll("one #y two #x three") def foo() { expect: true where: x << [1, 2, 3] y << ["a", "b", "c"] } """) then: 1 * listener.testStarted { it.methodName == "one a two 1 three" } 1 * listener.testStarted { it.methodName == "one b two 2 three" } 1 * listener.testStarted { it.methodName == "one c two 3 three" } } def "naming pattern may refer to feature name and iteration count"() { when: runner.runSpecBody(""" @Unroll("one #featureName two #iterationCount three") def foo() { expect: true where: x << [1, 2, 3] y << ["a", "b", "c"] } """) then: 1 * listener.testStarted { it.methodName == "one foo two 0 three" } 1 * listener.testStarted { it.methodName == "one foo two 1 three" } 1 * listener.testStarted { it.methodName == "one foo two 2 three" } } @Issue("http://issues.spockframework.org/detail?id=65") def "variables in naming pattern whose value is null are replaced correctly"() { when: runner.runSpecBody(""" @Unroll("one #x two #y three") def foo() { expect: true where: x << [1] y << [null] } """) then: 1 * listener.testStarted { it.methodName == "one 1 two null three" } } @Issue("http://issues.spockframework.org/detail?id=231") def "naming pattern supports property expressions"() { when: runner.runSpecBody(""" @Unroll("one #actor.details.name two") def foo() { expect: true where: actor = new Actor() } """) then: 1 * listener.testStarted { it.methodName == "one fred two" } } @Issue("http://issues.spockframework.org/detail?id=231") def "naming pattern supports zero-arg method calls"() { when: runner.runSpecBody(""" @Unroll("one #actor.details.name.size() two") def foo() { expect: true where: actor = new Actor() } """) then: 1 * listener.testStarted { it.methodName == "one 4 two" } } def "expressions in naming pattern that can't be evaluated are prefixed with 'Error:'"() { when: runner.runSpecBody(""" @Unroll("#obj #obj.ok() #obj.bang() #obj.missing() #missing") def foo() { expect: true where: obj = { def obj = new Expando(); obj.ok = { "ok" }; obj.toString = { throw new RuntimeException() }; obj.bang = { throw new NullPointerException() }; obj }() } """) then: 1 * listener.testStarted { it.methodName == "#Error:obj ok #Error:obj.bang() #Error:obj.missing() #Error:missing" } } @Issue("http://issues.spockframework.org/detail?id=231") def "method name can act as naming pattern"() { when: runner.runSpecBody(""" @Unroll def "one #actor.details.name.size() two"() { expect: true where: actor = new Actor() } """) then: 1 * listener.testStarted { it.methodName == "one 4 two" } } @Issue("http://issues.spockframework.org/detail?id=231") def "naming pattern in @Unroll annotation wins over naming pattern in method name"() { when: runner.runSpecBody(""" @Unroll("#actor.details.name") def "#actor.details.age"() { expect: true where: actor = new Actor() } """) then: 1 * listener.testStarted { it.methodName == "fred" } } @Issue("http://issues.spockframework.org/detail?id=232") def "can unroll a whole class at once"() { when: runner.runWithImports(""" @Unroll class Foo extends Specification { def "#actor.details.name"() { expect: true where: actor = new Actor() } def "not data-driven"() { expect: true } def "#actor.details.age"() { expect: true where: actor = new Actor() } } """) then: 1 * listener.testStarted { it.methodName == "fred" } 1 * listener.testStarted { it.methodName == "not data-driven" } 1 * listener.testStarted { it.methodName == "30" } } @Issue("http://issues.spockframework.org/detail?id=232") def "method-level unroll annotation wins over class-level annotation"() { when: runner.runWithImports(""" @Unroll class Foo extends Specification { @Unroll("#actor.details.name") def method() { expect: true where: actor = new Actor() } } """) then: 1 * listener.testStarted { it.methodName == "fred" } } private class Actor { Map details = [name: "fred", age: 30] } }spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/thirdparty/000077500000000000000000000000001202022523300276575ustar00rootroot00000000000000ToStringOutputOfMockingFrameworks.groovy000066400000000000000000000025371202022523300377060ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/thirdparty/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.thirdparty import org.easymock.EasyMock import org.mockito.Mockito import org.jmock.Mockery class ToStringOutputOfMockingFrameworks { static void main(args) { println "JMock:" Mockery context = new Mockery(); def jmock1 = context.mock(Foo) println jmock1 def jmock2 = context.mock(Foo, "explicitly named") println jmock2 println() println "EasyMock:" def easymock1 = EasyMock.createMock(Foo) println easymock1 def easymock2 = EasyMock.createMock("explicitlyNamed", Foo) println easymock2 println() println "Mockito:" def mockito1 = Mockito.mock(Foo) println mockito1 def mockito2 = Mockito.mock(Foo,"explicitly named") println mockito2 } } interface Foo {}spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/util/000077500000000000000000000000001202022523300264425ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/util/CollectionUtilSpec.groovy000066400000000000000000000031421202022523300334550ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util import spock.lang.* class CollectionUtilSpec extends Specification { def "copyArray"() { def array = [1, 2, 3] as Object[] expect: CollectionUtil.copyArray(array, from, to) == result where: from << [0, 1, 0, 3] to << [3, 2, 0, 3] res << [[1, 2, 3], [2], [], []] result = res as Object[] } def "reverse an empty list"() { when: def reversed = CollectionUtil.reverse([]) then: toList(reversed) == [] } def "reverse a non-empty list"() { when: def reversed = CollectionUtil.reverse([1, 2, 3]) then: toList(reversed) == [3, 2, 1] } def "concatenate zero iterables"() { when: def iterable = CollectionUtil.concat() then: toList(iterable) == [] } def "concatenate multiple iterables"() { when: def iterable = CollectionUtil.concat([1, 2, 3], [], [4]) then: toList(iterable) == [1, 2, 3, 4] } def toList(iterable) { iterable.collect { it } } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/util/ObjectUtilSpec.groovy000066400000000000000000000035341202022523300325750ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util import spock.lang.Specification class ObjectUtilSpec extends Specification { def equals() { expect: ObjectUtil.equals(null, null) !ObjectUtil.equals(null, "foo") !ObjectUtil.equals("foo", null) ObjectUtil.equals("foo", "foo") !ObjectUtil.equals("foo", "bar") } def hashCode() { expect: ObjectUtil.hashCode(null) == 0 ObjectUtil.hashCode("foo") == "foo".hashCode() } def toString() { expect: ObjectUtil.toString(null) == "null" ObjectUtil.toString("foo") == "foo" } def getClass() { expect: ObjectUtil.getClass(null) == null ObjectUtil.getClass("foo") == String } def voidAwareGetClass() { expect: ObjectUtil.voidAwareGetClass(null) == void ObjectUtil.voidAwareGetClass("foo") == String } def eitherNull() { expect: ObjectUtil.eitherNull(null, null) ObjectUtil.eitherNull("foo", null) ObjectUtil.eitherNull(null, "bar") !ObjectUtil.eitherNull("foo", "bar") } def compare() { expect: ObjectUtil.compare(null, null) == 0 ObjectUtil.compare(null, 3) < 0 ObjectUtil.compare(3, null) > 0 ObjectUtil.compare(3, 3) == 0 ObjectUtil.compare(3, 4) < 0 ObjectUtil.compare(4, 3) > 0 } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/util/ReflectionUtilSpec.groovy000066400000000000000000000032641202022523300334610ustar00rootroot00000000000000 /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util import spock.lang.* class ReflectionUtilSpec extends Specification { def "getPropertyNameForGetterMethod"() { def method = ReflectionUtil.getMethodByName(HasProperties, methodName) expect: ReflectionUtil.getPropertyNameForGetterMethod(method) == propertyName where: methodName | propertyName "getLength" | "length" "isEmpty" | "empty" "getValid" | "valid" "getLengthStatic" | "lengthStatic" "isEmptyStatic" | "emptyStatic" "getValidStatic" | "validStatic" "getURL" | "URL" "getfoo" | "foo" "isfoo" | "foo" "get" | null "is" | null "foo" | null "setFoo" | null } static class HasProperties { int getLength() {} boolean isEmpty() {} boolean getValid() {} static int getLengthStatic() {} static boolean isEmptyStatic() {} static boolean getValidStatic() {} URL getURL() {} boolean getfoo() {} boolean isfoo() {} String get() {} String is() {} String foo() {} void setFoo(String foo) {} } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/util/SpockReleaseInfoSpec.groovy000066400000000000000000000016721202022523300337260ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util import spock.lang.* class SpockReleaseInfoSpec extends Specification { @See("http://groups.google.com/group/spockframework/browse_thread/thread/ad3a4da300d357fc") def "missing Groovy version is handled gracefully"() { expect: SpockReleaseInfo.isCompatibleGroovyVersion(VersionNumber.UNKNOWN) } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/org/spockframework/util/VersionNumberSpec.groovy000066400000000000000000000075331202022523300333320ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.util import spock.lang.* class VersionNumberSpec extends Specification { def "parsing"() { expect: VersionNumber.parse("1") == new VersionNumber(1, 0, 0, null) VersionNumber.parse("1.0") == new VersionNumber(1, 0, 0, null) VersionNumber.parse("1.0.0") == new VersionNumber(1, 0, 0, null) VersionNumber.parse("1.2") == new VersionNumber(1, 2, 0, null) VersionNumber.parse("1.2.3") == new VersionNumber(1, 2, 3, null) VersionNumber.parse("1-rc1-SNAPSHOT") == new VersionNumber(1, 0, 0, "rc1-SNAPSHOT") VersionNumber.parse("1.2-rc1-SNAPSHOT") == new VersionNumber(1, 2, 0, "rc1-SNAPSHOT") VersionNumber.parse("1.2.3-rc1-SNAPSHOT") == new VersionNumber(1, 2, 3, "rc1-SNAPSHOT") VersionNumber.parse("1.rc1-SNAPSHOT") == new VersionNumber(1, 0, 0, "rc1-SNAPSHOT") VersionNumber.parse("1.2.rc1-SNAPSHOT") == new VersionNumber(1, 2, 0, "rc1-SNAPSHOT") VersionNumber.parse("1.2.3.rc1-SNAPSHOT") == new VersionNumber(1, 2, 3, "rc1-SNAPSHOT") VersionNumber.parse("11.22.33.44") == new VersionNumber(11, 22, 33, "44") VersionNumber.parse("11.44") == new VersionNumber(11, 44, 0, null) VersionNumber.parse("11.fortyfour") == new VersionNumber(11, 0, 0, "fortyfour") } def "unparseable version number is represented as UNKNOWN (0.0.0)"() { expect: VersionNumber.parse(null) == VersionNumber.UNKNOWN VersionNumber.parse("") == VersionNumber.UNKNOWN VersionNumber.parse("foo") == VersionNumber.UNKNOWN VersionNumber.parse("1.") == VersionNumber.UNKNOWN VersionNumber.parse("1.2.3-") == VersionNumber.UNKNOWN } def "accessors"() { when: def version = new VersionNumber(1, 2, 3, "foo") then: version.major == 1 version.minor == 2 version.micro == 3 version.qualifier == "foo" } def "string representation"() { expect: new VersionNumber(1, 0, 0, null).toString() == "1.0.0" new VersionNumber(1, 2, 3, "foo").toString() == "1.2.3-foo" } def "equality"() { expect: new VersionNumber(1, 1, 1, null) == new VersionNumber(1, 1, 1, null) new VersionNumber(2, 1, 1, null) != new VersionNumber(1, 1, 1, null) new VersionNumber(1, 2, 1, null) != new VersionNumber(1, 1, 1, null) new VersionNumber(1, 1, 2, null) != new VersionNumber(1, 1, 1, null) new VersionNumber(1, 1, 1, "foo") != new VersionNumber(1, 1, 1, null) } def "comparison"() { expect: (new VersionNumber(1, 1, 1, null) <=> new VersionNumber(1, 1, 1, null)) == 0 (new VersionNumber(2, 1, 1, null) <=> new VersionNumber(1, 1, 1, null)) > 0 (new VersionNumber(1, 2, 1, null) <=> new VersionNumber(1, 1, 1, null)) > 0 (new VersionNumber(1, 1, 2, null) <=> new VersionNumber(1, 1, 1, null)) > 0 (new VersionNumber(1, 1, 1, "foo") <=> new VersionNumber(1, 1, 1, null)) > 0 (new VersionNumber(1, 1, 1, "b") <=> new VersionNumber(1, 1, 1, "a")) > 0 (new VersionNumber(1, 1, 1, null) <=> new VersionNumber(2, 1, 1, null)) < 0 (new VersionNumber(1, 1, 1, null) <=> new VersionNumber(1, 2, 1, null)) < 0 (new VersionNumber(1, 1, 1, null) <=> new VersionNumber(1, 1, 2, null)) < 0 (new VersionNumber(1, 1, 1, null) <=> new VersionNumber(1, 1, 1, "foo")) < 0 (new VersionNumber(1, 1, 1, "a") <=> new VersionNumber(1, 1, 1, "b")) < 0 } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/000077500000000000000000000000001202022523300227605ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/000077500000000000000000000000001202022523300237355ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/concurrent/000077500000000000000000000000001202022523300261175ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/concurrent/AsyncConditionsSpec.groovy000066400000000000000000000043041202022523300333110ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.concurrent import org.spockframework.runtime.SpockAssertionError import org.spockframework.runtime.SpockTimeoutError import spock.lang.* class AsyncConditionsSpec extends Specification { def "passing example - check passes"() { def conds = new AsyncConditions() when: Thread.start { conds.evaluate { assert true } } then: conds.await() } @FailsWith(SpockAssertionError) def "failing example 1 - eval fails"() { def conds = new AsyncConditions() when: Thread.start { conds.evaluate { assert false } } then: conds.await() } @FailsWith(SpockTimeoutError) def "failing example 2 - eval is missing"() { def conds = new AsyncConditions() expect: conds.await() } @FailsWith(SpockTimeoutError) def "one passing and one missing eval"() { def conds = new AsyncConditions(2) when: Thread.start { conds.evaluate { assert true } } then: conds.await() } @FailsWith(SpockAssertionError) def "one failing and one missing eval"() { def conds = new AsyncConditions(2) when: Thread.start { conds.evaluate { assert false } } then: conds.await() } def "multiple passing evals"() { def conds = new AsyncConditions(3) when: Thread.start { conds.evaluate { assert true assert true } conds.evaluate { assert true } } and: Thread.start { conds.evaluate { assert true } } then: conds.await() } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/concurrent/BlockingVariableSpec.groovy000066400000000000000000000031411202022523300333760ustar00rootroot00000000000000 /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.concurrent import spock.lang.* import java.util.concurrent.TimeUnit import org.spockframework.runtime.SpockTimeoutError class BlockingVariableSpec extends Specification { def "variable is read after it is written"() { def list = new BlockingVariable>() when: Thread.start { list.set([1, 2, 3]) } Thread.yield() sleep(500) then: list.get() == [1, 2, 3] } def "variable is read before it is written"() { def list = new BlockingVariable>() when: Thread.start { list.set([1, 2, 3]) Thread.yield() sleep(500) } then: list.get() == [1, 2, 3] } def "read times out if no write occurs"() { def list = new BlockingVariable() when: list.get() then: thrown(SpockTimeoutError) } def "timeout is configurable"() { def list = new BlockingVariable(1, TimeUnit.MILLISECONDS) when: list.get() then: thrown(SpockTimeoutError) } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/concurrent/BlockingVariablesSpec.groovy000066400000000000000000000044421202022523300335660ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.concurrent import org.spockframework.runtime.ConditionNotSatisfiedError import org.spockframework.runtime.SpockTimeoutError import spock.lang.* class BlockingVariablesSpec extends Specification { def "passing example 1 - variable is read after it is written"() { def vars = new BlockingVariables() when: Thread.start { vars.foo = 42 } Thread.sleep(500) then: vars.foo == 42 } def "passing example 2 - variable is read before it is written"() { def vars = new BlockingVariables() when: Thread.start { Thread.sleep(500) vars.foo = 42 } then: vars.foo == 42 } @FailsWith(ConditionNotSatisfiedError) def "failing example 1 - variable has wrong value"() { def vars = new BlockingVariables() when: Thread.start { vars.foo = 42 } then: vars.foo == 21 } @FailsWith(SpockTimeoutError) def "failing example 2 - variable is read but not written"() { def vars = new BlockingVariables() when: Thread.start { vars.foo = 42 } then: vars.bar == 42 } def "multiple variables"() { def vars = new BlockingVariables() when: Thread.start { vars.baz = 3 vars.bar = 2 } Thread.start { vars.foo = 1 } then: vars.foo == 1 vars.bar == 2 vars.baz == 3 } def "variable may be null"() { def vars = new BlockingVariables() when: Thread.start { vars.foo = null } then: vars.foo == null } def "vars can be used in single thread"() { def vars = new BlockingVariables() when: vars.bar = 2 vars.foo = 1 then: vars.foo == 1 vars.bar == 2 } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/matcher/000077500000000000000000000000001202022523300253605ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/matcher/IsCloseToSpec.groovy000066400000000000000000000027521202022523300313140ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.matcher import org.spockframework.runtime.ConditionNotSatisfiedError import spock.lang.* import static spock.util.matcher.HamcrestMatchers.closeTo class IsCloseToSpec extends Specification { def "compare Integers that are close enough"() { expect: 3 closeTo(2, 1) 3 closeTo(3, 0) 3 closeTo(4, 1) } @FailsWith(ConditionNotSatisfiedError) def "compare Integers that are not close enough"() { expect: 3 closeTo(1, 1) } def "compare BigDecimals that are close enough"() { expect: 3.1415 closeTo(3.1, 0.05) 3.1415 closeTo(3.1415000, 0) 3.1415 closeTo(3.2, 0.06) } @FailsWith(ConditionNotSatisfiedError) def "compare BigDecimals that are not close enough"() { expect: 3.1415 closeTo(3.0, 0.05) } def "mix integer and floating point numbers"() { expect: 3.1415 closeTo(3, 0.15) 3 closeTo(3.2, 1) } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/mop/000077500000000000000000000000001202022523300245305ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/mop/ConfineMetaClassChangesSpec.groovy000066400000000000000000000066011202022523300332640ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.mop import org.spockframework.EmbeddedSpecification import spock.lang.* /** * @author Luke Daley */ @Stepwise class ConfineMetaClassChangesSpec extends EmbeddedSpecification { def setupSpec() { newValue = 1 } def "change the metaclass"() { expect: value == 1 when: newValue = 2 then: value == 2 } def "value is still changed value"() { expect: value == 2 } @ConfineMetaClassChanges(String) def "change it again, but with restore annotation"() { expect: value == 2 when: newValue = 3 then: value == 3 } def "changes have been reverted"() { expect: value == 2 } @ConfineMetaClassChanges([String, String]) def "ensure duplicate classes in restore list don't cause errors"() { expect: true } @ConfineMetaClassChanges([String, Integer]) def "change more than one type"() { expect: value == 2 when: setNewValue(3, String) setNewValue(3, Integer) then: getValue("") == 3 getValue(1) == 3 } def "changes are reverted on both"() { expect: getValue("") == 2 when: getValue(1) then: thrown(MissingMethodException) } def "exercise a spec level restore"() { setup: newValue = 2 compiler.addPackageImport(getClass().package) def specs = compiler.compileWithImports(""" import spock.util.mop.ConfineMetaClassChanges $annotation @Stepwise class Spec1 extends Specification { def feature1() { expect: ConfineMetaClassChangesSpec.getValue() == 2 when: ConfineMetaClassChangesSpec.setNewValue(3) then: ConfineMetaClassChangesSpec.getValue() == 3 } def feature2() { expect: ConfineMetaClassChangesSpec.getValue() == 3 } } """) when: def failureCount = runner.runClasses(specs).failureCount then: failureCount == 0 value == afterValue where: annotation | afterValue "" | 3 "@ConfineMetaClassChanges(String)" | 2 } @ConfineMetaClassChanges(String) def "meta classes are restored after each iteration"() { expect: value == i when: newValue = i + 1 then: value == i + 1 where: i << [2,2] } def "meta class was restored after parameterised"() { expect: value == 2 } @ConfineMetaClassChanges([]) def "annotation with empty list/array value doesn't cause an error"(){ expect: true } def cleanupSpec() { [String, Integer].each { GroovySystem.metaClassRegistry.removeMetaClass(it) } } static setNewValue(value, type = String) { type.metaClass.getIsolateMetaClassExtensionValue = { -> value } } static getValue(seed = "") { seed.getIsolateMetaClassExtensionValue() } } spock-0.6-groovy-1.8/spock-specs/src/test/groovy/spock/util/mop/UseSpec.groovy000066400000000000000000000044561202022523300273570ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.util.mop import spock.lang.Specification class UseOnMethods extends Specification { // can be applied to a fixture method @Use(StringExtensions) def setupSpec() { assert "foo".duplicate() == "foofoo" } @Use(StringExtensions) def "can be applied to a feature method"() { expect: "foo".duplicate() == "foofoo" } @Use([StringExtensions, IntegerExtensions]) def "can use multiple categories"() { expect: 3.mul(4) == 12 "foo".duplicate() == "foofoo" } def "has no effect when applied to a helper method"() { when: helper() then: thrown(MissingMethodException) } @Use(StringExtensions) def helper() { "foo".duplicate() } def "has no effect on remaining feature methods"() { when: "foo".duplicate() then: thrown(MissingMethodException) } // has no effect on remaining fixture methods def setup() { try { "foo".duplicate() assert false } catch (MissingMethodException expected) {} } } @Use(StringExtensions) class UseOnClasses extends Specification { // affects fixture methods def setupSpec() { assert "foo".duplicate() == "foofoo" } def "affects feature methods"() { expect: "foo".duplicate() == "foofoo" } def "affects helper methods"() { when: helper() then: noExceptionThrown() } def helper() { assert "foo".duplicate() == "foofoo" } @Use(IntegerExtensions) def "can be combined with method-level category"() { expect: 3.mul(4) == 12 "foo".duplicate() == "foofoo" } } class StringExtensions { static String duplicate(String str) { str * 2 } } class IntegerExtensions { static mul(Integer n, Integer m) { n * m } }spock-0.6-groovy-1.8/spock-specs/src/test/java/000077500000000000000000000000001202022523300212355ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/000077500000000000000000000000001202022523300220245ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/000077500000000000000000000000001202022523300250615ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/groovy/000077500000000000000000000000001202022523300264065ustar00rootroot00000000000000JavaAnnotationWithClassRetention.java000077500000000000000000000015321202022523300356240ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/groovy/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * For testing purposes. */ @Retention(RetentionPolicy.CLASS) public @interface JavaAnnotationWithClassRetention { }JavaAnnotationWithRuntimeRetention.java000077500000000000000000000015361202022523300362060ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/groovy/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * For testing purposes. */ @Retention(RetentionPolicy.RUNTIME) public @interface JavaAnnotationWithRuntimeRetention { }JavaAnnotationWithSourceRetention.java000077500000000000000000000015351202022523300360220ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/groovy/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * For testing purposes. */ @Retention(RetentionPolicy.SOURCE) public @interface JavaAnnotationWithSourceRetention { } spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/groovy/JavaVarArgs.java000066400000000000000000000015111202022523300314160ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.groovy; public class JavaVarArgs { public static String[] varArgMethod(int i, String... strings) { return strings; } public static String[] arrayMethod(int i, String[] strings) { return strings; } } spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/junit/000077500000000000000000000000001202022523300262125ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/junit/Base.java000066400000000000000000000015111202022523300277250ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.junit; import org.junit.*; @Ignore public class Base { @Before public void before() { System.out.println("base"); } @Ignore @Test public void one() {} @Test public void odne() {} }spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/junit/Derived.java000066400000000000000000000014741202022523300304450ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.junit; import org.junit.*; @Ignore public class Derived extends Base { @Before public void before() { System.out.println("derived"); } @Ignore @Test public void two() {} } spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/junit/HelloSpockWithJUnit.java000066400000000000000000000024641202022523300327340ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.junit; import java.util.Arrays; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import static org.junit.Assert.assertEquals; @RunWith(Parameterized.class) public class HelloSpockWithJUnit { private String name; private int length; public HelloSpockWithJUnit(String name, int length) { this.name = name; this.length = length; } @Parameters public static List data() { return Arrays.asList(new Object[][] {{"Spock", 5}, {"Kirk", 4}, {"Scotty", 6}}); } @Test public void lengthOfSpockAndFriends() { assertEquals(length, name.length()); } }spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/junit/StringComparison.java000066400000000000000000000022451202022523300323610ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.junit; import org.junit.ComparisonFailure; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Conclusions: * 1. JUnit's string diffing is pretty simplistic (in the test below, * JUnit doesn't find any similarities between the two strings) * 2. As soon as at least one string contains a line break, * IDEA offers to compare strings in diff dialog. */ public class StringComparison { @Test(expected = ComparisonFailure.class) public void testCompareStrings() { assertEquals("1aaaaaaaa2", "2aaaaaaaa1"); } }spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/mock/000077500000000000000000000000001202022523300260125ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/mock/InterfaceWithNestedClass.java000066400000000000000000000003241202022523300335410ustar00rootroot00000000000000package org.spockframework.mock; public interface InterfaceWithNestedClass { class Service { private Service() {} public static InterfaceWithNestedClass getInstance() { return null; } } } spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/runtime/000077500000000000000000000000001202022523300265445ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/runtime/JavaMethods.java000066400000000000000000000016301202022523300316140ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.runtime; /** * @author Peter Niederwieser */ public class JavaMethods { public void voidInstanceMethod() {} public Object nonVoidInstanceMethod() { return null; } public static void voidStaticMethod() {} public static Object nonVoidStaticMethod() { return null; } } spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/smoke/000077500000000000000000000000001202022523300261775ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/smoke/CallChainException.java000066400000000000000000000013551202022523300325430ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke; /** * @author Peter Niederwieser */ public class CallChainException extends RuntimeException {} spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/smoke/JavaCallChain.java000066400000000000000000000022541202022523300314650ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.smoke; /** * Important: This file needs to be exact copy of GroovyCallChain.groovy. * * @author Peter Niederwieser */ public class JavaCallChain { public void a() { b(); } private int b() { new Inner().inner(); return 0; } static void c(String foo, String bar) { throw new CallChainException(); } class Inner { public void inner() { new StaticInner().staticInner(); } } static class StaticInner { public void staticInner() { c("foo", "bar"); } } } spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/smoke/mock/000077500000000000000000000000001202022523300271305ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/java/org/spockframework/smoke/mock/JavaCaller.java000066400000000000000000000004231202022523300317760ustar00rootroot00000000000000package org.spockframework.smoke.mock; import java.util.concurrent.Callable; public class JavaCaller { public Throwable call(Callable callable) throws Exception { try { callable.call(); return null; } catch (Throwable t) { return t; } } } spock-0.6-groovy-1.8/spock-specs/src/test/resources/000077500000000000000000000000001202022523300223265ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/resources/org/000077500000000000000000000000001202022523300231155ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/resources/org/spockframework/000077500000000000000000000000001202022523300261525ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/resources/org/spockframework/runtime/000077500000000000000000000000001202022523300276355ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-specs/src/test/resources/org/spockframework/runtime/InvalidConfig.txt000066400000000000000000000000101202022523300331010ustar00rootroot00000000000000runner {spock-0.6-groovy-1.8/spock-specs/src/test/resources/org/spockframework/runtime/ValidConfig.txt000066400000000000000000000000431202022523300325600ustar00rootroot00000000000000runner { filterStackTrace false }spock-0.6-groovy-1.8/spock-specs/src/test/resources/org/spockframework/runtime/extensionDescriptor000066400000000000000000000002031202022523300336260ustar00rootroot00000000000000# some comment org.spockframework.runtime.Extension1 #another comment org.spockframework.runtime.Extension2spock-0.6-groovy-1.8/spock-spring/000077500000000000000000000000001202022523300167335ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/spring.gradle000077500000000000000000000015111202022523300214160ustar00rootroot00000000000000apply from: script("publishMaven") displayName = "Spock Framework - Spring Module" description = "Spock's Spring Module makes it possible to use Spring's TestContext framework together with Spock. \ Both Spring 2.5.x and 3.x are supported." def springVersion = "3.1.0.RELEASE" dependencies { compile project(":spock-core") compile "org.springframework:spring-test:$springVersion", provided compile "org.springframework:spring-beans:$springVersion", provided testCompile "org.springframework:spring-context:$springVersion" // not used directly at compile-time, but needed by groovyc testCompile "org.springframework:spring-core:$springVersion" testCompile "org.springframework:spring-jdbc:$springVersion" testCompile "org.springframework:spring-tx:$springVersion" testRuntime libs.h2database testRuntime libs.log4j } spock-0.6-groovy-1.8/spock-spring/src/000077500000000000000000000000001202022523300175225ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/000077500000000000000000000000001202022523300204465ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/java/000077500000000000000000000000001202022523300213675ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/java/org/000077500000000000000000000000001202022523300221565ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/java/org/spockframework/000077500000000000000000000000001202022523300252135ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/java/org/spockframework/spring/000077500000000000000000000000001202022523300265155ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/java/org/spockframework/spring/SpringExtension.java000066400000000000000000000056461202022523300325320ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.ProfileValueUtils; import org.springframework.test.context.ContextConfiguration; import org.spockframework.runtime.AbstractRunListener; import org.spockframework.runtime.extension.IGlobalExtension; import org.spockframework.runtime.model.*; import org.spockframework.util.*; import spock.lang.Shared; @NotThreadSafe public class SpringExtension implements IGlobalExtension { public void visitSpec(SpecInfo spec) { if (!spec.getReflection().isAnnotationPresent(ContextConfiguration.class)) return; checkNoSharedFieldsInjected(spec); if (!handleProfileValues(spec)) return; SpringTestContextManager manager = new SpringTestContextManager(spec.getReflection()); final SpringInterceptor interceptor = new SpringInterceptor(manager); spec.addListener(new AbstractRunListener() { public void error(ErrorInfo error) { interceptor.error(error); } }); SpecInfo topSpec = spec.getTopSpec(); topSpec.getSetupSpecMethod().addInterceptor(interceptor); topSpec.getSetupMethod().addInterceptor(interceptor); topSpec.getCleanupMethod().addInterceptor(interceptor); topSpec.getCleanupSpecMethod().addInterceptor(interceptor); } private void checkNoSharedFieldsInjected(SpecInfo spec) { for (FieldInfo field : spec.getAllFields()) { if (field.getReflection().isAnnotationPresent(Shared.class) && (field.getReflection().isAnnotationPresent(Autowired.class) // avoid compile-time dependency on JDK 1.6 only class || ReflectionUtil.isAnnotationPresent(field.getReflection(), "javax.annotation.Resource"))) throw new SpringExtensionException( "@Shared field '%s' cannot be injected; use an instance field instead").withArgs(field.getName()); } } private boolean handleProfileValues(SpecInfo spec) { if (!ProfileValueUtils.isTestEnabledInThisEnvironment(spec.getReflection())) { spec.setExcluded(true); return false; } for (FeatureInfo feature : spec.getAllFeatures()) if (!ProfileValueUtils.isTestEnabledInThisEnvironment( feature.getFeatureMethod().getReflection(), spec.getReflection())) feature.setExcluded(true); return true; } } SpringExtensionException.java000066400000000000000000000017041202022523300343210ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/java/org/spockframework/spring/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring; import org.spockframework.runtime.extension.ExtensionException; public class SpringExtensionException extends ExtensionException { public SpringExtensionException(String message) { super(message); } public SpringExtensionException(String message, Throwable cause) { super(message, cause); } } spock-0.6-groovy-1.8/spock-spring/src/main/java/org/spockframework/spring/SpringInterceptor.java000066400000000000000000000056671202022523300330570ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring; import org.spockframework.runtime.extension.*; import org.spockframework.runtime.model.ErrorInfo; import org.spockframework.util.NotThreadSafe; @NotThreadSafe public class SpringInterceptor extends AbstractMethodInterceptor { private final SpringTestContextManager manager; private Throwable exception; private boolean beforeTestMethodInvoked = false; public SpringInterceptor(SpringTestContextManager manager) { this.manager = manager; } @Override public void interceptSetupSpecMethod(IMethodInvocation invocation) throws Throwable { manager.beforeTestClass(); invocation.proceed(); } @Override public void interceptSetupMethod(IMethodInvocation invocation) throws Throwable { manager.prepareTestInstance(invocation.getTarget()); exception = null; beforeTestMethodInvoked = true; manager.beforeTestMethod(invocation.getTarget(), invocation.getFeature().getFeatureMethod().getReflection()); invocation.proceed(); } @Override public void interceptCleanupMethod(IMethodInvocation invocation) throws Throwable { if (!beforeTestMethodInvoked) { invocation.proceed(); return; } beforeTestMethodInvoked = false; Throwable cleanupEx = null; try { invocation.proceed(); } catch (Throwable t) { cleanupEx = t; if (exception == null) exception = t; } Throwable afterTestMethodEx = null; try { manager.afterTestMethod(invocation.getTarget(), invocation.getFeature().getFeatureMethod().getReflection(), exception); } catch (Throwable t) { afterTestMethodEx = t; } if (cleanupEx != null) throw cleanupEx; if (afterTestMethodEx != null) throw afterTestMethodEx; } @Override public void interceptCleanupSpecMethod(IMethodInvocation invocation) throws Throwable { Throwable cleanupSpecEx = null; try { invocation.proceed(); } catch (Throwable t) { cleanupSpecEx = t; } Throwable afterTestClassEx = null; try { manager.afterTestClass(); } catch (Throwable t) { afterTestClassEx = t; } if (cleanupSpecEx != null) throw cleanupSpecEx; if (afterTestClassEx != null) throw afterTestClassEx; } public void error(ErrorInfo error) { if (exception == null) exception = error.getException(); } } SpringTestContextManager.java000066400000000000000000000041531202022523300342460ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/java/org/spockframework/spring/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring; import java.lang.reflect.Method; import org.springframework.test.context.TestContextManager; import org.spockframework.util.ReflectionUtil; /** * Wrapper around Spring's TestContextManager class that works with Spring 2.5 and Spring 3. */ public class SpringTestContextManager { private static final Method beforeTestClassMethod = ReflectionUtil.getMethodBySignature(TestContextManager.class, "beforeTestClass"); private static final Method afterTestClassMethod = ReflectionUtil.getMethodBySignature(TestContextManager.class, "afterTestClass"); private final TestContextManager delegate; public SpringTestContextManager(Class testClass) { delegate = new TestContextManager(testClass); } public void beforeTestClass() throws Exception { if (beforeTestClassMethod != null) ReflectionUtil.invokeMethod(delegate, beforeTestClassMethod); } public void afterTestClass() throws Exception { if (afterTestClassMethod != null) ReflectionUtil.invokeMethod(delegate, afterTestClassMethod); } public void prepareTestInstance(Object testInstance) throws Exception { delegate.prepareTestInstance(testInstance); } public void beforeTestMethod(Object testInstance, Method testMethod) throws Exception { delegate.beforeTestMethod(testInstance, testMethod); } public void afterTestMethod(Object testInstance, Method testMethod, Throwable exception) throws Exception { delegate.afterTestMethod(testInstance, testMethod, exception); } } spock-0.6-groovy-1.8/spock-spring/src/main/resources/000077500000000000000000000000001202022523300224605ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/resources/META-INF/000077500000000000000000000000001202022523300236205ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/resources/META-INF/services/000077500000000000000000000000001202022523300254435ustar00rootroot00000000000000org.spockframework.runtime.extension.IGlobalExtension000066400000000000000000000000511202022523300400300ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/main/resources/META-INF/servicesorg.spockframework.spring.SpringExtensionspock-0.6-groovy-1.8/spock-spring/src/test/000077500000000000000000000000001202022523300205015ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/groovy/000077500000000000000000000000001202022523300220265ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/000077500000000000000000000000001202022523300226155ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/000077500000000000000000000000001202022523300256525ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/000077500000000000000000000000001202022523300271545ustar00rootroot00000000000000DirtiesContextExample.groovy000066400000000000000000000023621202022523300346330ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.ApplicationContext import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.ContextConfiguration import spock.lang.* @ContextConfiguration(locations = "InjectionExamples-context.xml") class DirtiesContextExample extends Specification { @Shared savedContext @Autowired ApplicationContext context @DirtiesContext def "first spec method"() { setup: savedContext = context } def "second spec method"() { expect: !context.is(savedContext) } } spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/IService1.groovy000066400000000000000000000012771202022523300322240ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring interface IService1 { String generateString() } spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/IService2.groovy000066400000000000000000000013041202022523300322140ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring public interface IService2 { String generateQuickBrownFox() }spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/InjectionExamples.groovy000066400000000000000000000051301202022523300340430ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.ApplicationContext import org.springframework.test.context.ContextConfiguration import org.spockframework.util.ReflectionUtil import spock.util.EmbeddedSpecRunner import spock.lang.* @ContextConfiguration(locations = "InjectionExamples-context.xml") class InjectionExamples extends Specification { @Autowired IService1 service @Autowired ApplicationContext context def "injecting a field by type"() { expect: service instanceof IService1 } def "injecting a field by name (@Resource is JDK 1.6 only)"() { if (!ReflectionUtil.isClassAvailable("javax.annotation.Resource")) return def runner = new EmbeddedSpecRunner() when: runner.run """ package org.spockframework.spring import javax.annotation.Resource import org.spockframework.spring.IService1 import org.springframework.test.context.ContextConfiguration import spock.lang.* @ContextConfiguration(locations = "InjectionExamples-context.xml") class Foo extends Specification { @Resource IService1 myService1 def foo() { expect: myService1 instanceof IService1 } } """ then: noExceptionThrown() } def "direct usage of application context (discouraged)"() { expect: context != null context.getBean("myService1") instanceof IService1 } def "shared fields cannot be injected"() { if (!ReflectionUtil.isClassAvailable(ann)) return def runner = new EmbeddedSpecRunner() when: runner.runWithImports """ import org.spockframework.spring.IService1 import org.springframework.test.context.ContextConfiguration @ContextConfiguration class Foo extends Specification { @$ann @Shared IService1 sharedService def foo() { expect: true } } """ then: thrown(SpringExtensionException) where: ann << ["org.springframework.beans.factory.annotation.Autowired", "javax.annotation.Resource"] } } spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/Service1.groovy000066400000000000000000000015371202022523300321120ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring public class Service1 implements IService1 { private IService2 service2 Service1(Service2 service2) { this.service2 = service2 } String generateString() { service2.generateQuickBrownFox() } } spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/Service2.groovy000066400000000000000000000014131202022523300321040ustar00rootroot00000000000000 /* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring class Service2 implements IService2 { def String generateQuickBrownFox() { "The quick brown fox jumps over the lazy dog." } }SpringSpecInheritance.groovy000066400000000000000000000026501202022523300345760ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.ContextConfiguration import spock.lang.* abstract class BaseSpec extends Specification { @Autowired IService1 service1 def setup() { assert service1 instanceof IService1 assert this.service2 instanceof IService2 } } @ContextConfiguration(locations = "InjectionExamples-context.xml") class SpringSpecInheritance extends BaseSpec { @Autowired IService2 service2 def setup() { assert service1 instanceof IService1 assert service2 instanceof IService2 } def "fields of base class have been injected"() { expect: service1 instanceof IService1 } def "fields of derived class have been injected"() { expect: service2 instanceof IService2 } } TransactionalExample.groovy000066400000000000000000000046751202022523300344760ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring import org.springframework.beans.factory.annotation.Autowired import org.springframework.jdbc.core.JdbcTemplate import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.transaction.BeforeTransaction import org.springframework.transaction.annotation.Transactional import spock.lang.* /* * Shows how to leverage the Spring TestContext framework's transaction * support, using JdbcTemplate for interacting with the database. * * To learn more about transaction management in the Spring TestContext * framework, see: * http://static.springsource.org/spring/docs/3.0.x/reference/testing.html#testcontext-tx * * Note: Due to the way Spring's TestContext framework is designed, * @Shared fields cannot be injected. This also means that * setupSpec() and cleanupSpec() cannot get access to Spring beans. */ @ContextConfiguration(locations = "TransactionalExample-context.xml") class TransactionalExample extends Specification { @Shared boolean tableCreated = false @Autowired JdbcTemplate template /* * Populates the database. To prevent automatic rollback, we use a * @BeforeTransaction rather than a setup() method. Checking the * tableCreated flag ensures that the code is only run once. */ @BeforeTransaction def createTable() { if (tableCreated) return template.execute("create table data (id int, name varchar(25))") template.update("insert into data (id, name) values (?, ?), (?, ?)", [1, "fred", 2, "tom"] as Object[]) tableCreated = true } @Transactional def "delete rows from table"() { setup: template.update("delete from data") } @Transactional def "table is back to initial state"() { expect: template.queryForList("select * from data order by id") == [[ID: 1, NAME: "fred"], [ID: 2, NAME: "tom"]] } } TransactionalGroovySqlExample.groovy000066400000000000000000000050131202022523300363470ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/groovy/org/spockframework/spring/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.spring import javax.sql.DataSource import groovy.sql.Sql import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.transaction.BeforeTransaction import org.springframework.transaction.annotation.Transactional import spock.lang.Shared import spock.lang.Specification /* * Shows how to leverage the Spring TestContext framework's transaction * support, using groovy.sql.Sql for interacting with the database. * * To learn more about transaction management in the Spring TestContext * framework, see: * http://static.springsource.org/spring/docs/3.0.x/reference/testing.html#testcontext-tx * * Note: Due to the way Spring's TestContext framework is designed, * @Shared fields cannot be injected. This also means that * setupSpec() and cleanupSpec() cannot get access to Spring beans. */ @ContextConfiguration(locations = "TransactionalGroovySqlExample-context.xml") class TransactionalGroovySqlExample extends Specification { @Shared boolean tableCreated = false @Shared Sql sql @Autowired DataSource dataSource /* * Populates the database. To prevent automatic rollback, we use a * @BeforeTransaction rather than a setup() method. Checking the * tableCreated flag ensures that the code is only run once. */ @BeforeTransaction def createTable() { if (tableCreated) return sql = new Sql(dataSource) sql.execute("create table data (id int, name varchar(25))") sql.executeUpdate("insert into data (id, name) values (?, ?), (?, ?)", [1, "fred", 2, "tom"]) tableCreated = true } @Transactional def "delete rows from table"() { setup: sql.execute("delete from data") } @Transactional def "table is back to initial state"() { expect: sql.rows("select * from data order by id") == [[ID: 1, NAME: "fred"], [ID: 2, NAME: "tom"]] } } spock-0.6-groovy-1.8/spock-spring/src/test/resources/000077500000000000000000000000001202022523300225135ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/resources/log4j.properties000066400000000000000000000004261202022523300256520ustar00rootroot00000000000000log4j.rootLogger = WARN, X #log4j.logger.org.springframework.transaction=DEBUG #log4j.logger.org.springframework.test=DEBUG log4j.appender.X=org.apache.log4j.ConsoleAppender log4j.appender.X.layout=org.apache.log4j.PatternLayout log4j.appender.X.layout.conversionPattern=%m%n spock-0.6-groovy-1.8/spock-spring/src/test/resources/org/000077500000000000000000000000001202022523300233025ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/resources/org/spockframework/000077500000000000000000000000001202022523300263375ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/resources/org/spockframework/spring/000077500000000000000000000000001202022523300276415ustar00rootroot00000000000000InjectionExamples-context.xml000066400000000000000000000007731202022523300354160ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/resources/org/spockframework/spring TransactionalExample-context.xml000066400000000000000000000015061202022523300361060ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/resources/org/spockframework/spring TransactionalGroovySqlExample-context.xml000066400000000000000000000013601202022523300377720ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-spring/src/test/resources/org/spockframework/spring spock-0.6-groovy-1.8/spock-tapestry/000077500000000000000000000000001202022523300173045ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/000077500000000000000000000000001202022523300200735ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/000077500000000000000000000000001202022523300210175ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/java/000077500000000000000000000000001202022523300217405ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/java/org/000077500000000000000000000000001202022523300225275ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/java/org/spockframework/000077500000000000000000000000001202022523300255645ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/java/org/spockframework/tapestry/000077500000000000000000000000001202022523300274375ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/java/org/spockframework/tapestry/ExtensionModule.java000066400000000000000000000020331202022523300334220ustar00rootroot00000000000000/* * Copyright 2009, 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; import org.apache.tapestry5.ioc.ObjectLocator; import org.apache.tapestry5.ioc.annotations.Marker; /** * A Tapestry module that is started for every specification which uses Spock's * Tapestry extension. * * @author Peter Niederwieser */ @Marker(SpockTapestry.class) public class ExtensionModule { public static ObjectLocator build(ObjectLocator locator) { return locator; } } spock-0.6-groovy-1.8/spock-tapestry/src/main/java/org/spockframework/tapestry/SpockTapestry.java000066400000000000000000000021301202022523300331110ustar00rootroot00000000000000/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Marker annotation for services that are specific to the Spock/Tapestry integration module. * * @see ExtensionModule */ @Target({PARAMETER, FIELD, METHOD}) @Retention(RUNTIME) @Documented public @interface SpockTapestry {}spock-0.6-groovy-1.8/spock-tapestry/src/main/java/org/spockframework/tapestry/TapestryExtension.java000066400000000000000000000114221202022523300340120ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; import java.util.*; import org.apache.tapestry5.ioc.annotations.SubModule; import org.spockframework.runtime.extension.IGlobalExtension; import org.spockframework.runtime.extension.IMethodInterceptor; import org.spockframework.runtime.model.SpecInfo; /** * Facilitates the creation of integration-level specifications for applications based * on the Tapestry 5 inversion-of-control container. The main focus is on injecting * specifications with Tapestry-provided objects. This works just like for * regular Tapestry services, except that only field (and no constructor) * injection is supported. * *

Instead of inventing its own set of annotations, this extension reuses * Tapestry's own annotations. In particular, * *

    *
  • @SubModule indicates which Tapestry module(s) should be started * (and subsequently shut down)
  • *
  • @Inject marks fields which should be injected with a Tapestry service or * symbol
  • *
* * Related Tapestry annotations, such as @Service and @Symbol, * are also supported. For information on their use, see the * Tapestry IoC documentation. * To interact directly with the Tapestry registry, an injection point of type * ObjectLocator may be defined. However, this should be rarely needed. * *

For every specification annotated with @SubModule, the Tapestry * registry will be started up (and subsequently shut down) once. Because fields are injected * before field initializers and the setup()/setupSpec() * methods are run, they can be safely accessed from these places. * *

Fields marked as @Shared are injected once per specification; regular * fields once per feature (iteration). However, this does not mean that each * feature will receive a fresh service instance; rather, it is left to the Tapestry * registry to control the lifecycle of a service. Most Tapestry services use the default * "singleton" scope, which results in the same service instance being shared between all * features. * *

Features that require their own service instance(s) should be moved into separate * specifications. To avoid code fragmentation and duplication, you might want to put * multiple (micro-)specifications into the same source file, and factor out their * commonalities into a base class. * *

Usage example: * *

 * @SubModule(UniverseModule)
 * class UniverseSpec extends Specification {
 *   @Inject
 *   UniverseService service
 *
 *   UniverseService copy = service
 *
 *   def "service knows the answer to the universe"() {
 *     expect:
 *     copy == service        // injection occurred before 'copy' was initialized
 *     service.answer() == 42 // what else did you expect?!
 *   }
 * }
 * 
* * @author Peter Niederwieser */ public class TapestryExtension implements IGlobalExtension { public void visitSpec(SpecInfo spec) { Set> modules = collectModules(spec); if (modules == null) return; IMethodInterceptor interceptor = new TapestryInterceptor(spec, modules); SpecInfo topSpec = spec.getTopSpec(); topSpec.getSharedInitializerMethod().addInterceptor(interceptor); topSpec.getInitializerMethod().addInterceptor(interceptor); topSpec.getCleanupMethod().addInterceptor(interceptor); topSpec.getCleanupSpecMethod().addInterceptor(interceptor); } // Returns null if no SubModule annotation was found. // Returns an empty list if one or more SubModule annotations were found, // but they didn't specify any modules. This distinction is important to // allow activation of the extension w/o specifying any modules. private Set> collectModules(SpecInfo spec) { Set> modules = null; for (SpecInfo curr : spec.getSpecsTopToBottom()) { SubModule subModule = curr.getReflection().getAnnotation(SubModule.class); if (subModule == null) continue; if (modules == null) modules = new HashSet>(); modules.addAll(Arrays.>asList(subModule.value())); } return modules; } } TapestryInterceptor.java000066400000000000000000000110471202022523300342600ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/java/org/spockframework/tapestry/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; import java.lang.annotation.Annotation; import java.lang.reflect.*; import java.util.*; import org.apache.tapestry5.ioc.*; import org.apache.tapestry5.ioc.annotations.Autobuild; import org.apache.tapestry5.ioc.annotations.Inject; import org.spockframework.runtime.extension.*; import org.spockframework.runtime.model.FieldInfo; import org.spockframework.runtime.model.SpecInfo; import org.spockframework.util.*; import spock.lang.Shared; import spock.lang.Specification; /** * Controls creation, startup and shutdown of the Tapestry container, * and injects specifications with Tapestry-provided objects. * * @author Peter Niederwieser */ // Important implementation detail: Only the fixture methods of // spec.getTopSpec() are intercepted (see TapestryExtension) public class TapestryInterceptor extends AbstractMethodInterceptor { private final SpecInfo spec; private final Set> modules; private Registry registry; public TapestryInterceptor(SpecInfo spec, Set> modules) { this.spec = spec; this.modules = modules; } @Override public void interceptSharedInitializerMethod(IMethodInvocation invocation) throws Throwable { runBeforeRegistryCreatedMethods((Specification) invocation.getTarget()); createAndStartupRegistry(); injectServices(invocation.getTarget(), true); invocation.proceed(); } @Override public void interceptCleanupSpecMethod(IMethodInvocation invocation) throws Throwable { try { invocation.proceed(); } finally { shutdownRegistry(); } } @Override public void interceptInitializerMethod(IMethodInvocation invocation) throws Throwable { injectServices(invocation.getTarget(), false); invocation.proceed(); } private void runBeforeRegistryCreatedMethods(Specification spec) { Object returnValue; for (Method method : findAllBeforeRegistryCreatedMethods()) { returnValue = ReflectionUtil.invokeMethod(spec, method); // Return values of a type other than Registry are silently ignored. // This avoids problems in case the method unintentionally returns a // value (which is common due to Groovy's implicit return). if (returnValue instanceof Registry) registry = (Registry) returnValue; } } private void createAndStartupRegistry() { if (registry != null) return; RegistryBuilder builder = new RegistryBuilder(); builder.add(ExtensionModule.class); for (Class module : modules) builder.add(module); registry = builder.build(); registry.performRegistryStartup(); } private List findAllBeforeRegistryCreatedMethods() { List methods = new ArrayList(); for (SpecInfo curr : spec.getSpecsTopToBottom()) { Method method = ReflectionUtil.getDeclaredMethodByName(curr.getReflection(), "beforeRegistryCreated"); if (method != null) { method.setAccessible(true); methods.add(method); } } return methods; } private void injectServices(Object target, boolean sharedFields) throws IllegalAccessException { for (final FieldInfo field : spec.getAllFields()) if ((field.getReflection().isAnnotationPresent(Inject.class) || field.getReflection().isAnnotationPresent(Autobuild.class)) && field.getReflection().isAnnotationPresent(Shared.class) == sharedFields) { Field rawField = field.getReflection(); Object value = registry.getObject(rawField.getType(), createAnnotationProvider(field)); rawField.setAccessible(true); rawField.set(target, value); } } private AnnotationProvider createAnnotationProvider(final FieldInfo field) { return new AnnotationProvider() { public T getAnnotation(Class annotationClass) { return field.getReflection().getAnnotation(annotationClass); } }; } private void shutdownRegistry() { if (registry != null) registry.shutdown(); } } spock-0.6-groovy-1.8/spock-tapestry/src/main/resources/000077500000000000000000000000001202022523300230315ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/resources/META-INF/000077500000000000000000000000001202022523300241715ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/resources/META-INF/services/000077500000000000000000000000001202022523300260145ustar00rootroot00000000000000org.spockframework.runtime.extension.IGlobalExtension000066400000000000000000000000551202022523300404050ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/main/resources/META-INF/servicesorg.spockframework.tapestry.TapestryExtensionspock-0.6-groovy-1.8/spock-tapestry/src/test/000077500000000000000000000000001202022523300210525ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/groovy/000077500000000000000000000000001202022523300223775ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/groovy/org/000077500000000000000000000000001202022523300231665ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/groovy/org/spockframework/000077500000000000000000000000001202022523300262235ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/groovy/org/spockframework/tapestry/000077500000000000000000000000001202022523300300765ustar00rootroot00000000000000BeforeRegistryCreatedMethod.groovy000066400000000000000000000041661202022523300366610ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/groovy/org/spockframework/tapestry/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry import org.apache.tapestry5.ioc.RegistryBuilder import org.apache.tapestry5.ioc.annotations.* import spock.lang.* @SubModule(Module1) class BeforeRegistryCreatedMethod extends Specification { @Shared @Inject IService1 sharedServiceField @Inject IService1 instanceServiceField @Shared String sharedField = "sharedField" String instanceField = "instanceField" @Shared boolean beforeRegistryCreatedRun def beforeRegistryCreated() { assert sharedServiceField == null assert instanceServiceField == null assert sharedField == null assert instanceField == null assert !beforeRegistryCreatedRun beforeRegistryCreatedRun = true } def beforeSpec() { assert sharedServiceField instanceof Service1 assert instanceServiceField == null assert sharedField == "sharedField" assert instanceField == null assert beforeRegistryCreatedRun } def feature() { expect: sharedServiceField instanceof IService1 instanceServiceField instanceof IService1 sharedField == "sharedField" instanceField == "instanceField" beforeRegistryCreatedRun } } @SubModule([]) class CustomTapestryRegistry extends Specification { @Inject IService1 service1 def beforeRegistryCreated() { def builder = new RegistryBuilder() builder.add(Module1) def registry = builder.build() registry.performRegistryStartup() registry } def "custom registry is used for injection"() { expect: service1 instanceof IService1 } } InjectionExamples.groovy000066400000000000000000000041511202022523300347100ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/groovy/org/spockframework/tapestry/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry import org.apache.tapestry5.ioc.ObjectLocator import org.apache.tapestry5.ioc.annotations.* import spock.lang.* @SubModule(Module1) class ServiceInjection extends Specification { @Inject IService1 service1 @Inject IService2 service2 def "injected services"() { expect: service1.generateString() == service2.generateQuickBrownFox() } } @SubModule(Module1) class ObjectLocatorInjection extends Specification { @Inject private ObjectLocator locator def "injected object locator"() { expect: locator.getService(IService1).generateString() == locator.getService(IService2).generateQuickBrownFox() } } @SubModule(Module1) class SymbolInjection extends Specification { @Inject @Symbol("java.version") String javaVersion @Inject @Symbol("configKey") // Groovy doesn't yet support constants in annotations, so we have to use a literal String configValue @Inject @Value("\${java.version} and \${configKey}") String computedValue def "injected system property"() { expect: javaVersion == System.getProperty("java.version") } def "injected application default"() { expect: configValue == "configValue" } def "injected computed value"() { expect: computedValue == "${System.getProperty("java.version")} and configValue" } } @SubModule(Module2) class AutobuildInjection extends Specification { @Autobuild Service1 service1 def "auto-built service"() { expect: service1 instanceof Service1 } }TapestrySpecInheritance.groovy000066400000000000000000000034131202022523300360670ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/groovy/org/spockframework/tapestry/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry import org.apache.tapestry5.ioc.annotations.* import spock.lang.* @SubModule(Module1) abstract class BaseSpec extends Specification { static beforeRegistryCreatedCount = 0 @Inject IService1 service1 @Inject IService2 service2 private beforeRegistryCreated() { assert beforeRegistryCreatedCount == 0 beforeRegistryCreatedCount++ } def setupSpec() { assert beforeRegistryCreatedCount == 2 } def setup() { assert service1 instanceof IService1 assert service2 instanceof IService2 } } @SubModule(Module2) class TapestrySpecInheritance extends BaseSpec { @Inject IService2 anotherService2 def beforeRegistryCreated() { assert beforeRegistryCreatedCount == 1 beforeRegistryCreatedCount++ } def setup() { assert service1 instanceof IService1 assert service2 instanceof IService2 assert anotherService2 instanceof IService2 } def "fields of base class have been injected"() { expect: service1 instanceof IService1 service2 instanceof IService2 } def "fields of derived class have been injected"() { expect: anotherService2 instanceof IService2 } } spock-0.6-groovy-1.8/spock-tapestry/src/test/java/000077500000000000000000000000001202022523300217735ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/java/org/000077500000000000000000000000001202022523300225625ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/java/org/spockframework/000077500000000000000000000000001202022523300256175ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/java/org/spockframework/tapestry/000077500000000000000000000000001202022523300274725ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-tapestry/src/test/java/org/spockframework/tapestry/IService1.java000066400000000000000000000013171202022523300321310ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; public interface IService1 { public String generateString(); } spock-0.6-groovy-1.8/spock-tapestry/src/test/java/org/spockframework/tapestry/IService2.java000066400000000000000000000013261202022523300321320ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; public interface IService2 { public String generateQuickBrownFox(); } spock-0.6-groovy-1.8/spock-tapestry/src/test/java/org/spockframework/tapestry/Module1.java000066400000000000000000000023321202022523300316430ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; import org.apache.tapestry5.ioc.MappedConfiguration; import org.apache.tapestry5.ioc.ServiceBinder; import org.apache.tapestry5.ioc.annotations.SubModule; // Tapestry module classes cannot currently be written in Groovy // See https://issues.apache.org/jira/browse/TAPESTRY-2746 @SubModule(Module2.class) public class Module1 { public static void bind(ServiceBinder binder) { binder.bind(IService1.class, Service1.class); } public void contributeApplicationDefaults(MappedConfiguration configuration) { configuration.add("configKey", "configValue"); } } spock-0.6-groovy-1.8/spock-tapestry/src/test/java/org/spockframework/tapestry/Module2.java000066400000000000000000000016721202022523300316520ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; import org.apache.tapestry5.ioc.ServiceBinder; // Tapestry module classes cannot currently be written in Groovy // See https://issues.apache.org/jira/browse/TAPESTRY-2746 public class Module2 { public static void bind(ServiceBinder binder) { binder.bind(IService2.class, Service2.class); } }spock-0.6-groovy-1.8/spock-tapestry/src/test/java/org/spockframework/tapestry/Service1.java000066400000000000000000000016011202022523300320140ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; public class Service1 implements IService1 { private final IService2 service2; public Service1(IService2 service2) { this.service2 = service2; } public String generateString() { return service2.generateQuickBrownFox(); } } spock-0.6-groovy-1.8/spock-tapestry/src/test/java/org/spockframework/tapestry/Service2.java000066400000000000000000000014461202022523300320240ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.tapestry; public class Service2 implements IService2 { public String generateQuickBrownFox() { return "The quick brown fox jumps over the lazy dog."; } } spock-0.6-groovy-1.8/spock-tapestry/tapestry.gradle000077500000000000000000000014661202022523300223510ustar00rootroot00000000000000apply from: script("publishMaven") displayName = "Spock Framework - Tapestry Module" description = "Spock's Tapestry Module provides support for testing Tapestry 5 based applications." repositories { // need to explicitly add repository defined in tapestry-ioc POM // (workaround for http://jira.codehaus.org/browse/GRADLE-611) maven { url "http://repository.jboss.com/maven2" } } // 5.3.x seems to require Java 1.6 (evidence: org.apache.tapestry5.ioc.internal.util.InternalUtils makes direct use of @PostConstruct) tapestryVersion = System.getProperty("java.version").startsWith("1.5") ? "5.2.6" : "5.3.2" dependencies { compile project(":spock-core") compile "org.apache.tapestry:tapestry-ioc:$tapestryVersion", provided compile "org.apache.tapestry:tapestry5-annotations:$tapestryVersion", provided } spock-0.6-groovy-1.8/spock-unitils/000077500000000000000000000000001202022523300171205ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/000077500000000000000000000000001202022523300177075ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/main/000077500000000000000000000000001202022523300206335ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/main/java/000077500000000000000000000000001202022523300215545ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/main/java/org/000077500000000000000000000000001202022523300223435ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/main/java/org/spockframework/000077500000000000000000000000001202022523300254005ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/main/java/org/spockframework/unitils/000077500000000000000000000000001202022523300270675ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/main/java/org/spockframework/unitils/UnitilsExtension.java000066400000000000000000000026611202022523300332630ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.unitils; import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension; import org.spockframework.runtime.model.*; import org.spockframework.util.NotThreadSafe; import spock.unitils.UnitilsSupport; @NotThreadSafe public class UnitilsExtension extends AbstractAnnotationDrivenExtension { @Override public void visitSpecAnnotation(UnitilsSupport unitilsSupport, SpecInfo spec) { UnitilsInterceptor interceptor = new UnitilsInterceptor(); spec.getSetupSpecMethod().addInterceptor(interceptor); spec.getSetupMethod().addInterceptor(interceptor); spec.getCleanupMethod().addInterceptor(interceptor); for (FeatureInfo feature : spec.getFeatures()) { feature.addInterceptor(interceptor); feature.getFeatureMethod().addInterceptor(interceptor); } } } spock-0.6-groovy-1.8/spock-unitils/src/main/java/org/spockframework/unitils/UnitilsInterceptor.java000066400000000000000000000051071202022523300336030ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.unitils; import org.unitils.core.TestListener; import org.unitils.core.Unitils; import org.spockframework.runtime.extension.AbstractMethodInterceptor; import org.spockframework.runtime.extension.IMethodInvocation; import org.spockframework.runtime.model.FeatureInfo; import org.spockframework.util.NotThreadSafe; @NotThreadSafe public class UnitilsInterceptor extends AbstractMethodInterceptor { private final TestListener listener = Unitils.getInstance().getTestListener(); private FeatureInfo currentFeature; @Override public void interceptSetupSpecMethod(IMethodInvocation invocation) throws Throwable { listener.beforeTestClass(invocation.getTarget().getClass()); invocation.proceed(); } @Override public void interceptSetupMethod(IMethodInvocation invocation) throws Throwable { listener.afterCreateTestObject(invocation.getTarget()); listener.beforeTestSetUp(invocation.getTarget(), currentFeature.getFeatureMethod().getReflection()); invocation.proceed(); } @Override public void interceptFeatureMethod(IMethodInvocation invocation) throws Throwable { Throwable throwable = null; listener.beforeTestMethod(invocation.getTarget(), invocation.getMethod().getReflection()); try { invocation.proceed(); } catch (Throwable t) { throwable = t; throw t; } finally { listener.afterTestMethod(invocation.getTarget(), invocation.getMethod().getReflection(), throwable); } } @Override public void interceptCleanupMethod(IMethodInvocation invocation) throws Throwable { try { invocation.proceed(); } finally { listener.afterTestTearDown(invocation.getTarget(), currentFeature.getFeatureMethod().getReflection()); } } @Override public void interceptFeatureExecution(IMethodInvocation invocation) throws Throwable { currentFeature = invocation.getMethod().getFeature(); try { invocation.proceed(); } finally { currentFeature = null; } } } spock-0.6-groovy-1.8/spock-unitils/src/main/java/spock/000077500000000000000000000000001202022523300226735ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/main/java/spock/unitils/000077500000000000000000000000001202022523300243625ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/main/java/spock/unitils/UnitilsSupport.java000066400000000000000000000020601202022523300302470ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package spock.unitils; import java.lang.annotation.*; import org.spockframework.runtime.extension.ExtensionAnnotation; import org.spockframework.unitils.UnitilsExtension; /** * Activates Unitils support for a specification. * All Unitils features are supported. */ @Inherited @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @ExtensionAnnotation(UnitilsExtension.class) public @interface UnitilsSupport {} spock-0.6-groovy-1.8/spock-unitils/src/main/java/spock/unitils/package-info.java000066400000000000000000000012761202022523300275570ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Integration with Unitils. */ package spock.unitils;spock-0.6-groovy-1.8/spock-unitils/src/test/000077500000000000000000000000001202022523300206665ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/groovy/000077500000000000000000000000001202022523300222135ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/groovy/org/000077500000000000000000000000001202022523300230025ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/groovy/org/spockframework/000077500000000000000000000000001202022523300260375ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/groovy/org/spockframework/unitils/000077500000000000000000000000001202022523300275265ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/groovy/org/spockframework/unitils/dbunit/000077500000000000000000000000001202022523300310135ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/groovy/org/spockframework/unitils/dbunit/User.groovy000066400000000000000000000013121202022523300331750ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.unitils.dbunit class User { String firstName String lastName int age }spock-0.6-groovy-1.8/spock-unitils/src/test/groovy/org/spockframework/unitils/dbunit/UserDao.groovy000066400000000000000000000023321202022523300336240ustar00rootroot00000000000000/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.unitils.dbunit import groovy.sql.Sql import javax.sql.DataSource class UserDao { private Sql sql UserDao(DataSource dataSource) { sql = new Sql(dataSource) } User findByName(String firstName, String lastName) { def row = sql.firstRow("select * from user where first_name=? and last_name=?", [firstName, lastName]) row2User(row) } List findByMinimalAge(int age) { sql.rows("select * from user where age >= ?", [age]).collect { row2User(it) } } private row2User(row) { new User(firstName: row.first_name, lastName: row.last_name, age: row.age) } }UserDaoSpec.groovy000066400000000000000000000032701202022523300343620ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/groovy/org/spockframework/unitils/dbunit/* * Copyright 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.spockframework.unitils.dbunit import javax.sql.DataSource import org.unitils.dbunit.annotation.DataSet import org.unitils.database.annotations.TestDataSource import groovy.sql.Sql import spock.lang.* import spock.unitils.UnitilsSupport import static org.unitils.reflectionassert.ReflectionAssert.assertPropertyLenientEquals @UnitilsSupport @DataSet class UserDaoSpec extends Specification { @Shared Sql sql = Sql.newInstance("jdbc:h2:mem:userdb", "org.h2.Driver") def setupSpec() { sql.execute("create table user (first_name varchar(25), last_name varchar(50), age int)") } def cleanupSpec() { sql.close() } @TestDataSource private DataSource dataSource def "find user by name"() { UserDao userDao = new UserDao(dataSource) def user = userDao.findByName("john", "doe") expect: assertPropertyLenientEquals("firstName", "john", user) } def "find users by minimal age"() { UserDao userDao = new UserDao(dataSource) List users = userDao.findByMinimalAge(18) expect: assertPropertyLenientEquals("age", [39], users) } } spock-0.6-groovy-1.8/spock-unitils/src/test/java/000077500000000000000000000000001202022523300216075ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/java/org/000077500000000000000000000000001202022523300223765ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/java/org/unitils/000077500000000000000000000000001202022523300240655ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/java/org/unitils/core/000077500000000000000000000000001202022523300250155ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/java/org/unitils/core/dbsupport/000077500000000000000000000000001202022523300270375ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/java/org/unitils/core/dbsupport/H2DbSupport.java000066400000000000000000000233641202022523300320260ustar00rootroot00000000000000/* * Copyright 2006-2007, Unitils.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.unitils.core.dbsupport; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.Set; import org.unitils.core.UnitilsException; import static org.unitils.thirdparty.org.apache.commons.dbutils.DbUtils.closeQuietly; // Copied from: http://jira.unitils.org/browse/UNI-79 /** * Implementation of {@link org.unitils.core.dbsupport.DbSupport} for a H2 * database * * @author Mark Thomas */ public class H2DbSupport extends DbSupport { /** * Creates support for H2 databases. */ public H2DbSupport() { super("h2"); } /** * Returns the names of all tables in the database. * * @return The names of all tables in the database */ @Override public Set getTableNames() { return getSQLHandler().getItemsAsStringSet("select TABLE_NAME from " + "INFORMATION_SCHEMA.TABLES where TABLE_TYPE = 'TABLE' AND " + "TABLE_SCHEMA = '" + getSchemaName() + "'"); } /** * Gets the names of all columns of the given table. * * @param tableName The table, not null * @return The names of the columns of the table with the given name */ @Override public Set getColumnNames(String tableName) { return getSQLHandler().getItemsAsStringSet("select COLUMN_NAME from " + "INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + getSchemaName() + "'"); } /** * Gets the names of all primary columns of the given table. * * @param tableName The table, not null * @return The names of the primary key columns of the table with the given * name */ @Override public Set getIdentityColumnNames(String tableName) { return getSQLHandler().getItemsAsStringSet("select COLUMN_NAME from " + "INFORMATION_SCHEMA.INDEXES where PRIMARY_KEY = 'TRUE' AND " + "TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + getSchemaName() + "'"); } /** * Retrieves the names of all the views in the database schema. * * @return The names of all views in the database */ @Override public Set getViewNames() { return getSQLHandler().getItemsAsStringSet("select TABLE_NAME from " + "INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '" + getSchemaName() + "'"); } /** * Retrieves the names of all the sequences in the database schema. * * @return The names of all sequences in the database */ @Override public Set getSequenceNames() { return getSQLHandler().getItemsAsStringSet("select SEQUENCE_NAME from " + "INFORMATION_SCHEMA.SEQUENCES where SEQUENCE_SCHEMA = '" + getSchemaName() + "'"); } /** * Retrieves the names of all the triggers in the database schema. * * @return The names of all triggers in the database */ @Override public Set getTriggerNames() { return getSQLHandler().getItemsAsStringSet("select TRIGGER_NAME from " + "INFORMATION_SCHEMA.TRIGGERS where TRIGGER_SCHEMA = '" + getSchemaName() + "'"); } /** * Returns the value of the sequence with the given name. *

* Note: this can have the side-effect of increasing the sequence value. * * @param sequenceName The sequence, not null * @return The value of the sequence with the given name */ @Override public long getSequenceValue(String sequenceName) { return getSQLHandler().getItemAsLong("select CURRENT_VALUE from " + "INFORMATION_SCHEMA.SEQUENCES where SEQUENCE_SCHEMA = '" + getSchemaName() + "' and SEQUENCE_NAME = '" + sequenceName + "'"); } /** * Sets the next value of the sequence with the given sequence name to the * given sequence value. * * @param sequenceName The sequence, not null * @param newSequenceValue The value to set */ @Override public void incrementSequenceToValue(String sequenceName, long newSequenceValue) { getSQLHandler().executeUpdate("alter sequence " + qualified(sequenceName) + " restart with " + newSequenceValue); } /** * Increments the identity value for the specified identity column on the * specified table to the given value. * * @param tableName The table with the identity column, not null * @param identityColumnName The column, not null * @param identityValue The new value */ @Override public void incrementIdentityColumnToValue(String tableName, String identityColumnName, long identityValue) { getSQLHandler().executeUpdate("alter table " + qualified(tableName) + " alter column " + quoted(identityColumnName) + " RESTART WITH " + identityValue); } /** * Disables all referential constraints (e.g. foreign keys) on all tables * in the schema */ @Override public void disableReferentialConstraints() { getSQLHandler().executeUpdate( "SET REFERENTIAL_INTEGRITY FALSE"); } /** * Disables all value constraints (e.g. not null) on all tables in the schema */ @Override public void disableValueConstraints() { disableCheckAndUniqueConstraints(); disableNotNullConstraints(); } /** * Disables all check and unique constraints on all tables in the schema */ protected void disableCheckAndUniqueConstraints() { Connection connection = null; Statement queryStatement = null; Statement alterStatement = null; ResultSet resultSet = null; try { connection = getSQLHandler().getDataSource().getConnection(); queryStatement = connection.createStatement(); alterStatement = connection.createStatement(); resultSet = queryStatement.executeQuery("select TABLE_NAME, " + "CONSTRAINT_NAME from INFORMATION_SCHEMA.CONSTRAINTS where " + "CONSTRAINT_TYPE IN ('CHECK', 'UNIQUE') AND CONSTRAINT_SCHEMA " + "= '" + getSchemaName() + "'"); while (resultSet.next()) { String tableName = resultSet.getString("TABLE_NAME"); String constraintName = resultSet.getString("CONSTRAINT_NAME"); alterStatement.executeUpdate("alter table " + qualified(tableName) + " drop constraint " + quoted(constraintName)); } } catch (Exception e) { throw new UnitilsException("Error while disabling check and unique " + "constraints on schema " + getSchemaName(), e); } finally { closeQuietly(queryStatement); closeQuietly(connection, alterStatement, resultSet); } } /** * Disables all not null constraints on all tables in the schema */ protected void disableNotNullConstraints() { Connection connection = null; Statement queryStatement = null; Statement alterStatement = null; ResultSet resultSet = null; try { connection = getSQLHandler().getDataSource().getConnection(); queryStatement = connection.createStatement(); alterStatement = connection.createStatement(); // Do not remove PK constraints resultSet = queryStatement.executeQuery("select col.TABLE_NAME, " + "col.COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS col where " + "col.IS_NULLABLE = 'NO' and col.TABLE_SCHEMA = '" + getSchemaName() + "' " + "AND NOT EXISTS (select COLUMN_NAME " + "from INFORMATION_SCHEMA.INDEXES pk where pk.TABLE_NAME = " + "col.TABLE_NAME and pk.COLUMN_NAME = col.COLUMN_NAME and " + "pk.TABLE_SCHEMA = '" + getSchemaName() + "' AND pk.PRIMARY_KEY = TRUE)"); while (resultSet.next()) { String tableName = resultSet.getString("TABLE_NAME"); String columnName = resultSet.getString("COLUMN_NAME"); alterStatement.executeUpdate("alter table " + qualified(tableName) + " alter column " + quoted(columnName) + " set null"); } } catch (Exception e) { throw new UnitilsException("Error while disabling not null " + "constraints on schema " + getSchemaName(), e); } finally { closeQuietly(queryStatement); closeQuietly(connection, alterStatement, resultSet); } } /** * Sequences are supported. * * @return True */ @Override public boolean supportsSequences() { return true; } /** * Triggers are supported. * * @return True */ @Override public boolean supportsTriggers() { return true; } /** * Identity columns are supported. * * @return True */ @Override public boolean supportsIdentityColumns() { return true; } /** * Cascade are supported. * * @return True */ @Override public boolean supportsCascade() { return true; } }spock-0.6-groovy-1.8/spock-unitils/src/test/resources/000077500000000000000000000000001202022523300227005ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/resources/org/000077500000000000000000000000001202022523300234675ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/resources/org/spockframework/000077500000000000000000000000001202022523300265245ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/resources/org/spockframework/unitils/000077500000000000000000000000001202022523300302135ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/resources/org/spockframework/unitils/dbunit/000077500000000000000000000000001202022523300315005ustar00rootroot00000000000000UserDaoSpec.xml000066400000000000000000000002471202022523300343230ustar00rootroot00000000000000spock-0.6-groovy-1.8/spock-unitils/src/test/resources/org/spockframework/unitils/dbunit spock-0.6-groovy-1.8/spock-unitils/src/test/resources/unitils.properties000066400000000000000000000006641202022523300265130ustar00rootroot00000000000000database.driverClassName=org.h2.Driver database.url=jdbc:h2:mem:userdb;IFEXISTS=TRUE database.dialect=h2 database.userName= database.password= database.schemaNames=public database.storedIndentifierCase.h2=auto database.identifierQuoteString.h2=auto org.unitils.core.dbsupport.DbSupport.implClassName.h2=org.unitils.core.dbsupport.H2DbSupport org.dbunit.dataset.datatype.IDataTypeFactory.implClassName=org.dbunit.ext.h2.H2DataTypeFactoryspock-0.6-groovy-1.8/spock-unitils/unitils.gradle000077500000000000000000000020321202022523300217670ustar00rootroot00000000000000apply from: script("publishMaven") displayName = "Spock Framework - Unitils Module" description = "Spock's Unitils Module makes it possible to use Unitils together with Spock." dependencies { compile project(":spock-core") compile "org.unitils:unitils-core:3.3" // the following are transitive deps of unitils-core with scope compile // nevertheless, if we don't specify them explicitely, groovyc crashes with // NoClassDefFoundError at org.codehaus.groovy.vmplugin.v5.Java5.configureClassNode(Java5.java:285) compile "commons-collections:commons-collections:3.2", internal compile "ognl:ognl:2.6.9", internal testCompile "org.unitils:unitils-dbunit:3.3", { exclude module: "jta" } testCompile "org.unitils:unitils-database:3.3", { exclude module: "jta" } // for some reason, groovyc needs junit dependency for compiling tests // otherwise we'll get: // java.lang.NoClassDefFoundError: junit/framework/AssertionFailedError testCompile libs.junit testRuntime libs.h2database testRuntime libs.log4j }