libdancer2-perl-0.166001+dfsg.orig/0000775000175000017500000000000012657672331016102 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/LICENSE0000644000175000017500000004366112650351107017103 0ustar gregoagregoaThis software is copyright (c) 2015 by Alexis Sukrieh. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2015 by Alexis Sukrieh. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Suite 500, Boston, MA 02110-1335 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2015 by Alexis Sukrieh. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End libdancer2-perl-0.166001+dfsg.orig/MANIFEST0000644000175000017500000002303212657672331017231 0ustar gregoagregoa# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.042. AUTHORS Changes GitGuide.md LICENSE MANIFEST META.json META.yml Makefile.PL lib/Dancer2.pm lib/Dancer2/CLI.pm lib/Dancer2/CLI/Command/gen.pm lib/Dancer2/CLI/Command/version.pm lib/Dancer2/Config.pod lib/Dancer2/Cookbook.pod lib/Dancer2/Core.pm lib/Dancer2/Core/App.pm lib/Dancer2/Core/Cookie.pm lib/Dancer2/Core/DSL.pm lib/Dancer2/Core/Dispatcher.pm lib/Dancer2/Core/Error.pm lib/Dancer2/Core/Factory.pm lib/Dancer2/Core/HTTP.pm lib/Dancer2/Core/Hook.pm lib/Dancer2/Core/MIME.pm lib/Dancer2/Core/Request.pm lib/Dancer2/Core/Request/Upload.pm lib/Dancer2/Core/Response.pm lib/Dancer2/Core/Response/Delayed.pm lib/Dancer2/Core/Role/ConfigReader.pm lib/Dancer2/Core/Role/DSL.pm lib/Dancer2/Core/Role/Engine.pm lib/Dancer2/Core/Role/Handler.pm lib/Dancer2/Core/Role/HasLocation.pm lib/Dancer2/Core/Role/Hookable.pm lib/Dancer2/Core/Role/Logger.pm lib/Dancer2/Core/Role/Serializer.pm lib/Dancer2/Core/Role/SessionFactory.pm lib/Dancer2/Core/Role/SessionFactory/File.pm lib/Dancer2/Core/Role/StandardResponses.pm lib/Dancer2/Core/Role/Template.pm lib/Dancer2/Core/Route.pm lib/Dancer2/Core/Runner.pm lib/Dancer2/Core/Session.pm lib/Dancer2/Core/Time.pm lib/Dancer2/Core/Types.pm lib/Dancer2/FileUtils.pm lib/Dancer2/Handler/AutoPage.pm lib/Dancer2/Handler/File.pm lib/Dancer2/Logger/Capture.pm lib/Dancer2/Logger/Capture/Trap.pm lib/Dancer2/Logger/Console.pm lib/Dancer2/Logger/Diag.pm lib/Dancer2/Logger/File.pm lib/Dancer2/Logger/Note.pm lib/Dancer2/Logger/Null.pm lib/Dancer2/Manual.pod lib/Dancer2/Manual/Deployment.pod lib/Dancer2/Manual/Migration.pod lib/Dancer2/Manual/Testing.pod lib/Dancer2/Plugin.pm lib/Dancer2/Plugins.pod lib/Dancer2/Policy.pod lib/Dancer2/Serializer/Dumper.pm lib/Dancer2/Serializer/JSON.pm lib/Dancer2/Serializer/Mutable.pm lib/Dancer2/Serializer/YAML.pm lib/Dancer2/Session/Simple.pm lib/Dancer2/Session/YAML.pm lib/Dancer2/Template/Implementation/ForkedTiny.pm lib/Dancer2/Template/Simple.pm lib/Dancer2/Template/TemplateToolkit.pm lib/Dancer2/Template/Tiny.pm lib/Dancer2/Test.pm lib/Dancer2/Tutorial.pod script/dancer2 share/skel/.dancer share/skel/MANIFEST.SKIP share/skel/Makefile.PL share/skel/bin/+app.psgi share/skel/config.yml share/skel/cpanfile share/skel/environments/development.yml share/skel/environments/production.yml share/skel/lib/AppFile.pm share/skel/public/+dispatch.cgi share/skel/public/+dispatch.fcgi share/skel/public/404.html share/skel/public/500.html share/skel/public/css/error.css share/skel/public/css/style.css share/skel/public/favicon.ico share/skel/public/images/perldancer-bg.jpg share/skel/public/images/perldancer.jpg share/skel/t/001_base.t share/skel/t/002_index_route.t share/skel/views/index.tt share/skel/views/layouts/main.tt t/00-compile.t t/00-report-prereqs.dd t/00-report-prereqs.t t/app.t t/app/t1/bin/app.psgi t/app/t1/config.yml t/app/t1/lib/App1.pm t/app/t1/lib/Sub/App2.pm t/app/t2/.dancer t/app/t2/config.yml t/app/t2/lib/App3.pm t/app_alone.t t/author-no-tabs.t t/author-pod-syntax.t t/auto_page.t t/caller.t t/charset_server.t t/classes/Dancer2-Core-Factory/new.t t/classes/Dancer2-Core-Hook/new.t t/classes/Dancer2-Core-Request/new.t t/classes/Dancer2-Core-Request/serializers.t t/classes/Dancer2-Core-Response-Delayed/after_hooks.t t/classes/Dancer2-Core-Response-Delayed/new.t t/classes/Dancer2-Core-Response/new_from.t t/classes/Dancer2-Core-Role-Engine/with.t t/classes/Dancer2-Core-Role-Handler/with.t t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/bin/.exists t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/bin/.exists t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/lib/fakescript.pl t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/inner/dir/.exists t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/.dancer t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/fakescript.pl t/classes/Dancer2-Core-Role-HasLocation/with.t t/classes/Dancer2-Core-Role-Serializer/with.t t/classes/Dancer2-Core-Role-StandardResponses/with.t t/classes/Dancer2-Core-Route/base.t t/classes/Dancer2-Core-Route/deprecated_param_keys.t t/classes/Dancer2-Core-Route/match.t t/classes/Dancer2-Core-Runner/environment.t t/classes/Dancer2-Core-Runner/new.t t/classes/Dancer2-Core-Runner/psgi_app.t t/classes/Dancer2-Core/camelize.t t/classes/Dancer2/import-pragmas.t t/classes/Dancer2/import.t t/config.yml t/config/config.yml t/config/environments/failure.yml t/config/environments/merging.yml t/config/environments/production.yml t/config/environments/staging.json t/config_multiapp.t t/config_reader.t t/config_settings.t t/context-in-before.t t/cookie.t t/corpus/pretty/505.tt t/corpus/pretty/relative.tt t/corpus/pretty_public/404.html t/corpus/pretty_public/510.html t/corpus/static/1x1.png t/corpus/static/index.html t/custom_dsl.t t/dancer-test.t t/dancer-test/config.yml t/deserialize.t t/dispatcher.t t/dsl.t t/dsl/any.t t/dsl/app.t t/dsl/content.t t/dsl/delayed.t t/dsl/error_template.t t/dsl/extend.t t/dsl/extend_config/config.yml t/dsl/halt.t t/dsl/halt_with_param.t t/dsl/parameters.t t/dsl/pass.t t/dsl/path.t t/dsl/route_retvals.t t/dsl/send_file.t t/dsl/splat.t t/dsl/to_app.t t/engine.t t/error.t t/factory.t t/file_utils.t t/forward.t t/forward_before_hook.t t/forward_test_tcp.t t/hooks.t t/http_methods.t t/http_status.t t/issues/config.yml t/issues/gh-1013/gh-1013.t t/issues/gh-1013/views/t.tt t/issues/gh-1070.t t/issues/gh-1098.t t/issues/gh-596.t t/issues/gh-634.t t/issues/gh-639/fails/.dancer t/issues/gh-639/fails/config.yml t/issues/gh-639/fails/issue.t t/issues/gh-639/succeeds/.dancer t/issues/gh-639/succeeds/config.yml t/issues/gh-639/succeeds/issue.t t/issues/gh-650/gh-650.t t/issues/gh-650/views/environment_setting.tt t/issues/gh-723.t t/issues/gh-730.t t/issues/gh-762.t t/issues/gh-762/views/404.tt t/issues/gh-794.t t/issues/gh-797.t t/issues/gh-799.t t/issues/gh-811.t t/issues/gh-931.t t/issues/gh-936.t t/issues/gh-936/views/error.tt t/issues/gh-944.t t/issues/memleak/die_in_hooks.t t/lib/App1.pm t/lib/App2.pm t/lib/DancerPlugin.pm t/lib/EmptyPlugin.pm t/lib/Foo.pm t/lib/FooPlugin.pm t/lib/Hookee.pm t/lib/MyDancerDSL.pm t/lib/OnPluginImport.pm t/lib/PluginWithImport.pm t/lib/SubApp1.pm t/lib/SubApp2.pm t/lib/TestApp.pm t/lib/TestPod.pm t/log_die_before_hook.t t/log_levels.t t/logger.t t/logger_console.t t/memory_cycles.t t/mime.t t/multi_apps.t t/multi_apps_forward.t t/multiapp_template_hooks.t t/named_apps.t t/plugin_import.t t/plugin_multiple_apps.t t/plugin_register.t t/plugin_syntax.t t/psgi_app.t t/psgi_app_forward_and_pass.t t/public/file.txt t/redirect.t t/release-distmeta.t t/request.t t/request_make_forward_to.t t/request_upload.t t/response.t t/roles/hook.t t/route-pod-coverage/route-pod-coverage.t t/scope_problems/config.yml t/scope_problems/dispatcher_internal_request.t t/scope_problems/keywords_before_template_hook.t t/scope_problems/session_is_cleared.t t/scope_problems/views/500.tt t/scope_problems/with_return_dies.t t/serializer.t t/serializer_json.t t/serializer_mutable.t t/session_config.t t/session_engines.t t/session_forward.t t/session_hooks.t t/session_in_template.t t/session_lifecycle.t t/session_object.t t/sessions/VZnfBAAAM1tKFkfDZ4IUwyKrWceQJRkE.yml t/sessions/VZnfBAAAM1uzNFM805U0WYIBH6g9O9sP.yml t/sessions/VZnfBAAAM1vX474E7L8-IKj6yGKXydT6.yml t/sessions/VZnjPwAAO6k-BdDf7U1asyu8L3IiwLPH.yml t/sessions/VZnjPwAAO6k9bW5FauLnPe6HtecLdTl7.yml t/sessions/VZnjPwAAO6mvnV4jszDm0R5-aWeczZvi.yml t/sessions/VZnmcwAAQCxW6LW-ZL8Xt8U8jJfvzYQE.yml t/sessions/VZnmcwAAQCzAiy3r3BF_Y9nl17qh9xWZ.yml t/sessions/VZnmcwAAQCzZczgTm1OVACmWHKa_8Ba3.yml t/sessions/Vg04TQAAIh5Z2I-GTU_wKFHO4feGKLE_.yml t/sessions/Vg04TQAAIh5f8_rJkoZU-jF0X0Ju1tUT.yml t/sessions/Vg04TQAAIh5ip4atDSSzR5k8O0kUe8xe.yml t/sessions/Vg04TQAAIh6LD69zbMVWaoqIU23Crkdm.yml t/sessions/Vg04TQAAIh6p0AWJuzbIW1SGm4EYmG3M.yml t/sessions/Vg04TQAAIh7D5x7ePVh0dCf2cIkxpaxw.yml t/sessions/Vg064wAAJ9kOJP85EngBszwmwHbWlNSI.yml t/sessions/Vg064wAAJ9kQ4eZCIrRZYn2MHmDG9gdR.yml t/sessions/Vg064wAAJ9kdprsPF4Sv3csep-q5vNcS.yml t/sessions/Vg064wAAJ9kplKAlXLoTRgcwpA4SHS7p.yml t/sessions/Vg064wAAJ9lUqjejJGWqSsvCik0IMkXR.yml t/sessions/Vg064wAAJ9laQxRh3IZuFLenkVBgIk9I.yml t/shared_engines.t t/template.t t/template_default_tokens.t t/template_ext.t t/template_name.t t/template_simple.t t/template_tiny/01_compile.t t/template_tiny/02_trivial.t t/template_tiny/03_samples.t t/template_tiny/04_compat.t t/template_tiny/05_preparse.t t/template_tiny/samples/01_hello.tt t/template_tiny/samples/01_hello.txt t/template_tiny/samples/01_hello.var t/template_tiny/samples/02_null.tt t/template_tiny/samples/02_null.txt t/template_tiny/samples/02_null.var t/template_tiny/samples/03_chomp.tt t/template_tiny/samples/03_chomp.txt t/template_tiny/samples/03_chomp.var t/template_tiny/samples/04_nested.tt t/template_tiny/samples/04_nested.txt t/template_tiny/samples/04_nested.var t/template_tiny/samples/05_condition.tt t/template_tiny/samples/05_condition.txt t/template_tiny/samples/05_condition.var t/template_tiny/samples/06_object.tt t/template_tiny/samples/06_object.txt t/template_tiny/samples/06_object.var t/template_tiny/samples/07_nesting.tt t/template_tiny/samples/07_nesting.txt t/template_tiny/samples/07_nesting.var t/template_tiny/samples/08_foreach.tt t/template_tiny/samples/08_foreach.txt t/template_tiny/samples/08_foreach.var t/template_tiny/samples/09_trim.tt t/template_tiny/samples/09_trim.txt t/template_tiny/samples/09_trim.var t/time.t t/types.t t/uri_for.t t/vars.t t/views/auto_page.tt t/views/beforetemplate.tt t/views/folder/page.tt t/views/index.tt t/views/layouts/main.tt t/views/session_in_template.tt t/views/template_simple_index.tt t/views/tokens.tt xt/perlcritic.rc xt/perltidy.rc xt/whitespace.t libdancer2-perl-0.166001+dfsg.orig/Changes0000644000175000017500000013375712650351107017377 0ustar gregoagregoa0.166001 2016-01-22 07:54:46+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #1105, #1106, #1108: Autopage + Template Toolkit broke in last release. (Kaitlyn Parkhurst @symkat, Russell Jenkins) 0.166000 2016-01-12 19:01:51+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #1013, #1092: Remove race condition caused by caching available engines. (Sawyer X, Menno Blom, Russell Jenkins) * GH #1089: Exact macthing of route regex comments for tokens/splats. (Sawyer X) * GH #1079, #1082: Allow routes to return '0' as response content, and serializer hooks are called when default response content is to be returned. (Alberto Simões, Russell Jenkins) * GH #1093, 1095: Use a dynamic TT2 INCLUDE_PATH to allow relative views with relative includes; fixing regression introduced by #1037. (Russell Jenkins) * GH #1096, #1097: Return compatibility on Perl 5.8.x! (Peter Mottram - @SysPete) [ DOCUMENTATION ] * GH #1076: Typo in Dancer2::Core::Hook POD. (Jonathan Scott Duff) [ ENHANCEMENTS ] * GH #1074: Add sample session engine config to skeleton app. (Peter Mottram - @SysPete) * GH #1088: Return route objects when defining new routes. (Sawyer X) 0.165000 2015-12-17 09:19:13+01:00 Europe/Amsterdam [ BUG FIXES ] * Revert session_name change, as this would invalidate all existing changes. We will need to rethink this change. (Stefan @racke Hornburg, Sawyer X) 0.164000 2015-12-16 23:42:24+01:00 Europe/Amsterdam [ DOCUMENTATION ] * Update core team members and contributors list. (Russell Jenkins) * GH #1066: Fix typo in Cookbook. (gertvanoss) * Correct typo. It's "query_parameters", not "request_parameters". Thanks to mst for letting me know and making sure I fix it! (Sawyer X) [ BUG FIXES ] * GH #1040: Forward with a post body no longer tries to re-read body filehandle. (Bas Bloemsaat) * GH #1042: Add Diggest::SHA as explicit prequisite for installs on perl < v5.9.3. (Russell Jenkins) * GH #1071, #1070: HTML escape the message in the default error page. (Peter Mottram) * GH #1062, #1063: Command line interface didn't support "-s SKELETON_DIRECTORY" in any order. (Nuno Carvalho) * GH #1052, #1053: Always call before_serializer hook when serializer is set. (Mickey Nasriachi) * GH #1034: Correctly use different session cookie name for Dancer2. (Jason A. Crome) * GH #1060: Remove trailing slashes when providing skeleton directory. (Gabor Szabo) [ ENHANCEMENTS ] * Use Plack 1.0035 to make sure you only have HTTP::Headers::Fast in the Plack::Request object internally. * GH #951 #1037: Dancer2::Template::TemplateToolkit no longer sets TT2 INCLUDE_PATH directive, allowing `views` setting to be non-absolute paths. (Russell Jenkins) * GH #1032 #1043: Add .dancer file to new app scaffolding. (Jason A. Crome) * GH #1045: Small cleanups to Request class. (Russell Jenkins) * GH #1033: strict && warnings in Dancer2::CLI. (Mohammad S Anwar) * GH #1052, #1053: Allow before_serializer hook to change the content using @_. (Mickey Nasriachi) * GH #1060: Ignore .git directory when using an external skeleton directory. (Gabor Szabo) * GH #1060: Support more asset file extensions. (Gabor Szabo) * GH #1072: Add request->is_options(). (Theo van Hoesel) 0.163000 2015-10-15 12:47:57+02:00 Europe/Amsterdam [ DOCUMENTATION ] * GH: #1030: Fix pod references pointing to Dancer package (Mohammad S Anwar, Russell Jenkins) 0.162000_01 2015-10-13 17:05:09+02:00 Europe/Amsterdam (TRIAL RELEASE) [ BUG FIXES ] * GH #996: Fix warning with optional arguments. (Bas Bloemsaat) * GH #1001: Do not trigger an internal error on 404. (Russell Jenkins) * GH #1008,#976: Hack to quiet warning while plugins architecture is being rewritten. (Russell Jenkins) * Use Safe::Isa when calling their functions in the respected eval. (Sawyer X) [ ENHANCEMENTS ] * GH #738, #740, #988: route_parameters, query_parameters, and body_parameters keywords added, providing Hash::MultiValue objects! (Sawyer X) * #941, #999: delayed() keyword now has "on_error" option for controlling errors. (Sawyer X) * dancer2 app now support -s switch to supply an app skeleton (Nuno Carvalho) * "perl_version" token in templates now uses $^V, not $]. (Sawyer X) * GH #966: Remove Dist::Zilla::Plugin::AutoPrereqs. (Vernon) * GH #992: Deprecate creating route named placeholders ":captures" and ":splat". (Sawyer X) * Bump Moo requirement to 2.000000. (Alberto Simões) * GH #1012: Add :nopragmas import flag. (Sawyer X) [ DOCUMENTATION ] * GH #974: Use correct classname. (Sawyer X) * GH #958: Fix manual example with loading additional routes. (Sawyer X) * GH #960: Fix a few links. (Sawyer X) * Document you can install Scope::Upper for greater speed. (Sawyer X) * GH #1000: Correct POD name for Dancer2::Manual::Deployment. (Jason A. Crome) * GH #1017: Fix instructions on running app.psgi. Highlight beginner-friendly application running instructions. (Jason Crome) * GH #920, #1020: Remove deprecated functionality from example plugin. (Jason Crome) * GH #1002: Correct execute_hook() call in plugins documentation. (Jason Crome) * Expand on auto-reloading options using Plack Shotgun loader. (Jason Crome, @girlwithglasses) * GH #1024: Document the need to define static_handler when changing the public_dir option. (Sébastien Deseille) 0.162000 2015-09-06 13:08:05+02:00 Europe/Amsterdam [ BUG FIXES ] * Not exactly bug fix, but now captures() always returns hashref. (Sawyer X) * GH #931: Using params() keyword, route parameters now override body parameters which override query parameters. (Sawyer X) [ ENHANCEMENTS ] * Small speed bump: use eval{} instead of Try::Tiny. (Sawyer X) [ DOCUMENTATION ] * Replace File::Slurp with File::Slurper in tutorial. (Nick Tonkin) 0.161000_01 2015-08-28 15:29:00+02:00 Europe/Amsterdam [ BUG FIXES ] * GH #947, #948: Escape file paths in regex patterns. (A. Sinan Unur) * GH #944: Setting response content in before hook when a serializer is set no longer triggers an error. (Russell Jenkins, Dmitrii Tcyganov) * GH #965: Remove non-existant role from Response::Delayed. (Vernon, Russell Jenkins) * GH #971: Route options matching no longer uses each iterator. (Tina Müller) * GH #959: Custom error template rendering fixed. (Russell Jenkins) * GH #961: Render custom error templates in before hooks. (Russell Jenkins) * GH #978: Tests - fix response regex after html_encode (Vernon) * GH #972: Exceptions thrown by serializers no longer masked. (Russell Jenkins) [ DOCUMENTATION ] * GH #967: Fix upload example. (Alberto Simões) * GH #881: Add cookie timeout example. (Andy Beverley) * GH #963: Document all available template tokens. (Sawyer X) [ ENHANCEMENTS ] * Optimize the s*#t out of basic routing. Faster than Dancer 1 now. (Sawyer X) * Only load HTTP::Server::PSGI when asked to start a development server not under Plack. (Sawyer X, Mickey Nasriachi) * GH #949: Produce cleaner, non-verbose test output (Vernon) * GH #950: Decode characters in param keys (Patrick Zimmermann) * GH #914: Include stack trace on default error page when show_errors is true. (Vernon) * GH #980, #981: halt keyword sets response content if provided, as Dancer 1 does. (Achilles Kars) * GH #909, #957, #983: HTML5 templates in generated apps and default error template (Gabor Szabo, Kadir, Vernon) * GH #972, #719, #969, #644, #647: Streamline serializer helpers. to_json/from_json now faster. (Russell Jenkins) 0.161000 2015-07-08 14:57:16+02:00 Europe/Amsterdam [ BUG FIXES ] * GH #915, #930: Check existence of optional extension headers when behind proxy. (Andy Beverley, Pedro Melo, Russell Jenkins) * GH #926, #940: Set session directory default to $apprdir/session. (Russell Jenkins) * GH #936, #939: Use the error_template configuration on a 404. (Russell Jenkins) * GH #844, #937: Non-hash serialized params do not cause a crash. (Sawyer X) * GH #943: Pass @_ to UNIVERSAL's VERSION so it validates version number. (Sawyer X) * GH #934: Cleanup internals in the old Dispatcher. (Russell Jenkins) [ DOCUMENTATION ] * Sanitize Changes * GH #938: Fix POD link to params keyword. (Ludovic Tolhurst-Cleaver) * GH #935: Provide more details and considerations when using behind_proxy. (Andy Beverley) [ ENHANCEMENT ] * GH #933: use note in tests to produce cleaner non-verbose output (Vernon) * Remove unnecessary dependencies: build chain should be smaller. (Sawyer X) * No need for Module::Build. (Sawyer X) * GH #911: Dancer2 request object is now a subclass of Plack::Request. It's also much faster now. (Sawyer X) 0.160003 2015-06-06 11:09:00+02:00 Europe/Amsterdam [ BUG FIXES ] * GH #921, #922: Plack >= 1.0035. (Russell Jenkins, Alberto Simões) [ ENHANCEMENT ] * #922: Use HTTP::Headers::Fast in request and response objects (Russell Jenkins) 0.160002 2015-06-04 13:03:38+02:00 Europe/Amsterdam [ BUG FIXES ] * GH #920: Sanitize session IDs in file-based sessions. (Russell Jenkins, Andrew Beverley) [ DOCUMENTATION ] * GH #908: Cleanup Dancer references in DBIC section of cookbook (Julien Fiegehenn) * GH #910: Misc spelling and grammar fixes (Gregor Herrmann) * GH #916: Fix test example. (Peter Mottram - @SysPete) * GH #912, #913: Fix documentation on when stacks are printed. (Andrew Solomon) 0.160001 2015-05-14 20:40:10+02:00 Europe/Amsterdam [ BUG FIXES ] * GH #893, #895: Catch config parse errors when Config::Any doesn't throw them. (Russell Jenkins) * GH #899: Minimum YAML version supported is v0.86 (Shlomi Fish) * GH #906: send_file - missing import and fix logic error for streaming by default (Russell Jenkins) [ DOCUMENTATION ] * GH #897: Remove docs for unimplemented 'load' keyword (Fayland Lam) [ ENHANCEMENT ] * GH #894, #898: Add status and headers methods to ::Response::Delayed (Yanick Champoux, Charlie Gonzalez) 0.160000 2015-04-27 00:12:55+02:00 Europe/Amsterdam [ BUG FIXES ] * GH #868: Fix incorrect access name in $error->throw. (cdmalon) * GH #879, #883: Fix version numbering in packaging and tests. (Russell Jenkins) * File serving (send_file) won't call serializer. (Russell Jenkins) * GH #892, #510: Workaround for multiple plugins with hooks. (Russell Jenkins, Alberto Simões) * GH #558: Remove "prefix" inconsistency with possibly missing postfixed forward slash. (Sawyer X) [ DOCUMENTATION ] * GH #816, #874 Document session engine changes in migration documentation. (Chenchen Zhao) * GH #866, #870: Clarify that you cannot forward to a static file, why, and two different ways of accomplishing it without forward. (Sakshee Vijayvargia) * GH #878: Rework example for optional named matching due to operator precedence. (Andrew Solomon) * GH #844: Document Simple session backend is the default. (Sawyer X) [ ENHANCEMENT ] * GH #869: Streaming file serving (send_file). (Russell Jenkins) * GH #793: "prefix" now supports the path definition spec. (Sawyer X) * GH #817, #845: Route spec under a prefix doesn't need to start with a slash (but must without a prefix). (Sawyer X, Russell Jenkins) * GH #871: Use Safe.pm instead of eval with Dancer2::Serializer::Dumper. (David Zurborg) * GH #880: Reduce and cleanup different logging calls in order to handle the stack frames traceback for logging classes. (Russell Jenkins) * GH #857, #875: When failing to render in Template::Toolkit, make the error reflect it's a TT error, not an internal one. (valerycodes) 0.159003 2015-03-23 14:57:15+01:00 Europe/Amsterdam [ BUG FIXES ] * Fixed another memory leak with compiled hooks. (Sawyer X) * Fixed a memory leak with conditionally applied static middleware (Russell Jenkins) [ DOCUMENTATION ] * GH #854, #858: Fix after_template_render hook example. (Adam Weinberger) * GH #861: Improve documentation of 'forward'. (Andy Beverley) 0.159002 2015-03-03 19:21:21+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #856: Memory leak when throwing exception from a hook. (Sawyer X) 0.159001 2015-02-25 15:31:35+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #855: Ensure Dancer2::Test is compatible with Pod::Simple 3.30. (Russell Jenkins) [ DOCUMENTATION ] * Add an example for delayed (async) streaming response. (Sawyer X) * Small link fix. (Sawyer X) 0.159000 2015-02-24 04:51:20+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #762: Delay app cleanup until errors are rendered. (Russell Jenkins) * GH #835: Correct Logic error in Logger if no request exists. (Lennart Hengstmengel) * GH #839: Correct "no_server_tokens" definition in production.yml. (Nikita K) * GH #853, #852: Handle malformed (contentless) cookies. (pants) * GH #840, #842: Ensure session data available to template engines. (Russell Jenkins) * GH #565, #847, #849: Fix HTTP Status template logic and documentation. (Daniel Muey, Russell Jenkins, Dávid Kovács) * GH #843: Add missing attributes to Moo class used in tests. (Graham Knop) [ ENHANCEMENT ] * GH #836: Support delayed (asynchronous) responses! ("Delayed responses" in Dancer2::Manual for more information.) (Sawyer X) * GH #824: Use Plack::MIME by default, MIME::Types as failback if available. (Alberto Simões) * GH #792, #848: Keywords can now use prototypes. (Russell Jenkins, Sawyer X) [ DOCUMENTATION ] * GH #837, #838, #841: Major documentation restructure. (Snigdha Dagar) (Check eb9416e9 and a78e27d7 for more details.) * GH #823: Cleanup Manual and Cookbook docs. (Omar M. Othman) * GH #828: Provide README.mkdn. (Nuno Carvalho) * GH #830: Fix typo in Session::YAML pod. (Vince W) * GH #831,#832: Fix broken link in Session::YAML pod. (Vince W) 0.158000 2015-01-01 18:08:04+01:00 Europe/Amsterdam ** Happy new year! ** [ ENHANCEMENT ] * GH #778: Avoid hard-coded static page location. (Dávid Kovács) * Speed up big uploads significantly. (Rick Myers) * GH #821: Use Import::Into to import pragmas. (Russell Jenkins) * GH #782: Fix utf8 pragma import. (Maxim Vuets) * GH #786: Perlbrew fix. (Dávid Kovács) * GH #622: Refactoring. (James Raspass) [ DOCUMENTATION ] * GH #713: Change order of statements in Cookbook to not imply that D2::P::Ajax::ajax() calls have priority. (Sawyer X) 0.157001 2014-12-21 20:40:13+01:00 Europe/Amsterdam [ ENHANCEMENT ] * GH #814, #815: Rename "app.pl" to "app.psgi". (Sawyer X) 0.157000 2014-12-14 18:23:33+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #799: Set current request earlier so log formats using requests will work. (Sawyer X) * GH #650: Provide default environment to app for templating. (Dávid Kovács, Chi Trinh) * GH #800: Better portability code, for different Windows situations. (Christian Walde) * Less littering of the test directories with session files. (Sawyer X) [ ENHANCEMENT ] * GH #810: strict && warnings in the app.pl. (Sawyer X) * Use to_app keyword in skeleton. (Sawyer X) * GH #801: Under production, server tokens are disabled. (Sawyer X) * GH #588, #779: Remove LWP::UserAgent in favor of HTTP::Tiny. (Dávid Kovács, simbabque, Sawyer X) * Remove all usages of Test::TCP in favor of Plack::Test. (Sawyer X) [ DOCUMENTATION ] * GH #802: Remove indication of warnings configuration option and add explanation in migration document. (Sawyer X) * GH #806: Link in main docs to the migration document. (Gabor Szabo) * GH #807: Update migration document with more session data, changes to app.pl, and Template::Toolkit configuration. (Gabor Szabo) * GH #813: Update migration document with information on encoding and usage of Plack::Request internally. (Gabor Szabo, Sawyer X) 0.156001 2014-12-08 23:03:43+01:00 Europe/Amsterdam [ DOCUMENTATION ] * Documentations suggested serializers aren't consistent. We fixed it so we make sure docs reflect that. (Sawyer X) 0.156000 2014-12-07 18:04:14+01:00 Europe/Amsterdam [ BUG FIXES ] * Do not try to deserialize empty content. (Lennart Hengstmengel, Sawyer X) * Do not call serialization hooks when no serialization took place. (Sawyer X) * Be more cautious on undef output from serializer. (Daniel Böhmer, Sawyer X) [ ENHANCEMENTS ] * Add cpanfile when scaffolding a new app. (Dávid Kovács, Sawyer X) * Response "content" attribute no longer stringifies. This should help reduce warnings, odd debugging problems, etc. (Sawyer X) * DSL "uri_for" no longer returns URI object. Instead just the URI. (Sawyer X) [ DOCUMENTATION ] * GH #777: Fix doc for mentioning public dir. (Dávid Kovács, Sawyer X) * GH #787: Document all environment variables. (Sawyer X) 0.155004 2014-12-04 11:51:23+01:00 Europe/Amsterdam [ BUG FIXES ] * Guard against content length being empty strings. This is really bizarre case but saw it once. (Sawyer X) 0.155003 2014-12-03 22:32:12+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #798: More test fixes on Windows. (A. Sinan Unur) 0.155002 2014-12-02 22:59:32+01:00 Europe/Amsterdam [ BUG FIXES ] * Fix test on Windows. (A. Sinan Unur) 0.155001 2014-11-28 17:42:24+01:00 Europe/Amsterdam [ BUG FIXES ] * Small typo in test. (Dávid Kovács) 0.155000 2014-11-28 01:18:39+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #773, #775: AutoPage handler no longer renders layouts. (Dávid Kovács, Sawyer X) * GH #770: Prevent crazy race condition between the logger engine and other engines. This means engines now call "log_cb" to log. (Sawyer X) * App now has default name to caller package. (Sawyer X) * Serializers will not try to serialize empty content. (Sawyer X) * Lots of cleanups in Core::Request in favor of Plack::Request. (Sawyer X) [ ENHANCEMENTS ] * Layouts directory can be configured using 'layout_dir'. (Sawyer X) * GH #648, #760: Logger format now supports 'h', 'u', 'U', 'h', 'i'. They are documented but weren't really available. (Lennart Hengstmengel) * Serializers having errors will not fail if there is no logger. (Sawyer X) * Create a request object with a single argument of $env, like Plack::Request. (Sawyer X) [ DOCUMENTATION ] * Remove documented hack for static content because we use the middleware now anyway. (Sawyer X) * Document further the difference between splat and megasplat. (Dávid Kovács) 0.154000 2014-11-17 15:36:31+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #744: Serialize anything, not just references. (Sawyer X) * GH #744: Serialize regardless of content_type of serializer. (Sawyer X) * GH #764: Catch template render errors. (Russell Jenkins, Steven Humphrey) * Calling uri_for(undef) doesn't crash. (Sawyer X) * GH #732: Correct name for 403 (Forbidden, not Unauthorized). (Theo van Hoesel, Sawyer X, Mickey Nasriachi, Omar M. Othman) * GH #753: Syntax of parameterized types. (Russell Jenkins) * GH #734: Failing tests on Windows. (Russell Jenkins, Sawyer X) [ ENHANCEMENTS ] * GH #664, #684, #715: Handler::File replaced for static files with Plack::Middleware::Static, allowing files to be served *before* routes. This means hooks do not apply to static files anymore! (Russell Jenkins, DavsX) * Engines now have "logger" attribute to log errors. It sends the Dancer2::Logger:: object, if one exists. (Sawyer X) * Serializers do not need to implement "loaded" method. (Sawyer X) * GH #733: In core: response_xxx removed in favor of generic standard_response. (Sawyer X, Mickey Nasriachi, Omar M. Othman) * GH #514, #642, #729: Allow mixing named params, splat, and megasplat. (Russell Jenkins, Johan Spade, Dávid Kovács) * GH #596: no_server_tokens works, as well as DANCER_NO_SERVER_TOKENS. (Omar M. Othman, Sawyer X, Mickey Nasriachi) * GH #639: Validate engine types in configuration. (Sawyer X, Omar M. Othman, Mickey Nasriachi, Russell Jenkins) * GH #663, #741: Remove "accept_type" attribute and other references. (Mickey Nasriachi, Theo van Hoesel) * GH #748: Provide forwarded_host, forwarded_protocol. (Sawyer X) * GH #748: Do not provide a default env, require env for a request. (Sawyer X) * GH #742: Update test skeleton to use to_app. (Dávid Kovács) * GH #636: Use Plack::Test in more tests. (Dávid Kovács) [ DOCUMENTATION ] * GH #656: Dancer2::Manual::Testing as a guide for testing Dancer2 applications. (Sawyer X) * Improved documentation of route matching. (Russell Jenkins) * Migration document update relating to enhancements. (Sawyer X, Mickey Nasriachi) * GH #731: Document changes in session. (racke, Sawyer X, Mickey Nasriachi, Omar M. Othman) * Document "id" attribute in Request object. (Sawyer X) * Correct Cookbook examples on command line scripts. (Sawyer X) 0.153002 2014-10-30 09:23:52+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #734: More failing tests. (Sawyer X) 0.153001 2014-10-27 12:39:54+01:00 Europe/Amsterdam [ BUG FIXES ] * GH #734: Failing tests on Windows. (Sawyer X) [ DOCUMENTATION ] * GH #724: Plack::Test example in Dancer2::Test. (Jakob Voss) 0.153000 2014-10-23 23:45:36+02:00 Europe/Amsterdam [ BUG FIXES ] * GH #634, #687: Fix file logger defaults. (Russell Jenkins, Dávid Kovács, Sawyer X) * GH #730: Make App use app-level config for behind_proxy. (Sawyer X) * GH #727: Disable regex metachars when calculating app location in tests (Gregor Herrmann) * GH #681, #682, #712: Clear session engine within destroy_session. (DavX, Russell Jenkins) * Ignore :tests in importing, don't suggest :script. (Sawyer X) [ ENHANCEMENT ] * Internal: Move the implementation of send_file from DSL to App. (Russell Jenkins) [ DOCUMENTATION ] * GH #728: Typos in Policy document. (Olaf Alders, Sawyer X) 0.152000 2014-10-14 04:30:59+02:00 Europe/Amsterdam [ BUG FIXES ] * GH #723: Redispatched requests lose data. (Sawyer X) [ ENHANCEMENT ] * Provide 'content' keyword to set the response content. (Sawyer x) * GH #616, #155, #615: Session engines are now lazy! (Russell Jenkins) * Dancer2 response objects can be created from arrays or from Plack::Response objects. (Sawyer X) * GH #718: Clean up App's Template engine. (Russell Jenkins) * Adding class-based tests. (Sawyer X) [ DOCUMENTATION ] * Add a policy document under Dancer2::Policy. (Sawyer X) * Document log_format instead of logger_format. (Sawyer X) 0.151000 2014-10-08 21:49:06+02:00 Europe/Amsterdam [ ENHANCEMENT ] * Apps are now a proper independent PSGI application. Forwarding and passing requests between apps will still work if you use the 'Dancer2->psgi_app' method without providing a class, but it might still be phased out in the future. (Sawyer X) [ DOCUMENTATION ] * Migration document! (Snigdha Dagar) * GH #667: Fix typo in cookbook pod. (Lindsey Beesley) * GH #649, #670: Document core logger. (simbabque) * GH #689: Git guide markdown fixes. (Paul Cochrane) * GH #690, #691, #694, #696, #698, #699, #700, #702, #703, #704, #705, #706, #707, #708, #710: Doc cleanups. (Paul Cochrane) * GH #688: Improve testing documentation. (Paul Chochrane) * GH #692: Document serving static files using Plack::Middleware::Static. (Dávid Kovács @DavsX) * GH #695: Correct Dancer2::Logger::Capture, add test example. (Dávid Kovács @DavsX) * GH #716: Correct document on proxy procotol forwarding in Apache. (Andy Beverley) 0.150000 2014-08-17 01:35:16CEST+0200 Europe/Amsterdam [ DOCUMENTATION ] * GH #657: Update multi-app example in cookbook to include route merging. (Bas Bloemsaat) * GH #643: Improve session factory docs by mentioning Dancer2::Config. (Andy Jack) [ BUG FIXES ] * Postponed hooks are no longer sent to all Apps. (Sawyer X, Mickey Nasriachi) * 404 File Not Found Application reworked to stay up to date with postponed hooks merging in multiple apps. (Russell Jenkins) * GH #610, #662: Removed two circular references memory leaks! (Russell Jenkins) * GH #633: Log an error when a hook dies. (DavsX) [ ENHANCEMENT ] * Allow settings apps in the psgi_app() call by name or regex. (Sawyer X) * GH #651: silly typo in clearer method name (DavsX). 0.149000_02 2014-08-10 13:50:39CEST+0200 Europe/Amsterdam [ ENHANCEMENT ] * GH #641: Adding a shim layer to prevent available hooks (and thus plugins) from breaking. * Each App can now define its own configuration. The Runner's application-specific configure has been untangled. (Russell @veryrusty Jenkins, Sawyer X, Mickey Nasriachi) * Multiple Dancer App support. You can now create a App-specific PSGI application using MyApp->psgi_app. (Russell @veryrusty Jenkins, Sawyer X, Mickey Nasriachi) * Add routes and hooks to an existing app on import. (Russell @veryrusty Jenkins, Stevan Humphrey, Stefan racke Hornburg, Jean Stebens, Chunzi, Sawyer X, Mickey Nasriachi) * Allow DSL class to be specified in configuration file. (Stevan Humphrey) * forward() now returns a new request which is then just runs the dispatching loop again. (Sawyer X, Mickey Nasriachi) [ BUG FIXES ] * GH #336: Set log level correctly. (Andrew Solomon, Pedro Bruno) * GH #627, #607: Remove potential context issues with returning undef explicitly. (Javier Rojas) * GH #646: Fix whitespacing for tests. (DavsX) 0.149000_01 2014-07-23 21:31:21CEST+0200 Europe/Amsterdam *************************** NOTICE *************************** * This very is a major upgrade * * We untangled the context, DSL implementation a bit * * Please check your code, including your plugins, thoroughly * * Thank you * [ ENHANCEMENTS ] * GH #589: Removing Dancer2::Core::Context global context variable. Finally in. (Sawyer X, Mickey Nasriachi, Russell @veryrusty Jenkins) [ BUG FIXES ] * GH #606, #605: Fix for setting public directory. (Ivan Kocienski, Russell Jenkins, Stefan @racke Hornburg) * GH #618, #620: Fix jQuery link generated by CLI skeleton. (Michał Wojciechowski) * GH #589: Major memory leak fix by removal of Dancer2::Core::Context. [ ENHANCEMENTS ] * GH #620: Bump jQuery to 1.11.1. (Michał Wojciechowski) 0.143000 2014-07-05 21:39:28CEST+0200 Europe/Amsterdam [ BUG FIXES ] * GH #538, #539: Coerce propogated exceptions to strings within Error object. (Steven Humphrey) * GH #531: Generate valid HTML when show_errors is true from Error objects. (Steven Humphrey) * GH #603: Update skeleton test to use Plack::Test. (Sawyer X) [ ENHANCEMENTS ] * Provide psgi_app in top-level Dancer.pm to make it easier to change it. (Sawyer X) 0.142000 2014-06-24 15:16:42CEST+0200 Europe/Amsterdam [ BUG FIXES ] * GH #550, #555: Allow the content type to be set when using send_file as per the documentation. (Russell Jenkins, Steven Humphrey) [ ENHANCEMENTS ] * GH #512, #520, #602: Pass all settings into JSON serializer engine. (Jakob Voss, Russell Jenkins) * GH #532: Serialize runtime errors such as those produced by die if a serializer exists. (Steven Humphrey) 0.141000 2014-06-08 22:27:03CEST+0200 Europe/Amsterdam * No functional changes. 0.140900_01 2014-06-07 23:32:56IDT+0300 Asia/Jerusalem [ BUG FIXES ] * GH #447: Setting the apphandler now triggers the Dancer Runner configuration change, which works. (Sawyer X) * GH #578: Remove the default engine configurations. (Sawyer X) * GH #567: Check for proper module names in loading engines. Might help with taint mode. (Sawyer X) * GH #585, #595: Return 405 Method Not Allowed instead of 500. (Omar M. Othman) * GH #570, #579: Ensure keywords pass, send_error and send_file exit immediatly when executed. (Russell Jenkins) [ ENHANCEMENTS ] * GH #587: Serializer::Mutable alive! (Pedro Bruno) [ DOCUMENTATION ] * Fix doc for params(). Ported from Dancer#1025 (Stefan Hornburg) 0.140001 2014-05-01 10:49:25CEST+0200 Europe/Amsterdam [ BUG FIXES ] * Bugfix for extracting multiple cookies within a request. (Cymon, Russell Jenkins) * Require minimum version of Plack to make sure we can add the Head middleware. Not exactly a bug, but not a feature. (Sawyer X) [ DOCUMENTATION ] * Correct reference to HTTP::Server::Simple::PSGI. (Russell Jenkins) 0.140000 2014-04-28 23:14:31CEST+0200 Europe/Amsterdam [ ENHANCEMENTS ] * Replace Config role with better ConfigReader role. (Mickey Nasriachi, Stefan Hornburg, Sawyer X) * Move App-related attributes (engines) to App instead of config role. (Mickey Nasriachi, Stefan Hornburg, Sawyer X) * Untangle Runner-Server (removing Server entirely). (Mickey Nasriachi, Stefan Hornburg, Sawyer X) * Replace HTTP::Server::Simple::PSGI with HTTP::Server::PSGI. (Mickey Nasriachi, Stefan Hornburg, Sawyer X) * GH #527: Build request cookie objects from request headers, not env. (Russell Jenkins) * GH #569: Transform cookie using the HTTP_COOKIE header, per PSGI spec. (Russell Jenkins) * GH #559, #544: Use Plack middleware for HEAD request content removal. (Russell Jenkins) * GH #513, #483: Deserialize body content for DELETE requests. (Russell Jenkins, Yanick Champoux, Sawyer X) 0.13 2014-04-13 19:19:44CEST+0200 Europe/Amsterdam [ ENHANCEMENTS ] * GH #562: Change YAML::Any to YAML (Steven Humphrey, Russell Jenkins). [ BUG FIXES ] * GH #524: Double encoding for YAML sessions. * GH #557: Switch to using YAML::Old. * GH #548: Deserializer test failure. 0.12 2014-04-07 22:42:12 Europe/Amsterdam [ ENHANCEMENTS ] * GH#518: Bump jQuery to 1.10.2 (Grzegorz Rożniecki). * GH#535: Support OPTIONS and PATCH requests in Server::Standalone. (Russell Jenkins) * GH#553: Dancer2 CLI: specify directory to write app skeleton (Jean Stebens) * GH#543: Additional HTTP Methods for Ajax plugin (Jean Stebens). [ DOCUMENTATION ] * RT#91428: POD encoding set to UTF-8 in main .pm (Gregor Herrmann). * GH#517: Miscellaneous documentation fixes (Cesare Gargano). * GH#518: "Getting started" demo page fixes (Grzegorz Rożniecki). * GH#522: s/PerlHandler/PerlResponseHandler/ in Apache2 sample configuration (Grzegorz Rożniecki) * GH#521: Remove duplicated POD and clean up list details (Shlomi Fish) * GH#526: Cleanup POD formating and code snippets in manual. (Grzegorz Rożniecki) [ BUG FIXES ] * GH#528,529: Force PSGI server in dispatch scripts for CGI or fcgi deployments (Erik Smit, Alberto Simões) * GH#550,GH#551: Update all headers in Handler::File (Sawyer X, Stefan @racke Hornburg) * GH#540: Fix hook execution when default scalar was used in hook code. (baynes, Russell Jenkins) * GH#552: Rework test suite to use Plack::Test (Sawyer X, Stefan @racke Hornburg) * GH#560: Return value of hooks do not alter response content. (Jean Stebens) 0.11 2013-12-15 14:19:22 Europe/Amsterdam [ ENHANCEMENTS ] * GH#481: Don't pollute @INC automatically when Dancer2 is imported, each runner is now responsible of including the local ./lib dir if needed. * GH#469, 418: Dancer2::Plugin provides a ':no_dsl' flag for modern Plugins (Pedro Melo) * GH#485: Keywords 'redirect' and 'forward' exit immediatly when executed in a route/hook. New dependency on Return::MultiLevel (Russell Jenkins). * GH#495: Use accessor and predicates instead of direct access. Addresses GH#493 too. (Russell Jenkins) * GH#502,GH#472: Rework halt to use with_return from Return::MultiLevel. (Russell Jenkins) * GH#479,GH#480,GH#508: Pass parameters to params() in the DSL. (Slava Goltser, unickuity, Russell Jenkins) * GH#505: Fix empty HTTP_REFERER in Dancer::Core::Request (Menno Blom). * GH#503: Multiple reverse proxy support (Menno Blom). * GH#371,GH#506: CLI tool rewrite (using App::Cmd, supports plugins, etc.). (Ivan Kruglov, Samit Badle, Sawyer X) * GH#498: Add some missing items in MANIFEST.SKIP (Gabor Szabo, Sawyer X). [ DOCUMENTATION ] * GH#489: Remove link to Dancer2::Deployment pod which does not exist (Sweet-kid) * GH#511: s/Deflator/Deflater/; (Cesare Gargano) * GH#491: Updated config paths for template_toolkit in cookbook. (Mark A. Stratman) * GH#494: Update session config details (Dancer2::Config), namespace fixup in Dancer2::Core::cookie. (Russell Jenkins) * GH#470: Fix Plack::Builder mount usage (Pedro Melo). * GH#507: Fix plenty of typos (David Steinbrunner). * GH#477: Document problem with Plack Shotgun on Windows (Ahmad M. Zawawi). * GH#504: Add link to Dancer2::Plugin::Sixpack (Menno Blom). * GH#490: Document Dancer2 should be FatPackable (Sawyer X). * GH#452: Make a complete authors section, clean it up (Pau Amma). * More fixes to main documentation (Pau Amma). 0.10 2013-09-28 15:26:41 Europe/Paris [ DOCUMENTATION ] * GH#431: Miscellaneous documentation fixes (Gideon D'souza) * Small POD corrections (Ashvini V) [ ENHANCEMENTS ] * GH#482: Show the startup banner when the worker starts by default (Alexis Sukrieh). * GH#481: Include local lib dir in @INC by defaults (Alexis Sukrieh). * GH#423: Remove ':tests' from Dancer.pm import (Alberto Simões). * GH#422: Get rid of core_debug method (Alberto Simões). * GH#421: Support Plugin::Ajax content_type (Russell Jenkins). * GH#428: Make default errors CSS path relocatable (Russell Jenkins). * GH#427, GH#443: Replace global warnings with lexical (Russell Jenkins). * GH#374: Don't create an app from app.psgi (Alberto Simões). * Cleanup Core::Request, Core::Request::Upload (Mickey Nasriachi). * GH#445: Test Template::Simple (Alexis Sukrieh, Russell Jenkins). * GH#449: Test Session hooks (Gideon D'souza) * GH#434,440: Imutable attributes (Mickey Nasriachi). * GH#435: Allow send_error to serialize error (Russell Jenkins). * Add more tests to session id rw (Pedro Melo). * Whitespace cleanup (Ivan Bessarabov). [ BUG FIXES ] * GH#424,425: Fix logger tests for different timezones, and close logfile before deleting it: Windows dixit. (Gideon D'souza, Russell Jenkins) 0.09 2013-09-02 00:12:58 Asia/Jerusalem [ ENHANCEMENTS ] * Rewite DSL keyword engine (Mickey Nasriachi) * Require minimum Role::Tiny 1.003000 (Alberto Simões) * GH#382: Move Request attributes to params, and fix serializers behavior (Russell Jenkins) * GH#406: Replace Dancer2::ModuleLoader with Class::Load (Alberto Simões, Sawyer X) * GH#329: Remove 'load_app' DSL keyword. Remove reference to 'load' as well. (Sawyer X) * GH#412: Autopages are now called properly with correct MIME. (Alberto Simões) [ DOCUMENTATION ] * GH#390: minor cookbook documentation fixes (Russell Jenkins) * GH#392: remove support to auto_reload and suggest alternative in Dancer2::Cookbook (Ahmad M. Zawawi) * GH#397,407: Miscellaneous documentation fixes (Andrew Solomon) * Documentation cleanups (Alex Beamish) [ BUG FIXES ] * When compiling route regex object with prefix, add the closing anchor (Mickey Nasriachi) * GH#386: honor log level defined in config file (Alberto Simões) * GH#396,409: Miscellaneous bug fixes (Russell Jenkins) * GH#403: Fix forward behavior (Russell Jenkins) 0.08 2013-08-18 15:22:45 Asia/Jerusalem [ ENHANCEMENTS ] * GH#352: Define content_type as a property for serializers. (Franck Cuny) * Cleanup duplicate HTTP status code between Core::Error and Core::HTTP (Russel Jenkins) * GH#363: Move core methods to Dancer2::Core (Alberto Simões) * GH#362: Serializers documentation and test cleanup. (Franck Cuny) * Refactoring of the engine method. (Franck Cuny) * Misc. code cleanup. (Russel Jenkins) * GH#280: Remove the unused ':syntax' importing tag (Sawyer X) * Display startup info only if environment is "development" (Franck Cuny) * Move postponed_hooks to server from runner (Sawyer X) * Provide easier access to global runner (Sawyer X) * Bunch of code cleanups which also includes speed boost (Sawyer X) * More immutability in the runner class and config role (Sawyer X) [ BUG FIXES ] * GH#85, GH#354: Fix autopages, especially in subdirs (Stefan Hornburg, Alberto Simões) * GH#365: Fix serializer settings (Steven Humphrey) * GH#333: callerstack for logger was too short (Alberto Simões) * GH#369: Move request deserialization from Dispatcher to Content & Request (Russell Jenkins) [ DOCUMENTATION ] * GH#192: Documentation the current usage of middlewares using Plack::Builder (Sawyer X) * GH#195, GH#197, GH#372: Multiple apps with Plack::Builder (Sawyer X) * GH#348: Documentation of Role::Logger (Franck Cuny) * GH#350: Move part of README.md to GitGuide.md (Franck Cuny) * GH#353: Documentation of Role::Serializer (Alberto Simões, Franck Cuny) * Misc. minor documentation tweak (Alberto Simões, Franck Cuny) 0.07 2013-08-04 01:14:59 Asia/Jerusalem [ ENHANCEMENTS ] * GH#344, GH#284: Now forward() calls preserve sessions (cym0n, Alberto Simões) * Separation of engines from triggers and configuration (Sawyer X, Franck Cuny) * GH#347: Remove old compatibility option 'log_path' (Franck Cuny) * GH#156, GH#250, GH#349: Remove unused module (Alberto Simões, mokko) * GH#331: Hook cleanups and documentation. (Franck Cuny) * GH#335: Serializing cleanup. (Franck Cuny) * GH#332: Clean up multiple definitions of core_debug (Franck Cuny) * GH#338: Clean up route builder (Mickey Nasriachi) * Clean up of the dzil configuration (Alberto Simões) [ BUG FIXES ] * GH#334: Fix for GH#86, to display custom 500 page/template on internal server errors (Russell Jenkins) * GH#346: Fix tests on 5.8.9 (Albert Simões) [ DOCUMENTATION ] * GH#345: Documentation reorganization (Alberto Simões, Franck Cuny) 0.06 2013-07-30 (Sawyer X) [ ENHANCEMENTS ] * Clean up of the dzil configuration (Alberto Simões,Franck Cuny, Russel Jenkins) * GH#327: Add support for 'info' log level (Russell Jenkins) * Remove 'for_versions' usage from tests (Alberto Simões) [ BUG FIXES ] * GH#326, GH#232: don't end up with empty views and layout (Franck Cuny) * GH#325: don't die or complain when two routes have the same path (Franck Cuny) * GH#320: fix plugin_setting deprecation warning (David Golden) [ DOCUMENTATION ] * POD cleanup (Sawyer X, Franck Cuny) 0.05 2013-07-20 18:51:53 Europe/Paris [ DEPRECATION ] * Dancer2::Plugin drops support for Dancer 1 (issue #207) a DEPRECATION notice is issued when a plugin uses the old syntax (Alexis Sukrieh, Mokko, David Golden) * Drop support for 'use Dancer2 :moose' (Franck Cuny) [ ENHANCEMENTS ] * Add support for HTTP_X_FORWARDED_PROTO (Yanick Champoux) * Don't inflate custom types (Graham Knop) * Encode UTF8 params in Dancer2::Test (Vincent Bachelier) * Make Dancer2::Core::Request more lazy (Franck Cuny) * Don't use rootdir for app location (David Golden) * Improve File logger (David Golden) * Drop body when status is 1x or [23]04 (Franck Cuny) * Add support for HTTP_X_FORWARDED_PROTO (Yanick Champoux) * Prevent duplicate routes from being created (Franck Cuny) * Add support for route options (Franck Cuny) * Add support for prefix with route defined with regex (Franck Cuny) * Methods to return path of views and layout in the Template role (Franck Cuny, Yanick Champoux). * GH#31, GH#221: Config merging support (Russell Jenkins) [ BUG FIXES ] * GH#272: test function 'route_doesnt_exist' was not handling test comment properly. (Jeff Boes, Yanick Champoux) * GH#228: handle UTF-8 correctly in JSON serializer (Steven Humphrey) * GH#270: handle correctly serializer's options (Keith Broughton) * GH#274: `dancer -v' returns the correct version (Dinis Rebolo) * GH#286: for HEAD request, drop response's body (Franck Cuny) * GH#293: fix defaults tests for a newly generated app (Franck Cuny) * GH#216: check 'show_errors' when returning an internal error (Franck Cuny) * GH#246: Add serialization of log messages (Stefan Hornburg) * GH#268: Dancer2::Core::Response->status accepts stringy HTTP codes (Franck Cuny) * GH#308: Add support for ENV{DANCER_CONFDIR} and ENV{DANCER_ENVDIR} (Franck Cuny) * GH#210: Don't print startup banner if startup_info is set to 0 (Maurice Mengel, Franck Cuny) * plugin_setting does not trigger a DEPRECATION warning anymore (Report by Alberto Simões, fix by Alexis Sukrieh) * GH#251: Support for on-the-fly changes of layouts/views (Franck Cuny) * GH#302: Avoid double encoding in Handler::File (Russell Jenkins) [ DOCUMENTATION ] * Lots of documentation cleanup (Mokko, David Precious) * Documenting Dancer2::Handler::AutoPage (Sabiha Imran, Sawyer X) * Documenting Dancer2::Core::Dispatcher (Babitha Balachandran) * Documenting Dancer2::Manual::DSL (David Precious, Franck Cuny) * Various typo (Shlomi Fish, Colin Kuskie, Stefan Hornburg, Rick Yakubowski) * Documenting some internals (Colin Kuskie) * Documenting Dancer2::Core::MIME (Babitha B.) * Documenting Manual::Developers (Maurice Mengel) * Documenting Dancer2::Core::Response (Colin Kuskie) 0.04 - 2013-04-22 (Alexis Sukrieh) [ BUG FIXES ] * Fix "Internal Sever Error" when sending a file with send_file (Dinis Rebolo) * Allow the setting of the 'views' directory, like stated in documentation (Alexander Karelas) [ ENHANCEMENTS ] * Implement Dancer2::Test file uploads (Steven Humphrey) * Give Dancer2::Test the ability to handle multiselect inputs (Steven Humphrey) * Make Cookie objects stringify to their value. (David Precious) * New routines for Dancer2::Test to check pod coverage in apps routes (Dinis Rebolo) * New script dancer2 to bootstrap an application (mokko) * Fix tests when running under Windows environments (Russell Jenkins) * Serializing modify the response's content type (Yanick Champoux) [ DOCUMENTATION ] * Make introduction more fluid in Dancer2's POD. (mokko) [ PACKAGING ] * Remove prereq Digest::SHA (mokko) * Dancer::P::Bcrypt recomends Dancer::P::Passphrase (Blabos de Blebe) 0.03 - 2013-03-07 (Alexis Sukrieh) [ ENHANCEMENTS ] * Don't create a session when just checking if a value exists (David Golden) * Only flush sessions if they are dirty (David Golden) * Allow the default template file extension to be changed. (David Precious) * Add on_plugin_import function to Dancer2::Plugin (David Golden) (Fix for issue #284) [BUG FIXES] * Dancer2::ModuleLoader now use Module::Runtime at its core (issue #166, Yanick Champoux) [ DOCUMENTATION ] * changed <% to [% in documentations (Alexander Karelas) * Improve Dancer2::Plugin documentation (David Golden) 0.02 - 2013-02-24 (Alexis Sukrieh) [ DOCUMENTATION ] * No more "TODO" tokens in the documentations * More documentation for Core classes (Alexis Sukrieh) [ ENHANCEMENTS ] * Removed the "api_version" code that is useless and was breaking some tests. (Alexis Sukrieh) 0.01 [ ENHANCEMENTS ] * Dancer::Test takes a hash instead of an array for better backward compatibility with Dancer 1. (Celogeek) * Session revamp: better decoupling between Session and SessionFactory, support for session destruction and session values deletion. Everythin regarding session settings is now configurable. (David Golden). * Add route_exists and route_doesnt_exist in Dancer::Test (Mokko) * session cookie duration can be expressed with human readable strings * instead of numeric values (Alexis Sukrieh, issue #157). [ BUG FIXES ] * The engine configuration is now passed down to Dancer::Template::Implementation::ForkedTiny (Damien Krotkine). * Dancer App lookup now try to detect the dir "bin" and "lib" or ".dancer" file. (Celogeek) * Issues #125 and #126 Support for configuration bits for session objects, possible to change the cookie name instead of the hard-coded value 'dancer.session'. (Reported by David Golden, fixed by Alexis Sukrieh). [ DOCUMENTATION ] * Add more POD in Dancer::Test (Mokko) 1.9999_02 * Fix tests for previous release, tests cannot assume we're under Dancer 2 when the version is 1.9999 (Alexis Sukrieh) 1.9999_01 * First DEVELEOPER release of Dancer 2 complete rewrite of Dancer with a Moo backend. (Alexis Sukrieh, David Precious, Damien Krotkine, SawyerX, Yanick Champoux and others, plus Matt S. Trout as a reviewer). libdancer2-perl-0.166001+dfsg.orig/AUTHORS0000644000175000017500000000013112650351107017127 0ustar gregoagregoaSee perldoc Dancer2.pm, section AUTHORS, for a list of core developers and contributors. libdancer2-perl-0.166001+dfsg.orig/xt/0000775000175000017500000000000012650351107016521 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/xt/perlcritic.rc0000644000175000017500000000464112650351107021212 0ustar gregoagregoa# nice output, to easily see the POD of the policy verbose = [%p] %m at %f line %l, near '%r'\n # severity of 3 is a good start (1 is very strict, 5 very tolerant) severity = 3 # we want to use // without //ms [-RegularExpressions::RequireDotMatchAnything] [-RegularExpressions::RequireLineBoundaryMatching] [-RegularExpressions::RequireExtendedFormatting] minimum_regex_length_to_complain_about = 5 [-RegularExpressions::ProhibitComplexRegexes] # we don't want these POD rules [-Documentation::RequirePodSections] # We don't care about POD links [-Documentation::RequirePodLinksIncludeText] # we use $@ and $! [-Variables::ProhibitPunctuationVars] # We want to be able to use Carp::Verbose in our tests scripts, so # we add Carp to the whitelist [Variables::ProhibitPackageVars] packages = Data::Dumper File::Find FindBin Log::Log4perl Carp [-ValuesAndExpressions::ProhibitEmptyQuotes] # I really don't think q{/} is more readable than '/'... [-ValuesAndExpressions::ProhibitNoisyQuotes] # Perl::Critic recommends Readonly, but this IS BAD! # we use Const::Fast instead, but this policy keeps poping up. [-ValuesAndExpressions::ProhibitMagicNumbers] # we want to be able to build DSLs [-Modules::ProhibitAutomaticExportation] # We only want the main module to provide $VERSION [-Modules::RequireVersionVar] # we want to be able to define short getters [-Subroutines::RequireFinalReturn] # we cant do @_ mesures with that one [-Subroutines::RequireArgUnpacking] # name is a common used name for methods # but forbidden by this policy ... [-Subroutines::ProhibitBuiltinHomonyms] # some old libs use many args, we don't want to block that for now [-Subroutines::ProhibitManyArgs] # we allo protected subs [-Subroutines::ProhibitUnusedPrivateSubroutines] # We're not under CVS! :) [-Miscellanea::RequireRcsKeywords] [TestingAndDebugging::ProhibitNoStrict] allow = refs [TestingAndDebugging::ProhibitNoWarnings] allow = redefine prototype [TestingAndDebugging::RequireUseStrict] equivalent_modules = strictures Moo Moo::Role [TestingAndDebugging::RequireUseWarnings] equivalent_modules = strictures Moo Moo::Role # we use postifx controls [-ControlStructures::ProhibitPostfixControls] [-ControlStructures::ProhibitCascadingIfElse] # We want to use croak everywhere instead of die [ErrorHandling::RequireCarping] # allow backtick if capture result [InputOutput::ProhibitBacktickOperators] only_in_void_context = 1 [-Variables::ProhibitAugmentedAssignmentInDeclaration] libdancer2-perl-0.166001+dfsg.orig/xt/perltidy.rc0000644000175000017500000000224212650351107020701 0ustar gregoagregoa-l=79 # Max line width is 79 cols -i=4 # Indent level is 4 cols -ci=4 # Continuation indent is 4 cols -se # Errors to STDERR -vt=2 # Maximal vertical tightness -cti=0 # No extra indentation for closing brackets -pt=1 # Medium parenthesis tightness -bt=1 # Medium brace tightness -sbt=1 # Medium square bracket tightness -bbt=1 # Medium block brace tightness -nsfs # No space before semicolons -nolq # Don't outdent long quoted strings --break-at-old-comma-breakpoints -wbb="% + - * / x != == >= <= =~ < > | & **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=" # Break before all operators # extras/overrides/deviations from PBP --maximum-line-length=79 # be less generous --warning-output # Show warnings --maximum-consecutive-blank-lines=2 # default is 1 --nohanging-side-comments # troublesome for commented out code -isbc # block comments may only be indented if they have some space characters before the # -ci=2 # Continuation indent is 2 cols # we use version control, so just rewrite the file # -b # -- should not be active for dzil plugin ## for the up-tight folk :) #-pt=2 # High parenthesis tightness #-bt=2 # High brace tightness #-sbt=2 # High square bracket tightness libdancer2-perl-0.166001+dfsg.orig/xt/whitespace.t0000644000175000017500000000031212650351107021034 0ustar gregoagregoause Test::Whitespaces { dirs => [qw( lib script t tools xt )], ignore => [ qr{t/sessions/}, qr{t/template_tiny/samples}, ], }; libdancer2-perl-0.166001+dfsg.orig/t/0000775000175000017500000000000012650351107016331 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/session_in_template.t0000644000175000017500000000411212650351107022556 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; use HTTP::Cookies; { package TestApp; use Dancer2; get '/' => sub { template 'session_in_template' }; get '/set_session/*' => sub { my ($name) = splat; session name => $name; template 'session_in_template'; }; get '/destroy_session' => sub { # Need to call the 'session' keyword, so app->setup_session # is called and the session attribute in the engines is populated my $name = session 'name'; # Destroying the session should remove the session object from # all engines. app->destroy_session; template 'session_in_template'; }; setting( engines => { session => { 'Simple' => { session_dir => 't/sessions' } } } ); setting( session => 'Simple' ); } my $app = TestApp->to_app; is( ref $app, 'CODE', 'Got app' ); my $test = Plack::Test->create($app); my $jar = HTTP::Cookies->new(); my $base = 'http://localhost'; { my $res = $test->request( GET "$base/" ); ok $res->is_success, 'Successful request'; is $res->content, "session.name \n"; $jar->extract_cookies($res); } { my @requests = ( GET("$base/set_session/test_name"), GET("$base/") ); for my $req ( @requests ) { $jar->add_cookie_header($req); my $res = $test->request($req); ok $res->is_success, 'Successful request'; is $res->content, "session.name test_name\n"; $jar->extract_cookies($res); } } { my $request = GET "$base/"; $jar->add_cookie_header($request); my $res = $test->request($request); ok $res->is_success, 'Successful request'; is $res->content, "session.name test_name\n"; $jar->extract_cookies($res); } { my $request = GET "$base/destroy_session"; $jar->add_cookie_header($request); my $res = $test->request($request); ok $res->is_success, 'Successful request'; is $res->content, "session.name \n"; $jar->extract_cookies($res); } done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/config_settings.t0000644000175000017500000000132212650351107021677 0ustar gregoagregoause strict; use warnings; use Test::More; use Dancer2; # testing default values is( setting('port'), '3000', "default value for 'port' is OK" ); is( setting('content_type'), 'text/html', "default value for 'content_type' is OK" ); #should we test for all default values? # testing new settings ok( setting( 'foo' => '42' ), 'setting a new value' ); is( setting('foo'), 42, 'new value has been set' ); # test the alias 'set' ok( set( bar => 43 ), 'setting bar with set' ); is( setting('bar'), 43, 'new value has been set' ); #multiple values ok( setting( 'foo' => 43, bar => 44 ), 'set multiple values' ); ok( setting('foo') == 43 && setting('bar') == 44, 'set multiple values successful' ); done_testing; libdancer2-perl-0.166001+dfsg.orig/t/auto_page.t0000644000175000017500000000344312650351107020464 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; { package AutoPageTest; use Dancer2; set auto_page => 1; set views => 't/views'; set layout => 'main'; } my @engines = ('tiny'); eval {require Template; Template->import(); push @engines, 'template_toolkit';}; for my $tt_engine ( @engines ) { # Change template engine and run tests AutoPageTest::set( template => $tt_engine ); subtest "autopage with template $tt_engine" => \&run_tests; } sub run_tests { my $test = Plack::Test->create( AutoPageTest->to_app ); { my $r = $test->request( GET '/auto_page' ); is( $r->code, 200, 'Autopage found the page' ); like( $r->content, qr/---\nHey! This is Auto Page working/, '...with proper content', ); } { my $r = $test->request( GET '/folder/page' ); is( $r->code, 200, 'Autopage found the page under a folder' ); like( $r->content, qr/---\nPage under folder/, '...with proper content', ); } { my $r = $test->request( GET '/non_existent_page' ); is( $r->code, 404, 'Autopage doesnt try to render nonexistent pages' ); } { my $r = $test->request( GET '/layouts/main'); is( $r->code, 404, 'Layouts are not served' ); } { my $r = $test->request( GET '/file.txt' ); is( $r->code, 200, 'found file on public with autopage' ); is( $r->content, "this is a public file\n", '[GET /file.txt] Correct content', ); like( $r->headers->content_type, qr{text/plain}, 'public served file as correct mime', ); } } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/custom_dsl.t0000644000175000017500000000105012650351107020664 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Plack::Test; use HTTP::Request::Common; use FindBin qw($Bin); use lib "$Bin/lib"; use Dancer2 dsl => 'MyDancerDSL'; envoie '/' => sub { request->method; }; prend '/' => sub { proto { ::ok('in proto') }; # no sub! request->method; }; my $test = Plack::Test->create( __PACKAGE__->to_app ); is( $test->request( GET '/' )->content, 'GET', '[GET /] Correct content' ); is( $test->request( POST '/' )->content, 'POST', '[POST /] Correct content' ); done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/views/0000775000175000017500000000000012650351107017466 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/views/index.tt0000644000175000017500000000020112650351107021135 0ustar gregoagregoa[index] var = [% var %] before_layout_render = [% before_layout_render %] before_template_render = [% before_template_render %] libdancer2-perl-0.166001+dfsg.orig/t/views/auto_page.tt0000644000175000017500000000004012650351107021773 0ustar gregoagregoaHey! This is Auto Page working. libdancer2-perl-0.166001+dfsg.orig/t/views/layouts/0000775000175000017500000000000012650351107021166 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/views/layouts/main.tt0000644000175000017500000000016112650351107022457 0ustar gregoagregoalayout top var = [% var %] before_layout_render = [% before_layout_render %] --- [% content %] --- layout bottom libdancer2-perl-0.166001+dfsg.orig/t/views/folder/0000775000175000017500000000000012650351107020741 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/views/folder/page.tt0000644000175000017500000000002312650351107022217 0ustar gregoagregoaPage under folder. libdancer2-perl-0.166001+dfsg.orig/t/views/tokens.tt0000644000175000017500000000027312650351107021342 0ustar gregoagregoaperl_version: [% perl_version %] dancer_version: [% dancer_version %] settings.foo: [% settings.foo %] params.foo: [% params.foo %] session.foo [% session.foo %] vars.foo: [% vars.foo %] libdancer2-perl-0.166001+dfsg.orig/t/views/session_in_template.tt0000644000175000017500000000004012650351107024073 0ustar gregoagregoasession.name [% session.name %] libdancer2-perl-0.166001+dfsg.orig/t/views/template_simple_index.tt0000644000175000017500000000015712650351107024413 0ustar gregoagregoathis is var1="<% var1 %>" and var2=<% var2 %> another line <% foo%> <%bar %> <%baz%> <% var1 %>/<% var1 %> libdancer2-perl-0.166001+dfsg.orig/t/views/beforetemplate.tt0000644000175000017500000000005312650351107023031 0ustar gregoagregoaApp is [% myname %], again, it is [% it %] libdancer2-perl-0.166001+dfsg.orig/t/app.t0000644000175000017500000001222112650351107017272 0ustar gregoagregoause strict; use warnings; use Test::More; use Test::Fatal; use Dancer2; use Dancer2::Core::App; use Dancer2::Core::Dispatcher; use Dancer2::Core::Hook; use Dancer2::FileUtils; use File::Spec; # our app/dispatcher object my $app = Dancer2::Core::App->new( name => 'main', ); $app->setting( show_errors => 1 ); # enable show errors my $dispatcher = Dancer2::Core::Dispatcher->new( apps => [$app] ); # first basic tests isa_ok $app, 'Dancer2::Core::App'; # some routes to play with my @routes = ( { method => 'get', regexp => '/', code => sub {'/'}, }, { method => 'get', regexp => '/blog', code => sub {'/blog'}, }, ); # testing with and without prefixes for my $p ( '/', '/mywebsite' ) { for my $r (@routes) { $app->prefix($p); $app->add_route(%$r); } } is $app->environment, 'development'; my $routes_regexps = $app->routes_regexps_for('get'); is( scalar(@$routes_regexps), 4, "route regexps are OK" ); for my $path ( '/', '/blog', '/mywebsite/', '/mywebsite/blog', ) { my $env = { REQUEST_METHOD => 'GET', PATH_INFO => $path }; my $expected = { '/' => '/', '/blog' => '/blog', '/mywebsite/' => '/', '/mywebsite/blog' => '/blog', }; my $resp = $dispatcher->dispatch($env); is $resp->[0], 200, 'got a 200'; is $resp->[2][0], $expected->{$path}, 'got expected route'; } note "testing lexical prefixes"; # clear the prefix in $app (and by the way, makes sure it works when prefix is # undef). $app->prefix(undef); # nested prefixes bitches! $app->lexical_prefix( '/foo' => sub { $app->add_route( method => 'get', regexp => '/', code => sub {'/foo/'} ); $app->add_route( method => 'get', regexp => '/second', code => sub {'/foo/second'} ); $app->lexical_prefix( '/bar' => sub { $app->add_route( method => 'get', regexp => '/', code => sub {'/foo/bar'} ); $app->add_route( method => 'get', regexp => '/second', code => sub {'/foo/bar/second'} ); } ); }, ); # to make sure the lexical prefix did not crash anything $app->add_route( method => 'get', regexp => '/root', code => sub {'/root'} ); # make sure a meaningless lexical prefix is ignored $app->lexical_prefix( '/' => sub { $app->add_route( method => 'get', regexp => '/somewhere', code => sub {'/somewhere'}, ); } ); for my $path ( '/foo/', '/foo/second', '/foo/bar/second', '/root', '/somewhere' ) { my $env = { REQUEST_METHOD => 'GET', PATH_INFO => $path, }; my $resp = $dispatcher->dispatch($env); is $resp->[0], 200, 'got a 200'; is $resp->[2][0], $path, 'got expected route'; } note "test a failure in the callback of a lexical prefix"; like( exception { $app->lexical_prefix( '/test' => sub { Failure->game_over() } ); }, qr{Unable to run the callback for prefix '/test': Can't locate object method "game_over" via package "Failure"}, "caught an exception in the lexical prefix callback", ); $app->add_hook( Dancer2::Core::Hook->new( name => 'before', code => sub {1}, ) ); $app->add_hook( Dancer2::Core::Hook->new( name => 'before', code => sub { Foo->failure; }, ) ); $app->compile_hooks; my $env = { REQUEST_METHOD => 'GET', PATH_INFO => '/', }; like( $dispatcher->dispatch($env)->[2][0], qr/Exception caught in 'core.app.before_request' filter: Hook error: Can't locate object method "failure"/, 'before filter nonexistent method failure', ); $app->replace_hook( 'core.app.before_request', [ sub {1} ] ); $app->compile_hooks; $env = { REQUEST_METHOD => 'GET', PATH_INFO => '/', }; # test duplicate routes when the path is a regex $app = Dancer2::Core::App->new( name => 'main' ); my $regexp_route = { method => 'get', 'regexp' => qr!/(\d+)!, code => sub {1} }; $app->add_route(%$regexp_route); # try to get an invalid engine eval {$app->engine('foo')}; like( $@, qr/^Engine 'foo' is not supported/, "Engine 'foo' does not exist", ); my $tmpl_engine = $app->engine('template'); ok $tmpl_engine, "Template engine is defined"; ok !$app->has_serializer_engine, "Serializer engine does not exist"; is_deeply( $app->_get_config_for_engine('NonExistent'), {}, 'Empty configuration for nonexistent engine', ); # TODO: not such an intelligent check, this one... # set configuration for an engine $app->config->{'engines'}{'template'}{'Tiny'}{'hello'} = 'world'; is_deeply( $app->_get_config_for_engine( template => 'Tiny', $app->config ), { hello => 'world' }, '_get_config_for_engine can find the right configuration', ); is( File::Spec->canonpath( $app->caller ), File::Spec->catfile(t => 'app.t'), 'Correct caller for app', ); done_testing; libdancer2-perl-0.166001+dfsg.orig/t/hooks.t0000644000175000017500000001404012650351107017636 0ustar gregoagregoause strict; use warnings; use Test::More; use File::Spec; use Plack::Test; use HTTP::Request::Common; use Class::Load 'try_load_class'; use Capture::Tiny 0.12 'capture_stderr'; use JSON; try_load_class('Template') or plan skip_all => 'Template::Toolkit not present'; my $tests_flags = {}; { package App::WithSerializer; use Dancer2; set serializer => 'JSON'; my @hooks = qw( before_request after_request before_serializer after_serializer ); for my $hook (@hooks) { hook $hook => sub { $tests_flags->{$hook} ||= 0; $tests_flags->{$hook}++; }; } get '/' => sub { +{ "ok" => 1 } }; hook 'before_serializer' => sub { my ($data) = @_; # don't shift, want to alias.. if ( ref $data eq 'ARRAY' ) { push( @{$data}, ( added_in_hook => 1 ) ); } elsif ( ref $data eq 'HASH' ) { $data->{'added_in_hook'} = 1; } else { $_[0] = +{ 'added_in_hook' => 1 }; } }; get '/forward' => sub { Test::More::note 'About to forward!'; forward '/' }; get '/redirect' => sub { redirect '/' }; get '/json' => sub { +[ foo => 42 ] }; get '/nothing' => sub { return }; } { package App::WithFile; use Dancer2; my @hooks = qw< before_file_render after_file_render >; for my $hook (@hooks) { hook $hook => sub { $tests_flags->{$hook} ||= 0; $tests_flags->{$hook}++; }; } get '/send_file' => sub { send_file( File::Spec->rel2abs(__FILE__), system_path => 1 ); }; } { package App::WithTemplate; use Dancer2; set template => 'tiny'; my @hooks = qw( before_template_render after_template_render ); for my $hook (@hooks) { hook $hook => sub { $tests_flags->{$hook} ||= 0; $tests_flags->{$hook}++; }; } get '/template' => sub { template \"PLOP"; }; } { package App::WithIntercept; use Dancer2; get '/intercepted' => sub {'not intercepted'}; hook before => sub { response->content('halted by before'); halt; }; } { package App::WithError; use Dancer2; my @hooks = qw( on_route_exception ); for my $hook (@hooks) { hook $hook => sub { $tests_flags->{$hook} ||= 0; $tests_flags->{$hook}++; }; } get '/route_exception' => sub {die 'this is a route exception'}; hook after => sub { # GH#540 - ensure setting default scalar does not # interfere with hook execution (aliasing) $_ = 42; }; hook on_route_exception => sub { my ($app, $error) = @_; ::is ref($app), 'Dancer2::Core::App'; ::like $error, qr/this is a route exception/; }; hook init_error => sub { my ($error) = @_; ::is ref($error), 'Dancer2::Core::Error'; }; hook before_error => sub { my ($error) = @_; ::is ref($error), 'Dancer2::Core::Error'; }; hook after_error => sub { my ($response) = @_; ::is ref($response), 'Dancer2::Core::Response'; ::ok !$response->is_halted; ::like $response->content, qr/Internal Server Error/; }; } subtest 'Request hooks' => sub { my $test = Plack::Test->create( App::WithSerializer->to_app ); $test->request( GET '/' ); is( $tests_flags->{before_request}, 1, "before_request was called" ); is( $tests_flags->{after_request}, 1, "after_request was called" ); is( $tests_flags->{before_serializer}, 1, "before_serializer was called" ); is( $tests_flags->{after_serializer}, 1, "after_serializer was called" ); is( $tests_flags->{before_file_render}, undef, "before_file_render undef" ); note 'after hook called once per request'; # Get current value of the 'after_request' tests flag. my $current = $tests_flags->{after_request}; $test->request( GET '/redirect' ); is( $tests_flags->{after_request}, ++$current, "after_request called after redirect", ); note 'Serializer hooks'; $test->request( GET '/forward' ); is( $tests_flags->{after_request}, ++$current, "after_request called only once after forward", ); my $res = $test->request( GET '/json' ); is( $res->content, '["foo",42,"added_in_hook",1]', 'Response serialized' ); is( $tests_flags->{before_serializer}, 4, 'before_serializer was called' ); is( $tests_flags->{after_serializer}, 4, 'after_serializer was called' ); is( $tests_flags->{before_file_render}, undef, "before_file_render undef" ); $res = $test->request( GET '/nothing' ); is( $res->content, '{"added_in_hook":1}', 'Before hook modified content' ); is( $tests_flags->{before_serializer}, 5, 'before_serializer was called with no content' ); is( $tests_flags->{after_serializer}, 5, 'after_serializer was called after content changes in hook' ); }; subtest 'file render hooks' => sub { my $test = Plack::Test->create( App::WithFile->to_app ); $test->request( GET '/send_file' ); is( $tests_flags->{before_file_render}, 1, "before_file_render was called" ); is( $tests_flags->{after_file_render}, 1, "after_file_render was called" ); }; subtest 'template render hook' => sub { my $test = Plack::Test->create( App::WithTemplate->to_app ); $test->request( GET '/template' ); is( $tests_flags->{before_template_render}, 1, "before_template_render was called", ); is( $tests_flags->{after_template_render}, 1, "after_template_render was called", ); }; subtest 'before can halt' => sub { my $test = Plack::Test->create( App::WithIntercept->to_app ); my $resp = $test->request( GET '/intercepted' ); is( $resp->content, 'halted by before' ); }; subtest 'route_exception' => sub { my $test = Plack::Test->create( App::WithError->to_app ); capture_stderr { $test->request( GET '/route_exception' ) }; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/release-distmeta.t0000644000175000017500000000043012650351107021741 0ustar gregoagregoa#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } # This file was automatically generated by Dist::Zilla::Plugin::MetaTests. use Test::CPAN::Meta; meta_yaml_ok(); libdancer2-perl-0.166001+dfsg.orig/t/serializer_json.t0000644000175000017500000000313412650351107021717 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; use Dancer2::Serializer::JSON; # config { package MyApp; use Dancer2; our $entity; set engines => { serializer => { JSON => { pretty => 1, } } }; set serializer => 'JSON'; get '/serialize' => sub { return $entity; }; } my @tests = ( { entity => { a => 1, b => 2, }, options => { pretty => 1 }, name => "basic hash", }, { entity => { c => [ { d => 3, e => { f => 4, g => 'word', } } ], h => 6 }, options => { pretty => 1 }, name => "nested", }, { entity => { data => "\x{2620}" x 10 }, options => { pretty => 1, utf8 => 1 }, name => "utf8", } ); my $app = MyApp->to_app; for my $test (@tests) { my $expected = JSON::to_json( $test->{entity}, $test->{options} ); # Helpers pass options my $actual = Dancer2::Serializer::JSON::to_json( $test->{entity}, $test->{options} ); is( $actual, $expected, "to_json: $test->{name}" ); # Options from config my $serializer = Dancer2::Serializer::JSON->new(config => $test->{options}); my $output = $serializer->serialize( $test->{entity} ); is( $output, $expected, "serialize: $test->{name}" ); $MyApp::entity = $test->{entity}; test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/serialize' ); is($res->content, $expected, "serialized content in response: $test->{name}"); }; } done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/author-no-tabs.t0000644000175000017500000002614712650351107021371 0ustar gregoagregoa BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.09 use Test::More 0.88; use Test::NoTabs; my @files = ( 'lib/Dancer2.pm', 'lib/Dancer2/CLI.pm', 'lib/Dancer2/CLI/Command/gen.pm', 'lib/Dancer2/CLI/Command/version.pm', 'lib/Dancer2/Config.pod', 'lib/Dancer2/Cookbook.pod', 'lib/Dancer2/Core.pm', 'lib/Dancer2/Core/App.pm', 'lib/Dancer2/Core/Cookie.pm', 'lib/Dancer2/Core/DSL.pm', 'lib/Dancer2/Core/Dispatcher.pm', 'lib/Dancer2/Core/Error.pm', 'lib/Dancer2/Core/Factory.pm', 'lib/Dancer2/Core/HTTP.pm', 'lib/Dancer2/Core/Hook.pm', 'lib/Dancer2/Core/MIME.pm', 'lib/Dancer2/Core/Request.pm', 'lib/Dancer2/Core/Request/Upload.pm', 'lib/Dancer2/Core/Response.pm', 'lib/Dancer2/Core/Response/Delayed.pm', 'lib/Dancer2/Core/Role/ConfigReader.pm', 'lib/Dancer2/Core/Role/DSL.pm', 'lib/Dancer2/Core/Role/Engine.pm', 'lib/Dancer2/Core/Role/Handler.pm', 'lib/Dancer2/Core/Role/HasLocation.pm', 'lib/Dancer2/Core/Role/Hookable.pm', 'lib/Dancer2/Core/Role/Logger.pm', 'lib/Dancer2/Core/Role/Serializer.pm', 'lib/Dancer2/Core/Role/SessionFactory.pm', 'lib/Dancer2/Core/Role/SessionFactory/File.pm', 'lib/Dancer2/Core/Role/StandardResponses.pm', 'lib/Dancer2/Core/Role/Template.pm', 'lib/Dancer2/Core/Route.pm', 'lib/Dancer2/Core/Runner.pm', 'lib/Dancer2/Core/Session.pm', 'lib/Dancer2/Core/Time.pm', 'lib/Dancer2/Core/Types.pm', 'lib/Dancer2/FileUtils.pm', 'lib/Dancer2/Handler/AutoPage.pm', 'lib/Dancer2/Handler/File.pm', 'lib/Dancer2/Logger/Capture.pm', 'lib/Dancer2/Logger/Capture/Trap.pm', 'lib/Dancer2/Logger/Console.pm', 'lib/Dancer2/Logger/Diag.pm', 'lib/Dancer2/Logger/File.pm', 'lib/Dancer2/Logger/Note.pm', 'lib/Dancer2/Logger/Null.pm', 'lib/Dancer2/Manual.pod', 'lib/Dancer2/Manual/Deployment.pod', 'lib/Dancer2/Manual/Migration.pod', 'lib/Dancer2/Manual/Testing.pod', 'lib/Dancer2/Plugin.pm', 'lib/Dancer2/Plugins.pod', 'lib/Dancer2/Policy.pod', 'lib/Dancer2/Serializer/Dumper.pm', 'lib/Dancer2/Serializer/JSON.pm', 'lib/Dancer2/Serializer/Mutable.pm', 'lib/Dancer2/Serializer/YAML.pm', 'lib/Dancer2/Session/Simple.pm', 'lib/Dancer2/Session/YAML.pm', 'lib/Dancer2/Template/Implementation/ForkedTiny.pm', 'lib/Dancer2/Template/Simple.pm', 'lib/Dancer2/Template/TemplateToolkit.pm', 'lib/Dancer2/Template/Tiny.pm', 'lib/Dancer2/Test.pm', 'lib/Dancer2/Tutorial.pod', 'script/dancer2', 't/00-compile.t', 't/00-report-prereqs.dd', 't/00-report-prereqs.t', 't/app.t', 't/app/t1/bin/app.psgi', 't/app/t1/config.yml', 't/app/t1/lib/App1.pm', 't/app/t1/lib/Sub/App2.pm', 't/app/t2/.dancer', 't/app/t2/config.yml', 't/app/t2/lib/App3.pm', 't/app_alone.t', 't/auto_page.t', 't/caller.t', 't/charset_server.t', 't/classes/Dancer2-Core-Factory/new.t', 't/classes/Dancer2-Core-Hook/new.t', 't/classes/Dancer2-Core-Request/new.t', 't/classes/Dancer2-Core-Request/serializers.t', 't/classes/Dancer2-Core-Response-Delayed/after_hooks.t', 't/classes/Dancer2-Core-Response-Delayed/new.t', 't/classes/Dancer2-Core-Response/new_from.t', 't/classes/Dancer2-Core-Role-Engine/with.t', 't/classes/Dancer2-Core-Role-Handler/with.t', 't/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/bin/.exists', 't/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/bin/.exists', 't/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/lib/fakescript.pl', 't/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/inner/dir/.exists', 't/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/.dancer', 't/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/fakescript.pl', 't/classes/Dancer2-Core-Role-HasLocation/with.t', 't/classes/Dancer2-Core-Role-Serializer/with.t', 't/classes/Dancer2-Core-Role-StandardResponses/with.t', 't/classes/Dancer2-Core-Route/base.t', 't/classes/Dancer2-Core-Route/deprecated_param_keys.t', 't/classes/Dancer2-Core-Route/match.t', 't/classes/Dancer2-Core-Runner/environment.t', 't/classes/Dancer2-Core-Runner/new.t', 't/classes/Dancer2-Core-Runner/psgi_app.t', 't/classes/Dancer2-Core/camelize.t', 't/classes/Dancer2/import-pragmas.t', 't/classes/Dancer2/import.t', 't/config.yml', 't/config/config.yml', 't/config/environments/failure.yml', 't/config/environments/merging.yml', 't/config/environments/production.yml', 't/config/environments/staging.json', 't/config_multiapp.t', 't/config_reader.t', 't/config_settings.t', 't/context-in-before.t', 't/cookie.t', 't/corpus/pretty/505.tt', 't/corpus/pretty/relative.tt', 't/corpus/pretty_public/404.html', 't/corpus/pretty_public/510.html', 't/corpus/static/1x1.png', 't/corpus/static/index.html', 't/custom_dsl.t', 't/dancer-test.t', 't/dancer-test/config.yml', 't/deserialize.t', 't/dispatcher.t', 't/dsl.t', 't/dsl/any.t', 't/dsl/app.t', 't/dsl/content.t', 't/dsl/delayed.t', 't/dsl/error_template.t', 't/dsl/extend.t', 't/dsl/extend_config/config.yml', 't/dsl/halt.t', 't/dsl/halt_with_param.t', 't/dsl/parameters.t', 't/dsl/pass.t', 't/dsl/path.t', 't/dsl/route_retvals.t', 't/dsl/send_file.t', 't/dsl/splat.t', 't/dsl/to_app.t', 't/engine.t', 't/error.t', 't/factory.t', 't/file_utils.t', 't/forward.t', 't/forward_before_hook.t', 't/forward_test_tcp.t', 't/hooks.t', 't/http_methods.t', 't/http_status.t', 't/issues/config.yml', 't/issues/gh-1013/gh-1013.t', 't/issues/gh-1013/views/t.tt', 't/issues/gh-1070.t', 't/issues/gh-1098.t', 't/issues/gh-596.t', 't/issues/gh-634.t', 't/issues/gh-639/fails/.dancer', 't/issues/gh-639/fails/config.yml', 't/issues/gh-639/fails/issue.t', 't/issues/gh-639/succeeds/.dancer', 't/issues/gh-639/succeeds/config.yml', 't/issues/gh-639/succeeds/issue.t', 't/issues/gh-650/gh-650.t', 't/issues/gh-650/views/environment_setting.tt', 't/issues/gh-723.t', 't/issues/gh-730.t', 't/issues/gh-762.t', 't/issues/gh-762/views/404.tt', 't/issues/gh-794.t', 't/issues/gh-797.t', 't/issues/gh-799.t', 't/issues/gh-811.t', 't/issues/gh-931.t', 't/issues/gh-936.t', 't/issues/gh-936/views/error.tt', 't/issues/gh-944.t', 't/issues/memleak/die_in_hooks.t', 't/lib/App1.pm', 't/lib/App2.pm', 't/lib/DancerPlugin.pm', 't/lib/EmptyPlugin.pm', 't/lib/Foo.pm', 't/lib/FooPlugin.pm', 't/lib/Hookee.pm', 't/lib/MyDancerDSL.pm', 't/lib/OnPluginImport.pm', 't/lib/PluginWithImport.pm', 't/lib/SubApp1.pm', 't/lib/SubApp2.pm', 't/lib/TestApp.pm', 't/lib/TestPod.pm', 't/log_die_before_hook.t', 't/log_levels.t', 't/logger.t', 't/logger_console.t', 't/memory_cycles.t', 't/mime.t', 't/multi_apps.t', 't/multi_apps_forward.t', 't/multiapp_template_hooks.t', 't/named_apps.t', 't/plugin_import.t', 't/plugin_multiple_apps.t', 't/plugin_register.t', 't/plugin_syntax.t', 't/psgi_app.t', 't/psgi_app_forward_and_pass.t', 't/public/file.txt', 't/redirect.t', 't/request.t', 't/request_make_forward_to.t', 't/request_upload.t', 't/response.t', 't/roles/hook.t', 't/route-pod-coverage/route-pod-coverage.t', 't/scope_problems/config.yml', 't/scope_problems/dispatcher_internal_request.t', 't/scope_problems/keywords_before_template_hook.t', 't/scope_problems/session_is_cleared.t', 't/scope_problems/views/500.tt', 't/scope_problems/with_return_dies.t', 't/serializer.t', 't/serializer_json.t', 't/serializer_mutable.t', 't/session_config.t', 't/session_engines.t', 't/session_forward.t', 't/session_hooks.t', 't/session_in_template.t', 't/session_lifecycle.t', 't/session_object.t', 't/sessions/VZnfBAAAM1tKFkfDZ4IUwyKrWceQJRkE.yml', 't/sessions/VZnfBAAAM1uzNFM805U0WYIBH6g9O9sP.yml', 't/sessions/VZnfBAAAM1vX474E7L8-IKj6yGKXydT6.yml', 't/sessions/VZnjPwAAO6k-BdDf7U1asyu8L3IiwLPH.yml', 't/sessions/VZnjPwAAO6k9bW5FauLnPe6HtecLdTl7.yml', 't/sessions/VZnjPwAAO6mvnV4jszDm0R5-aWeczZvi.yml', 't/sessions/VZnmcwAAQCxW6LW-ZL8Xt8U8jJfvzYQE.yml', 't/sessions/VZnmcwAAQCzAiy3r3BF_Y9nl17qh9xWZ.yml', 't/sessions/VZnmcwAAQCzZczgTm1OVACmWHKa_8Ba3.yml', 't/sessions/Vg04TQAAIh5Z2I-GTU_wKFHO4feGKLE_.yml', 't/sessions/Vg04TQAAIh5f8_rJkoZU-jF0X0Ju1tUT.yml', 't/sessions/Vg04TQAAIh5ip4atDSSzR5k8O0kUe8xe.yml', 't/sessions/Vg04TQAAIh6LD69zbMVWaoqIU23Crkdm.yml', 't/sessions/Vg04TQAAIh6p0AWJuzbIW1SGm4EYmG3M.yml', 't/sessions/Vg04TQAAIh7D5x7ePVh0dCf2cIkxpaxw.yml', 't/sessions/Vg064wAAJ9kOJP85EngBszwmwHbWlNSI.yml', 't/sessions/Vg064wAAJ9kQ4eZCIrRZYn2MHmDG9gdR.yml', 't/sessions/Vg064wAAJ9kdprsPF4Sv3csep-q5vNcS.yml', 't/sessions/Vg064wAAJ9kplKAlXLoTRgcwpA4SHS7p.yml', 't/sessions/Vg064wAAJ9lUqjejJGWqSsvCik0IMkXR.yml', 't/sessions/Vg064wAAJ9laQxRh3IZuFLenkVBgIk9I.yml', 't/shared_engines.t', 't/template.t', 't/template_default_tokens.t', 't/template_ext.t', 't/template_name.t', 't/template_simple.t', 't/template_tiny/01_compile.t', 't/template_tiny/02_trivial.t', 't/template_tiny/03_samples.t', 't/template_tiny/04_compat.t', 't/template_tiny/05_preparse.t', 't/template_tiny/samples/01_hello.tt', 't/template_tiny/samples/01_hello.txt', 't/template_tiny/samples/01_hello.var', 't/template_tiny/samples/02_null.tt', 't/template_tiny/samples/02_null.txt', 't/template_tiny/samples/02_null.var', 't/template_tiny/samples/03_chomp.tt', 't/template_tiny/samples/03_chomp.txt', 't/template_tiny/samples/03_chomp.var', 't/template_tiny/samples/04_nested.tt', 't/template_tiny/samples/04_nested.txt', 't/template_tiny/samples/04_nested.var', 't/template_tiny/samples/05_condition.tt', 't/template_tiny/samples/05_condition.txt', 't/template_tiny/samples/05_condition.var', 't/template_tiny/samples/06_object.tt', 't/template_tiny/samples/06_object.txt', 't/template_tiny/samples/06_object.var', 't/template_tiny/samples/07_nesting.tt', 't/template_tiny/samples/07_nesting.txt', 't/template_tiny/samples/07_nesting.var', 't/template_tiny/samples/08_foreach.tt', 't/template_tiny/samples/08_foreach.txt', 't/template_tiny/samples/08_foreach.var', 't/template_tiny/samples/09_trim.tt', 't/template_tiny/samples/09_trim.txt', 't/template_tiny/samples/09_trim.var', 't/time.t', 't/types.t', 't/uri_for.t', 't/vars.t', 't/views/auto_page.tt', 't/views/beforetemplate.tt', 't/views/folder/page.tt', 't/views/index.tt', 't/views/layouts/main.tt', 't/views/session_in_template.tt', 't/views/template_simple_index.tt', 't/views/tokens.tt' ); notabs_ok($_) foreach @files; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/template.t0000644000175000017500000000746512650351107020343 0ustar gregoagregoause strict; use warnings; use Test::More; use Dancer2::Core::Hook; use Plack::Test; use HTTP::Request::Common; use File::Spec; use File::Basename 'dirname'; eval { require Template; Template->import(); 1 } or plan skip_all => 'Template::Toolkit probably missing.'; use_ok('Dancer2::Template::TemplateToolkit'); my $views = File::Spec->rel2abs( File::Spec->catfile( dirname(__FILE__), 'views' ) ); my $tt = Dancer2::Template::TemplateToolkit->new( views => $views, layout => 'main.tt', ); isa_ok $tt, 'Dancer2::Template::TemplateToolkit'; ok $tt->does('Dancer2::Core::Role::Template'); $tt->add_hook( Dancer2::Core::Hook->new( name => 'engine.template.before_render', code => sub { my $tokens = shift; $tokens->{before_template_render} = 1; }, ) ); $tt->add_hook( Dancer2::Core::Hook->new( name => 'engine.template.before_layout_render', code => sub { my $tokens = shift; my $content = shift; $tokens->{before_layout_render} = 1; $$content .= "\ncontent added in before_layout_render"; }, ) ); $tt->add_hook( Dancer2::Core::Hook->new( name => 'engine.template.after_layout_render', code => sub { my $content = shift; $$content .= "\ncontent added in after_layout_render"; }, ) ); $tt->add_hook( Dancer2::Core::Hook->new( name => 'engine.template.after_render', code => sub { my $content = shift; $$content .= 'content added in after_template_render'; }, ) ); { package Bar; use Dancer2; # set template engine for first app Dancer2->runner->apps->[0]->set_template_engine($tt); get '/' => sub { template index => { var => 42 } }; } subtest 'template hooks' => sub { my $space = " "; my $result = "layout top var = 42 before_layout_render = 1 --- [index] var = 42 before_layout_render =$space before_template_render = 1 content added in after_template_render content added in before_layout_render --- layout bottom content added in after_layout_render"; my $test = Plack::Test->create( Bar->to_app ); my $res = $test->request( GET '/' ); is $res->content, $result, '[GET /] Correct content with template hooks'; }; { package Foo; use Dancer2; set views => '/this/is/our/path'; get '/default_views' => sub { set 'views' }; get '/set_views_via_settings' => sub { set views => '/other/path' }; get '/get_views_via_settings' => sub { set 'views' }; } subtest "modify views - absolute paths" => sub { my $test = Plack::Test->create( Foo->to_app ); is( $test->request( GET '/default_views' )->content, '/this/is/our/path', '[GET /default_views] Correct content', ); # trigger a test via a route $test->request( GET '/set_views_via_settings' ); is( $test->request( GET '/get_views_via_settings' )->content, '/other/path', '[GET /get_views_via_settings] Correct content', ); }; { package Baz; use Dancer2; set template => 'template_toolkit'; get '/set_views/**' => sub { my ($view) = splat; set views => join('/', @$view ); }; get '/:file' => sub { template param('file'); }; } subtest "modify views propogates to TT2 via dynamic INCLUDE_PATH" => sub { my $test = Plack::Test->create( Baz->to_app ); my $res = $test->request( GET '/index' ); is $res->code, 200, 'got template from views'; # Change views - this is an existing test corpus.. $test->request( GET '/set_views/t/corpus/pretty' ); # Get another template that is known to exist in the test corpus $res = $test->request( GET '/relative.tt' ); is $res->code, 200, 'got template from other view'; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/session_lifecycle.t0000644000175000017500000001064212650351107022221 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; use HTTP::Cookies; { package App; use Dancer2; set session => 'Simple'; set show_errors => 1; get '/no_session_data' => sub { return "session not modified"; }; get '/set_session/*' => sub { my ($name) = splat; session name => $name; }; get '/read_session' => sub { my $name = session('name') || ''; "name='$name'"; }; get '/destroy_session' => sub { my $name = session('name') || ''; app->destroy_session; return "destroyed='$name'"; }; get '/churn_session' => sub { app->destroy_session; session name => 'damian'; return "churned"; }; } my $url = 'http://localhost'; my $jar = HTTP::Cookies->new(); my $test = Plack::Test->create( App->to_app ); subtest 'No cookie set if session not referenced' => sub { my $res = $test->request( GET "$url/no_session_data" ); ok $res->is_success, "/no_session_data" or diag explain $res; $jar->extract_cookies($res); ok( !$jar->as_string, 'No cookie set' ); }; subtest 'No empty session created if session read attempted' => sub { my $res = $test->request( GET "$url/read_session" ); ok $res->is_success, "/read_session"; $jar->extract_cookies($res); ok( !$jar->as_string, 'No cookie set' ); }; my $sid1; subtest 'Set value into session' => sub { my $res = $test->request( GET "$url/set_session/larry" ); ok $res->is_success, "/set_session/larry"; $jar->extract_cookies($res); ok( $jar->as_string, 'Cookie set' ); # extract SID $jar->scan( sub { $sid1 = $_[2] } ); ok( $sid1, 'Got SID from cookie' ); }; subtest 'Read value back' => sub { # read value back my $req = GET "$url/read_session"; $jar->add_cookie_header($req); my $res = $test->request($req); ok $res->is_success, "/read_session"; $jar->clear; ok( !$jar->as_string, 'Jar cleared' ); $jar->extract_cookies($res); ok( $jar->as_string, 'session cookie set again' ); like $res->content, qr/name='larry'/, "session value looks good"; }; subtest 'Session cookie persists even if we do not touch sessions' => sub { my $req = GET "$url/no_session_data"; $jar->add_cookie_header($req); my $res = $test->request($req); ok $res->is_success, "/no_session_data"; $jar->clear; ok( !$jar->as_string, 'Jar cleared' ); $jar->extract_cookies($res); ok( $jar->as_string, 'session cookie set again' ); }; subtest 'Destroy session and check that cookies expiration is set' => sub { my $req = GET "$url/destroy_session"; $jar->add_cookie_header($req); my $res = $test->request($req); ok $res->is_success, "/destroy_session"; ok( $jar->as_string, 'We have a cookie before reading response' ); $jar->extract_cookies($res); ok( ! $jar->as_string, 'Cookie was removed from jar' ); }; subtest 'Session cookie not sent after session destruction' => sub { my $req = GET "$url/no_session_data"; $jar->add_cookie_header($req); my $res = $test->request($req); ok $res->is_success, "/no_session_data"; ok( !$jar->as_string, 'Jar is empty' ); $jar->extract_cookies($res); ok( !$jar->as_string, 'Jar still empty (no new session cookie)' ); }; my $sid2; subtest 'Set value into session again' => sub { my $res = $test->request( GET "$url/set_session/curly" ); ok $res->is_success, "/set_session/larry"; $jar->extract_cookies($res); ok( $jar->as_string, 'session cookie set' ); # extract SID $jar->scan( sub { $sid2 = $_[2] } ); isnt $sid2, $sid1, "New session has different ID"; }; subtest 'Destroy and create a session in one request' => sub { my $req = GET "$url/churn_session"; $jar->add_cookie_header($req); my $res = $test->request($req); ok $res->is_success, "/churn_session"; $jar->extract_cookies($res); ok( $jar->as_string, 'session cookie set' ); my $sid3; $jar->scan( sub { $sid3 = $_[2] } ); isnt $sid3, $sid2, "Changed session has different ID"; }; subtest 'Read value back' => sub { my $req = GET "$url/read_session"; $jar->add_cookie_header($req); my $res = $test->request($req); ok $res->is_success, "/read_session"; $jar->extract_cookies($res); ok( $jar->as_string, "session cookie set" ); like $res->content, qr/name='damian'/, "session value looks good"; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/app_alone.t0000644000175000017500000000063412650351107020455 0ustar gregoagregoa#!perl use strict; use warnings; use Test::More tests => 3; use Plack::Test; use HTTP::Request::Common; { package MyApp; use Dancer2; get '/' => sub {'OK'}; } my $app = MyApp->to_app; isa_ok( $app, 'CODE' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/' )->code, 200, '[GET /] Correct status' ); is( $cb->( GET '/' )->content, 'OK', '[GET /] Correct content' ); }; libdancer2-perl-0.166001+dfsg.orig/t/plugin_multiple_apps.t0000644000175000017500000000111312650351107022744 0ustar gregoagregoa# plugin_multiple_apps.t use strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; { package App; BEGIN { use Dancer2; set session => 'Simple'; } use t::lib::SubApp1 with => { session => engine('session') }; use t::lib::SubApp2 with => { session => engine('session') }; } my $app = Dancer2->psgi_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/subapp1' )->content, 1, '/subapp1' ); is( $cb->( GET '/subapp2' )->content, 2, '/subapp2' ); }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/deserialize.t0000644000175000017500000001377312650351107021027 0ustar gregoagregoause strict; use warnings; use Test::More tests => 15; use Plack::Test; use HTTP::Request::Common; use Dancer2::Logger::Capture; my $logger = Dancer2::Logger::Capture->new; isa_ok( $logger, 'Dancer2::Logger::Capture' ); { package App; use Dancer2; # default, we're actually overriding this later set serializer => 'JSON'; # for now set logger => 'Console'; put '/from_params' => sub { my %p = params(); return [ map +( $_ => $p{$_} ), sort keys %p ]; }; put '/from_data' => sub { my $p = request->data; return [ map +( $_ => $p->{$_} ), sort keys %{$p} ]; }; # This route is used for both toure and body params. post '/from/:town' => sub { my $p = params; return [ map +( $_ => $p->{$_} ), sort keys %{$p} ]; }; any [qw/del patch/] => '/from/:town' => sub { my $p = params('body'); return [ map +( $_ => $p->{$_} ), sort keys %{$p} ]; }; } my $test = Plack::Test->create( App->to_app ); subtest 'PUT request with parameters' => sub { for my $type ( qw ) { my $res = $test->request( PUT "/from_$type", 'Content-Type' => 'application/json', Content => '{ "foo": 1, "bar": 2 }' ); is( $res->content, '["bar",2,"foo",1]', "Parameters deserialized from $type", ); } }; my $app = App->to_app; use utf8; use JSON; use Encode; use Class::Load 'load_class'; note "Verify Serializers decode into characters"; { my $utf8 = '∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i)'; test_psgi $app, sub { my $cb = shift; for my $type ( qw/Dumper JSON YAML/ ) { my $class = "Dancer2::Serializer::$type"; load_class($class); my $serializer = $class->new(); my $body = $serializer->serialize({utf8 => $utf8}); # change the app serializer # we're overiding a RO attribute only for this test! Dancer2->runner->apps->[0]->set_serializer_engine( $serializer ); my $r = $cb->( PUT '/from_params', 'Content-Type' => $serializer->content_type, Content => $body, ); my $content = Encode::decode( 'UTF-8', $r->content ); # Dumper is a jerk and represents it in Perl \x{...} notation if ( $type eq 'Dumper' ) { { no strict; $content = eval $content; } # now $content is an actual ref again is_deeply( $content, [ 'utf8', $utf8 ], "utf-8 string returns the same using the $type serializer", ) } else { like( $content, qr{\Q$utf8\E}, "utf-8 string returns the same using the $type serializer", ); } } }; } # default back to JSON for the rest # we're overiding a RO attribute only for this test! Dancer2->runner->apps->[0]->set_serializer_engine( Dancer2::Serializer::JSON->new ); note "Decoding of mixed route and deserialized body params"; { # Check integers from request body remain integers # but route params get decoded. test_psgi $app, sub { my $cb = shift; my @req_params = ( "/from/D\x{c3}\x{bc}sseldorf", # /from/d%C3%BCsseldorf 'Content-Type' => 'application/json', Content => JSON::to_json({ population => 592393 }), ); my $r = $cb->( POST @req_params ); # Watch out for hash order randomization.. is_deeply( $r->content, '["population",592393,"town","'."D\x{c3}\x{bc}sseldorf".'"]', "Integer from JSON body remains integer and route params decoded", ); }; } # Check body is deserialized on PATCH and DELETE. # The RFC states the behaviour for DELETE is undefined; We take the lenient # and deserialize it. # http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-24#section-4.3.5 note "Deserialze any body content that is allowed or undefined"; { test_psgi $app, sub { my $cb = shift; for my $method ( qw/DELETE PATCH/ ) { my $request = HTTP::Request->new( $method, "/from/D\x{c3}\x{bc}sseldorf", # /from/d%C3%BCsseldorf [ 'Content-Type' => 'application/json' ], JSON::to_json({ population => 592393 }), ); my $response = $cb->($request); my $content = Encode::decode( 'UTF-8', $response->content ); # Only body params returned is( $content, '["population",592393]', "JSON body deserialized for " . uc($method) . " requests", ); } } } note 'Check serialization errors'; { Dancer2->runner->apps->[0]->set_serializer_engine( Dancer2::Serializer::JSON->new( log_cb => sub { $logger->log(@_) } ) ); test_psgi $app, sub { my $cb = shift; $cb->( PUT '/from_params', 'Content-Type' => 'application/json', Content => '---', ); my $trap = $logger->trapper; isa_ok( $trap, 'Dancer2::Logger::Capture::Trap' ); my $errors = $trap->read; isa_ok( $errors, 'ARRAY' ); is( scalar @{$errors}, 1, 'One error caught' ); my $msg = $errors->[0]; delete $msg->{'formatted'}; isa_ok( $msg, 'HASH' ); is( scalar keys %{$msg}, 2, 'Two items in the error' ); is( $msg->{'level'}, 'core', 'Correct level' ); like( $msg->{'message'}, qr{ ^ \QFailed to deserialize the request: \E \Qmalformed number\E }x, 'Correct error message', ); } } libdancer2-perl-0.166001+dfsg.orig/t/file_utils.t0000644000175000017500000000424112650351107020654 0ustar gregoagregoause strict; use warnings; use utf8; use Test::More tests => 20; use Test::Fatal; use File::Spec; BEGIN { @File::Spec::ISA = ("File::Spec::Unix") } use File::Temp 0.22; use Dancer2::FileUtils qw/read_file_content path_or_empty path/; sub write_file { my ( $file, $content ) = @_; open my $fh, '>', $file or die "cannot write file $file : $!"; binmode $fh, ':encoding(utf-8)'; print $fh $content; close $fh; } sub hexe { my $s = shift; $s =~ s/([\x00-\x1F])/sprintf('%#x',ord($1))/eg; return $s; } like( exception { Dancer2::FileUtils::open_file( '<', '/slfkjsdlkfjsdlf' ) }, qr{/slfkjsdlkfjsdlf' using mode '<'}, 'Failure opening nonexistent file', ); my $content = Dancer2::FileUtils::read_file_content(); is $content, undef; my $paths = [ [ undef => 'undef' ], [ '/foo/./bar/' => '/foo/bar/' ], [ '/foo/../bar' => '/bar' ], [ '/foo/bar/..' => '/foo/' ], ]; for my $case ( @$paths ) { is Dancer2::FileUtils::normalize_path( $case->[0] ), $case->[1]; } my $p = Dancer2::FileUtils::dirname('/somewhere'); is $p, '/'; my $tmp = File::Temp->new(); my $two = "²❷"; write_file( $tmp, "one$/$two" ); $content = read_file_content($tmp); is hexe($content), hexe("one$/$two"); my @content = read_file_content($tmp); is hexe( $content[0] ), hexe("one$/"); is $content[1], "$two"; # returns UNDEF on non-existant path my $path = 'bla/blah'; if ( !-e $path ) { is( path_or_empty($path), '', 'path_or_empty on non-existent path', ); } my $tmpdir = File::Temp->newdir; is( path_or_empty($tmpdir), $tmpdir, 'path_or_empty on an existing path' ); #slightly tricky paths on different platforms is( path( '/', 'b', '/c' ), '/b//c', 'path /,b,/c -> /b//c' ); is( path( '/', '/b', ), '/b', 'path /, /b -> /b' ); note "escape_filename"; { my $names = [ [ undef => 'undef' ], [ 'abcdef' => 'abcdef' ], [ 'ab++ef' => 'ab+2b+2bef' ], [ 'a/../b.txt' => 'a+2f+2e+2e+2fb+2etxt' ], [ "test\0\0" => 'test+00+00' ], [ 'test☠☠☠' => 'test+2620+2620+2620' ], ]; for my $case ( @$names ) { is Dancer2::FileUtils::escape_filename( $case->[0] ), $case->[1]; } } libdancer2-perl-0.166001+dfsg.orig/t/http_status.t0000644000175000017500000000262012650351107021076 0ustar gregoagregoause strict; use warnings; use Test::More tests => 11; use Dancer2::Core::HTTP; note "HTTP status"; { my @tests = ( { status => undef, expected => undef }, { status => 200, expected => 200 }, { status => 'Not Found', expected => 404 }, { status => 'bad_request', expected => 400 }, { status => 'i_m_a_teapot', expected => 418 }, { status => 'error', expected => 500 }, { status => 911, expected => 911 }, ); for my $test (@tests) { my $status_text = defined $test->{status} ? $test->{status} : 'undef'; is( Dancer2::Core::HTTP->status( $test->{status} ), $test->{expected}, "HTTP status looks good for $status_text" ); } } note "HTTP status_message"; { my @tests = ( { status => undef, expected => undef }, { status => 200, expected => 'OK' }, { status => 'error', expected => 'Internal Server Error' }, { status => 911, expected => undef }, ); for my $test (@tests) { my $status_text = defined $test->{status} ? $test->{status} : 'undef'; is( Dancer2::Core::HTTP->status_message( $test->{status} ), $test->{expected}, "HTTP status message looks good for $status_text" ); } } libdancer2-perl-0.166001+dfsg.orig/t/charset_server.t0000644000175000017500000000235412650351107021537 0ustar gregoagregoause Test::More; use strict; use warnings; use Encode; use utf8; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; get '/name/:name' => sub { "Your name: " . params->{name}; }; post '/name' => sub { "Your name: " . params->{name}; }; get '/unicode' => sub { "cyrillic shcha \x{0429}",; }; get '/symbols' => sub { '⚒ ⚓ ⚔ ⚕ ⚖ ⚗ ⚘ ⚙'; }; set charset => 'utf-8'; } my $app = Dancer2->psgi_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->( POST "/name", [ name => 'vasya'] ); is $res->content_type, 'text/html'; ok $res->content_type_charset ; # we always have charset if the setting is set is $res->content, 'Your name: vasya'; $res = $cb->( GET "/unicode" ); is $res->content_type, 'text/html'; is $res->content_type_charset, 'UTF-8'; is $res->content, Encode::encode( 'utf-8', "cyrillic shcha \x{0429}" ); $res = $cb->( GET "/symbols" ); is $res->content_type, 'text/html'; is $res->content_type_charset, 'UTF-8'; is $res->content, Encode::encode( 'utf-8', "⚒ ⚓ ⚔ ⚕ ⚖ ⚗ ⚘ ⚙" ); }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/logger_console.t0000644000175000017500000000264412650351107021523 0ustar gregoagregoause strict; use warnings; use Test::More; use Capture::Tiny 0.12 'capture_stderr'; use Dancer2::Logger::Console; my $file = __FILE__; my $l = Dancer2::Logger::Console->new( app_name => 'test', log_level => 'core' ); for my $level (qw{core debug info warning error}) { my $stderr = capture_stderr { $l->$level("$level") }; # We are dealing directly with the logger, not through the DSL. # Skipping 5 stack frames is likely to point to somewhere outside # this test; however Capture::Tiny adds in several call frames # (see below) to capture the output, giving a reasonable caller # to test for like $stderr, qr{$level in \Q$file\E l[.] 15}, "$level message sent"; } done_testing; __END__ # Stack frames involved where Role::Logger executes caller(5): # Dancer2::Core::Role::Logger::format_message(Dancer2::Logger::Console=HASH(0x7f8e41029c60), "error", "error") called at lib/Dancer2/Logger/Console.pm line 10 # Dancer2::Logger::Console::log(Dancer2::Logger::Console=HASH(0x7f8e41029c60), "error", "error") called at lib/Dancer2/Core/Role/Logger.pm line 183 # Dancer2::Core::Role::Logger::error(Dancer2::Logger::Console=HASH(0x7f8e41029c60), "error") called at t/logger_console.t line 12 # main::__ANON__() called at Capture/Tiny.pm line 369 # eval {...} called at Capture/Tiny.pm line 369 # Capture::Tiny::_capture_tee(0, 1, 0, 0, CODE(0x7f8e418181e0)) called at t/logger_console.t line 12 libdancer2-perl-0.166001+dfsg.orig/t/route-pod-coverage/0000775000175000017500000000000012650351107022040 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/route-pod-coverage/route-pod-coverage.t0000644000175000017500000000076412650351107025741 0ustar gregoagregoause strict; use warnings; use Test::More; use t::lib::TestPod; use Dancer2::Test apps => ['t::lib::TestPod']; is_pod_covered 'is pod covered'; my $pod_structure = { 't::lib::TestPod' => { 'has_pod' => 1, 'routes' => [ "post /in_testpod/*", "post /me:id", "get /in_testpod", "get /hello", "get /me:id" ] } }; is_deeply( route_pod_coverage, $pod_structure, 'my pod looks like expected' ); done_testing; libdancer2-perl-0.166001+dfsg.orig/t/shared_engines.t0000644000175000017500000000210112650351107021464 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Cookies; use HTTP::Request::Common; { package App; # call stuff before next use() statement BEGIN { use Dancer2; set session => 'Simple'; engine('session')->{'__marker__'} = 1; } use t::lib::Foo with => { session => engine('session') }; get '/main' => sub { session( 'test' => 42 ); }; } my $jar = HTTP::Cookies->new; my $url = 'http://localhost'; { my $test = Plack::Test->create( App->to_app ); my $res = $test->request( GET "$url/main" ); like $res->content, qr{42}, "session is set in main"; $jar->extract_cookies($res); ok( $jar->as_string, 'Got cookie' ); } { my $test = Plack::Test->create( t::lib::Foo->to_app ); my $req = GET "$url/in_foo"; $jar->add_cookie_header($req); my $res = $test->request($req); like $res->content, qr{42}, "session is set in foo"; } my $engine = t::lib::Foo->dsl->engine('session'); is $engine->{__marker__}, 1, "the session engine in subapp is the same"; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/template_ext.t0000644000175000017500000000115612650351107021212 0ustar gregoagregoause strict; use warnings; use Test::More; eval { require Template; Template->import(); 1 } or plan skip_all => 'Template::Toolkit probably missing.'; use Dancer2; set engines => { template => { template_toolkit => { extension => 'foo', }, }, }; set template => 'template_toolkit'; my $tt = engine('template'); isa_ok( $tt, 'Dancer2::Template::TemplateToolkit' ); is( $tt->default_tmpl_ext, 'foo', "Template extension is 'foo' as configured", ); is( $tt->view_pathname('foo'), 'foo.foo' , "view('foo') gives filename with right extension as configured", ); done_testing; libdancer2-perl-0.166001+dfsg.orig/t/log_levels.t0000644000175000017500000000342212650351107020650 0ustar gregoagregoa#!perl use strict; use warnings; use Test::More tests => 6; use Capture::Tiny 0.12 'capture_stderr'; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; set logger => 'console'; set log => 'debug'; get '/debug' => sub { debug "debug msg\n"; warning "warning msg\n"; error "error msg\n"; set log => 'warning'; return 'debug'; }; get '/warning' => sub { debug "debug msg\n"; warning "warning msg\n"; error "error msg\n"; return 'warning'; }; } my $app = App->to_app; test_psgi $app, sub { my $cb = shift; my $res; { my $stderr = capture_stderr { $res = $cb->( GET '/debug' ) }; is( $res->code, 200, 'Successful response' ); is( $res->content, 'debug', 'Correct content' ); like( $stderr, qr/ ^ # a debug line \[App:\d+\] \s debug [^\n]+ \n # a warning line \[App:\d+\] \s warning [^\n]+ \n # followed by an error line \[App:\d+\] \s error [^\n]+ \n $ /x, 'Log levels work', ); } { my $stderr = capture_stderr { $res = $cb->( GET '/warning' ) }; is( $res->code, 200, 'Successful response' ); is( $res->content, 'warning', 'Correct content' ); like( $stderr, qr/ ^ # a warning line \[App:\d+\] \s warning [^\n]+ \n # followed by an error line \[App:\d+\] \s error [^\n]+ \n $ /x, 'Log levels work', ); } }; libdancer2-perl-0.166001+dfsg.orig/t/serializer.t0000644000175000017500000000160512650351107020667 0ustar gregoagregoause strict; use warnings; use Test::More tests => 5; use Dancer2::Serializer::Dumper; use Plack::Test; use HTTP::Request::Common; { package MyApp; use Dancer2; set serializer => 'JSON'; get '/json' => sub { +{ bar => 'baz' } }; } my $app = MyApp->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; { # Response with implicit call to the serializer my $res = $cb->( GET '/json' ); is( $res->code, 200, '[/json] Correct status' ); is( $res->content, '{"bar":"baz"}', '[/json] Correct content' ); is( $res->headers->content_type, 'application/json', '[/json] Correct content-type headers', ); } }; my $serializer = Dancer2::Serializer::Dumper->new(); is( $serializer->content_type, 'text/x-data-dumper', 'content-type is set correctly', ); libdancer2-perl-0.166001+dfsg.orig/t/forward_test_tcp.t0000644000175000017500000000377312650351107022077 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; get '/' => sub { 'home:' . join( ',', params ); }; get '/bounce/' => sub { forward '/' }; get '/bounce/:withparams/' => sub { forward '/' }; get '/bounce2/adding_params/' => sub { forward '/', { withparams => 'foo' }; }; get '/go_to_post/' => sub { forward '/simple_post_route/', { foo => 'bar' }, { method => 'post' }; }; post '/simple_post_route/' => sub { 'post:' . join( ',', params ); }; post '/' => sub {'post-home'}; post '/bounce/' => sub { forward '/' }; } my $app = Dancer2->psgi_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->(GET "/"); is $res->code => 200; like $res->content => qr/home:/; $res = $cb->(GET "/bounce/"); is $res->code => 200; like $res->content => qr/home:/; $res = $cb->(GET "/bounce/thesethings/"); is $res->code => 200; is $res->content => 'home:withparams,thesethings'; $res = $cb->(GET "/bounce2/adding_params/"); is $res->code => 200; is $res->content => 'home:withparams,foo'; $res = $cb->(GET "/go_to_post/"); is $res->code => 200; is $res->content => 'post:foo,bar'; $res = $cb->(GET "/bounce/"); is $res->header('Content-Length') => 5; is $res->header('Content-Type') => 'text/html; charset=UTF-8'; is $res->header('Server') => "Perl Dancer2 " . Dancer2->VERSION; $res = $cb->(POST "/"); is $res->code => 200; is $res->content => 'post-home'; $res = $cb->(POST "/bounce/"); is $res->code => 200; is $res->content => 'post-home'; is $res->header('Content-Length') => 9; is $res->header('Content-Type') => 'text/html; charset=UTF-8'; is $res->header('Server') => "Perl Dancer2 " . Dancer2->VERSION; }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/redirect.t0000644000175000017500000001443712650351107020326 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; subtest 'basic redirects' => sub { { package App1; use Dancer2; get '/' => sub {'home'}; get '/bounce' => sub { redirect '/' }; get '/redirect' => sub { header 'X-Foo' => 'foo'; redirect '/'; }; get '/redirect_querystring' => sub { redirect '/login?failed=1' }; } my $app = App1->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; { my $res = $cb->( GET '/' ); is( $res->code, 200, '[GET /] Correct code' ); is( $res->content, 'home', '[GET /] Correct content' ); is( $res->headers->content_type, 'text/html', '[GET /] Correct content-type', ); is( $cb->( GET '/bounce' )->code, 302, '[GET /bounce] Correct code', ); } { my $res = $cb->( GET '/redirect' ); is( $res->code, 302, '[GET /redirect] Correct code' ); is( $res->headers->header('Location'), 'http://localhost/', 'Correct Location header', ); is( $res->headers->header('X-Foo'), 'foo', 'Correct X-Foo header', ); } { my $res = $cb->( GET '/redirect_querystring' ); is( $res->code, 302, '[GET /redirect_querystring] Correct code' ); is( $res->headers->header('Location'), 'http://localhost/login?failed=1', 'Correct Location header', ); } }; }; # redirect absolute subtest 'absolute and relative redirects' => sub { { package App2; use Dancer2; get '/absolute_with_host' => sub { redirect "http://foo.com/somewhere"; }; get '/absolute' => sub { redirect "/absolute"; }; get '/relative' => sub { redirect "somewhere/else"; }; } my $app = App2->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; { my $res = $cb->( GET '/absolute_with_host' ); is( $res->headers->header('Location'), 'http://foo.com/somewhere', 'Correct Location header', ); } { my $res = $cb->( GET '/absolute' ); is( $res->headers->header('Location'), 'http://localhost/absolute', 'Correct Location header', ); } { my $res = $cb->( GET '/relative' ); is( $res->headers->header('Location'), 'http://localhost/somewhere/else', 'Correct Location header', ); } }; }; subtest 'redirect behind a proxy' => sub { { package App3; use Dancer2; prefix '/test2'; set behind_proxy => 1; get '/bounce' => sub { redirect '/test2' }; } my $app = App3->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; { is( $cb->( GET '/test2/bounce', 'X-FORWARDED-HOST' => 'nice.host.name', )->headers->header('Location'), 'http://nice.host.name/test2', 'behind a proxy, host() is read from X_FORWARDED_HOST', ); } { is( $cb->( GET '/test2/bounce', 'X-FORWARDED-HOST' => 'nice.host.name', 'FORWARDED-PROTO' => 'https', )->headers->header('Location'), 'https://nice.host.name/test2', '... and the scheme is read from HTTP_FORWARDED_PROTO', ); } { is( $cb->( GET '/test2/bounce', 'X-FORWARDED-HOST' => 'nice.host.name', 'X-FORWARDED-PROTOCOL' => 'ftp', # stupid, but why not? )->headers->header('Location'), 'ftp://nice.host.name/test2', '... or from X_FORWARDED_PROTOCOL', ); } { is( $cb->( GET '/test2/bounce', 'X-FORWARDED-HOST' => 'nice.host.name', 'X-FORWARDED-PROTO' => 'https', )->headers->header('Location'), 'https://nice.host.name/test2', '... or from X_FORWARDED_PROTO', ); } }; }; subtest 'redirect behind multiple proxies' => sub { { package App4; use Dancer2; prefix '/test2'; set behind_proxy => 1; get '/bounce' => sub { redirect '/test2' }; } my $app = App4->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; { is( $cb->( GET '/test2/bounce', 'X-FORWARDED-HOST' => "proxy1.example, proxy2.example", )->headers->header('Location'), 'http://proxy1.example/test2', "behind multiple proxies, host() is read from X_FORWARDED_HOST", ); } { is( $cb->( GET '/test2/bounce', 'X-FORWARDED-HOST' => "proxy1.example, proxy2.example", 'FORWARDED-PROTO' => 'https', )->headers->header('Location'), 'https://proxy1.example/test2', '... and the scheme is read from HTTP_FORWARDED_PROTO', ); } { is( $cb->( GET '/test2/bounce', 'X-FORWARDED-HOST' => "proxy1.example, proxy2.example", 'X-FORWARDED-PROTOCOL' => 'ftp', # stupid, but why not? )->headers->header('Location'), 'ftp://proxy1.example/test2', '... or from X_FORWARDED_PROTOCOL', ); } }; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/public/0000775000175000017500000000000012650351107017607 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/public/file.txt0000644000175000017500000000002612650351107021263 0ustar gregoagregoathis is a public file libdancer2-perl-0.166001+dfsg.orig/t/plugin_register.t0000644000175000017500000000230712650351107021720 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Test::Fatal; subtest 'reserved keywords' => sub { use Dancer2::Plugin; like( exception { register dance => sub {1} }, qr/You can't use 'dance', this is a reserved keyword/, "Can't use Dancer2's reserved keywords", ); like( exception { register '1function' => sub {1} }, qr/You can't use '1function', it is an invalid name/, "Can't use invalid names for keywords", ); }; subtest 'plugin reserved keywords' => sub { { package Foo; use Dancer2::Plugin; Test::More::is( Test::Fatal::exception { register 'foo_method' => sub {1} }, undef, "can register a new keyword", ); } { package Bar; use Dancer2::Plugin; Test::More::like( Test::Fatal::exception { register 'foo_method' => sub {1} }, qr{can't use foo_method, this is a keyword reserved by Foo}, "cant register a keyword already registered by another plugin", ); } }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/response.t0000644000175000017500000000267212650351107020361 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Dancer2; use Dancer2::Core::Response; my $r = Dancer2::Core::Response->new( content => "hello" ); is $r->status, 200; is $r->content, 'hello'; note "content_type"; $r = Dancer2::Core::Response->new( headers => [ 'Content-Type' => 'text/html' ], content => 'foo', ); is_deeply $r->to_psgi, [ 200, [ Server => "Perl Dancer2 " . Dancer2->VERSION, 'Content-Length' => 3, 'Content-Type' => 'text/html', ], ['foo'] ]; isa_ok $r->headers, 'HTTP::Headers'; is $r->content_type, 'text/html'; $r->content_type('text/plain'); is $r->content_type, 'text/plain'; ok( !$r->is_forwarded ); $r->forward('http://perldancer.org'); ok( $r->is_forwarded ); is $r->header('X-Foo'), undef; $r->header( 'X-Foo' => 42 ); is $r->header('X-Foo'), 42; $r->header( 'X-Foo' => 432 ); is $r->header('X-Foo'), 432; $r->push_header( 'X-Foo' => 777 ); is $r->header('X-Foo'), '432, 777'; $r->header( 'X-Bar' => 234 ); is $r->header('X-Bar'), '234'; is scalar( @{ $r->headers_to_array } ), 12; # stringify HTTP status $r = Dancer2::Core::Response->new( content => "foo", status => "Not Found" ); is $r->status, 404; $r = Dancer2::Core::Response->new( content => "foo", status => "not_modified" ); is $r->status, 304; # test setting content as "0" $r = Dancer2::Core::Response->new( content => "foo" ); $r->content("0"); is $r->content, "0"; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/cookie.t0000644000175000017500000000741112650351107017770 0ustar gregoagregoause strict; use warnings; use Test::More; BEGIN { # Freeze time at Tue, 15-Jun-2010 00:00:00 GMT *CORE::GLOBAL::time = sub { return 1276560000 } } use Dancer2::Core::Cookie; note "Constructor"; my $cookie = Dancer2::Core::Cookie->new( name => "foo" ); isa_ok $cookie => 'Dancer2::Core::Cookie'; can_ok $cookie => 'to_header'; note "Setting values"; is $cookie->value("foo") => "foo"; is $cookie->value => "foo"; is $cookie . "bar", "foobar", "Stringifies to desired value"; ok $cookie->value( [qw(a b c)] ); is $cookie->value => 'a'; is_deeply [ $cookie->value ] => [qw(a b c)]; ok $cookie->value( { x => 1, y => 2 } ); like $cookie->value => qr/^[xy]$/; # hashes doesn't store order... is_deeply [ sort $cookie->value ] => [ sort ( 1, 2, 'x', 'y' ) ]; note "accessors and defaults"; is $cookie->name => 'foo'; is $cookie->name("bar") => "bar"; is $cookie->name => 'bar'; ok !$cookie->domain; is $cookie->domain("dancer.org") => "dancer.org"; is $cookie->domain => "dancer.org"; is $cookie->domain("") => ""; ok !$cookie->domain; is $cookie->path => '/', "by default, path is /"; ok $cookie->has_path, "has_path"; is $cookie->path("/foo") => "/foo"; ok $cookie->has_path, "has_path"; is $cookie->path => "/foo"; ok !$cookie->secure; is $cookie->secure(1) => 1; is $cookie->secure => 1; is $cookie->secure(0) => 0; ok !$cookie->secure; ok !$cookie->http_only; is $cookie->http_only(1) => 1; is $cookie->http_only => 1; is $cookie->http_only(0) => 0; ok !$cookie->http_only; note "expiration strings"; my $min = 60; my $hour = 60 * $min; my $day = 24 * $hour; my $week = 7 * $day; my $mon = 30 * $day; my $year = 365 * $day; ok !$cookie->expires; my %times = ( "+2" => "Tue, 15-Jun-2010 00:00:02 GMT", "+2h" => "Tue, 15-Jun-2010 02:00:00 GMT", "-2h" => "Mon, 14-Jun-2010 22:00:00 GMT", "1 hour" => "Tue, 15-Jun-2010 01:00:00 GMT", "3 weeks 4 days 2 hours 99 min 0 secs" => "Sat, 10-Jul-2010 03:39:00 GMT", "2 months" => "Sat, 14-Aug-2010 00:00:00 GMT", "12 years" => "Sun, 12-Jun-2022 00:00:00 GMT", 1288817656 => "Wed, 03-Nov-2010 20:54:16 GMT", 1288731256 => "Tue, 02-Nov-2010 20:54:16 GMT", 1288644856 => "Mon, 01-Nov-2010 20:54:16 GMT", 1288558456 => "Sun, 31-Oct-2010 20:54:16 GMT", 1288472056 => "Sat, 30-Oct-2010 20:54:16 GMT", 1288385656 => "Fri, 29-Oct-2010 20:54:16 GMT", 1288299256 => "Thu, 28-Oct-2010 20:54:16 GMT", 1288212856 => "Wed, 27-Oct-2010 20:54:16 GMT", # Anything not understood is passed through "basset hounds got long ears" => "basset hounds got long ears", "+2 something" => "+2 something", ); for my $exp ( keys %times ) { my $want = $times{$exp}; $cookie->expires($exp); is $cookie->expires => $want; } note "to header"; my @cake = ( { cookie => { name => 'bar', value => 'foo', expires => '+2h', secure => 1 }, expected => sprintf( "bar=foo; path=/; expires=%s; Secure", $times{'+2h'} ), }, { cookie => { name => 'bar', value => 'foo', domain => 'dancer.org', path => '/dance', http_only => 1 }, expected => "bar=foo; path=/dance; domain=dancer.org; HttpOnly", }, { cookie => { name => 'bar', value => 'foo', }, expected => "bar=foo; path=/", }, ); for my $cook (@cake) { my $c = Dancer2::Core::Cookie->new( %{ $cook->{cookie} } ); is $c->to_header => $cook->{expected}; } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/error.t0000644000175000017500000001251012650351107017644 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Plack::Test; use HTTP::Request::Common; use Dancer2::Core::App; use Dancer2::Core::Response; use Dancer2::Core::Request; use Dancer2::Core::Error; use JSON (); # Error serialization my $env = { 'psgi.url_scheme' => 'http', REQUEST_METHOD => 'GET', SCRIPT_NAME => '/foo', PATH_INFO => '/bar/baz', REQUEST_URI => '/foo/bar/baz', QUERY_STRING => 'foo=42&bar=12&bar=13&bar=14', SERVER_NAME => 'localhost', SERVER_PORT => 5000, SERVER_PROTOCOL => 'HTTP/1.1', REMOTE_ADDR => '127.0.0.1', HTTP_COOKIE => 'dancer.session=1234; fbs_102="access_token=xxxxxxxxxx%7Cffffff"', HTTP_X_FORWARDED_FOR => '127.0.0.2', REMOTE_HOST => 'localhost', HTTP_USER_AGENT => 'Mozilla', REMOTE_USER => 'sukria', }; my $app = Dancer2::Core::App->new( name => 'main' ); my $request = $app->build_request($env); $app->set_request($request); subtest 'basic defaults of Error object' => sub { my $err = Dancer2::Core::Error->new( app => $app ); is $err->status, 500, 'code'; is $err->title, 'Error 500 - Internal Server Error', 'title'; is $err->message, '', 'message'; like $err->content, qr!http://localhost:5000/foo/css!, "error content contains css path relative to uri_base"; }; subtest "send_error in route" => sub { { package App; use Dancer2; set serializer => 'JSON'; get '/error' => sub { send_error "This is a custom error message"; return "send_error returns so this content is not processed"; }; } my $app = App->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $r = $cb->( GET '/error' ); is( $r->code, 500, 'send_error sets the status to 500' ); like( $r->content, qr{This is a custom error message}, 'Error message looks good', ); is( $r->content_type, 'application/json', 'Response has appropriate content type after serialization', ); }; }; subtest "send_error with custom stuff" => sub { { package App; use Dancer2; get '/error/:x' => sub { my $x = param('x'); send_error "Error $x", "5$x"; }; } my $app = App->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $r = $cb->( GET '/error/42' ); is( $r->code, 542, 'send_error sets the status to 542' ); like( $r->content, qr{Error 42}, 'Error message looks good' ); }; }; subtest 'Response->error()' => sub { my $resp = Dancer2::Core::Response->new; isa_ok $resp->error( message => 'oops', status => 418 ), 'Dancer2::Core::Error'; is $resp->status => 418, 'response code is 418'; like $resp->content => qr/oops/, 'response content overriden by error'; like $resp->content => qr/teapot/, 'error code title is present'; ok $resp->is_halted, 'response is halted'; }; subtest 'Throwing an error with a response' => sub { my $resp = Dancer2::Core::Response->new; my $err = eval { Dancer2::Core::Error->new( exception => 'our exception', show_errors => 1 )->throw($resp) }; isa_ok($err, 'Dancer2::Core::Response', "Error->throw() accepts a response"); }; subtest 'Error with show_errors: 0' => sub { my $err = Dancer2::Core::Error->new( exception => 'our exception', show_errors => 0 )->throw; unlike $err->content => qr/our exception/; }; subtest 'Error with show_errors: 1' => sub { my $err = Dancer2::Core::Error->new( exception => 'our exception', show_errors => 1 )->throw; like $err->content => qr/our exception/; }; subtest 'App dies with serialized error' => sub { { package AppDies; use Dancer2; set serializer => 'JSON'; get '/die' => sub { die "oh no\n"; # I should serialize }; } my $app = AppDies->to_app; isa_ok( $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $r = $cb->( GET '/die' ); is( $r->code, 500, '/die returns 500' ); my $out = eval { JSON->new->utf8(0)->decode($r->decoded_content) }; ok(!$@, 'JSON decoding serializer error produces no errors'); isa_ok($out, 'HASH', 'Error deserializes to a hash'); like($out->{exception}, qr/^oh no/, 'Get expected error message'); }; }; subtest 'Error with exception object' => sub { local $@; eval { MyTestException->throw('a test exception object') }; my $err = Dancer2::Core::Error->new( exception => $@, show_errors => 1, )->throw; like $err->content, qr/a test exception object/, 'Error content contains exception message'; }; done_testing; { # Simple test exception class package MyTestException; use overload '""' => \&as_str; sub new { return bless {}; } sub throw { my ( $class, $error ) = @_; my $self = ref($class) ? $class : $class->new; $self->{error} = $error; die $self; } sub as_str { return $_[0]->{error} } } libdancer2-perl-0.166001+dfsg.orig/t/dispatcher.t0000644000175000017500000001351012650351107020642 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Carp 'croak'; use Dancer2; use Dancer2::Core::App; use Dancer2::Core::Route; use Dancer2::Core::Dispatcher; use Dancer2::Core::Hook; use Dancer2::Core::Response; set logger => 'Null'; # init our test fixture my $buffer = {}; my $app = Dancer2::Core::App->new( name => 'main' ); $app->setting( logger => engine('logger') ); $app->setting( show_errors => 1 ); # a simple / route $app->add_route( method => 'get', regexp => '/', code => sub {"home"}, ); # an error route $app->add_route( method => 'get', regexp => '/error', code => sub { Fail->fail }, ); # A chain of two route for /user/$foo $app->add_route( method => 'get', regexp => '/user/:name', code => sub { my $app = shift; $buffer->{user} = $app->request->params->{'name'}; $app->response->has_passed(1); }, ); $app->add_route( method => 'get', regexp => '/user/*?', code => sub { my $app = shift; "Hello " . $app->request->params->{'name'}; }, ); # a route with a 204 response $app->add_route( method => 'get', regexp => '/twoohfour', code => sub { my $app = shift; $app->response->status(204); "This content should be removed"; }, ); # the tests my @tests = ( { env => { REQUEST_METHOD => 'GET', PATH_INFO => '/', }, expected => [ 200, [ 'Content-Length' => 4, 'Content-Type' => 'text/html; charset=UTF-8', 'Server' => "Perl Dancer2 " . Dancer2->VERSION, ], ["home"] ] }, { env => { REQUEST_METHOD => 'GET', PATH_INFO => '/user/Johnny', }, expected => [ 200, [ 'Content-Length' => 12, 'Content-Type' => 'text/html; charset=UTF-8', 'Server' => "Perl Dancer2 " . Dancer2->VERSION, ], ["Hello Johnny"] ] }, { env => { REQUEST_METHOD => 'GET', PATH_INFO => '/twoohfour', }, expected => [ 204, [ 'Content-Type' => 'text/html; charset=UTF-8', 'Server' => "Perl Dancer2 " . Dancer2->VERSION, ], [] ] }, { env => { REQUEST_METHOD => 'GET', PATH_INFO => '/haltme', }, expected => [ 302, [ 'Location' => 'http://perldancer.org', 'Content-Length' => '305', 'Content-Type' => 'text/html; charset=utf-8', 'Server' => "Perl Dancer2 " . Dancer2->VERSION, ], qr/This item has moved/ ] }, # NOT SUPPORTED YET # { env => { # REQUEST_METHOD => 'GET', # PATH_INFO => '/admin', # }, # expected => [200, [], ["home"]] # }, ); # simulates a redirect with halt $app->add_hook( Dancer2::Core::Hook->new( name => 'before', code => sub { my $app = shift; if ( $app->request->path_info eq '/haltme' ) { $app->response->header( Location => 'http://perldancer.org' ); $app->response->status(302); $app->response->is_halted(1); } }, ) ); my $was_in_second_filter = 0; $app->add_hook( Dancer2::Core::Hook->new( name => 'before', code => sub { my $app = shift; if ( $app->request->path_info eq '/haltme' ) { $was_in_second_filter = 1; # should not happen because first filter halted the flow } }, ) ); $app->add_route( method => 'get', regexp => '/haltme', code => sub {"should not get there"}, ); $app->compile_hooks; plan tests => 16; my $dispatcher = Dancer2::Core::Dispatcher->new( apps => [$app] ); my $counter = 0; foreach my $test (@tests) { my $env = $test->{env}; my $expected = $test->{expected}; my $path = $env->{'PATH_INFO'}; my $resp = $dispatcher->dispatch($env); is( $resp->[0], $expected->[0], "[$path] Return code ok" ); my %got_headers = @{ $resp->[1] }; my %exp_headers = @{ $expected->[1] }; is_deeply( \%got_headers, \%exp_headers, "[$path] Correct headers" ); if ( ref( $expected->[2] ) eq "Regexp" ) { like $resp->[2][0] => $expected->[2], "[$path] Contents ok. (test $counter)"; } else { is_deeply $resp->[2] => $expected->[2], "[$path] Contents ok. (test $counter)"; } $counter++; } foreach my $test ( { env => { REQUEST_METHOD => 'GET', PATH_INFO => '/error', 'psgi.uri_scheme' => 'http', SERVER_NAME => 'localhost', SERVER_PORT => 5000, SERVER_PROTOCOL => 'HTTP/1.1', }, expected => [ 500, [ 'Content-Length', "Content-Type", 'text/html' ], qr!Internal Server Error.*Can't locate object method "fail" via package "Fail" \(perhaps you forgot to load "Fail"\?\) at t[\\/]dispatcher\.t line \d+\.!s ] } ) { my $env = $test->{env}; my $expected = $test->{expected}; my $psgi_response = $dispatcher->dispatch($env); my $resp = Dancer2::Core::Response->new( status => $psgi_response->[0], headers => $psgi_response->[1], content => $psgi_response->[2][0], ); is $resp->status => $expected->[0], "Return code ok."; ok( $resp->header('Content-Length') >= 140, "Length ok." ); like $resp->content, $expected->[2], "contents ok"; } is $was_in_second_filter, 0, "didnt enter the second filter, because of halt"; libdancer2-perl-0.166001+dfsg.orig/t/config/0000775000175000017500000000000012650351107017576 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/config/environments/0000775000175000017500000000000012650351107022325 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/config/environments/staging.json0000644000175000017500000000010412650351107024645 0ustar gregoagregoa{ "main": "1", "charset": 'UTF-8', "show_errors": "1" } libdancer2-perl-0.166001+dfsg.orig/t/config/environments/failure.yml0000644000175000017500000000007512650351107024477 0ustar gregoagregoanot valid YAML - inconsistent indentation foo: 42 bar: baz libdancer2-perl-0.166001+dfsg.orig/t/config/environments/production.yml0000644000175000017500000000004112650351107025227 0ustar gregoagregoashow_errors: 0 logger: "console" libdancer2-perl-0.166001+dfsg.orig/t/config/environments/merging.yml0000644000175000017500000000007012650351107024473 0ustar gregoagregoaapplication: some_feature: bar another_setting: baz libdancer2-perl-0.166001+dfsg.orig/t/config/config.yml0000644000175000017500000000011312650351107021557 0ustar gregoagregoamain: 1 charset: 'UTF-8' show_errors: 1 application: some_feature: foo libdancer2-perl-0.166001+dfsg.orig/t/config_reader.t0000644000175000017500000000710412650351107021305 0ustar gregoagregoause strict; use warnings; use Test::More; use Test::Fatal; use Carp 'croak'; use Dancer2::Core::Runner; use Dancer2::FileUtils qw/dirname path/; use File::Spec; use File::Temp; my $runner = Dancer2::Core::Runner->new(); my $location = File::Spec->rel2abs( path( dirname(__FILE__), 'config' ) ); { package Prod; use Moo; with 'Dancer2::Core::Role::ConfigReader'; sub name {'Prod'} sub _build_environment {'production'} sub _build_location {$location} sub _build_default_config {$runner->config} package Dev; use Moo; with 'Dancer2::Core::Role::ConfigReader'; sub _build_environment {'development'} sub _build_location {$location}; sub _build_default_config {$runner->config} package Failure; use Moo; with 'Dancer2::Core::Role::ConfigReader'; sub _build_environment {'failure'} sub _build_location {$location} sub _build_default_config {$runner->config} package Staging; use Moo; with 'Dancer2::Core::Role::ConfigReader'; sub _build_environment {'staging'} sub _build_location {$location} sub _build_default_config {$runner->config} package Merging; use Moo; with 'Dancer2::Core::Role::ConfigReader'; sub name {'Merging'} sub _build_environment {'merging'} sub _build_location {$location} sub _build_default_config {$runner->config} } my $d = Dev->new(); is_deeply $d->config_files, [ path( $location, 'config.yml' ), ], "config_files() only sees existing files"; my $f = Prod->new; is $f->does('Dancer2::Core::Role::ConfigReader'), 1, "role Dancer2::Core::Role::ConfigReader is consumed"; is_deeply $f->config_files, [ path( $location, 'config.yml' ), path( $location, 'environments', 'production.yml' ), ], "config_files() works"; my $j = Staging->new; is_deeply $j->config_files, [ path( $location, 'config.yml' ), path( $location, 'environments', 'staging.json' ), ], "config_files() does JSON too!"; note "bad YAML file"; my $fail = Failure->new; is $fail->environment, 'failure'; is_deeply $fail->config_files, [ path( $location, 'config.yml' ), path( $location, 'environments', 'failure.yml' ), ], "config_files() works"; like( exception { $fail->config }, qr{Unable to parse the configuration file}, 'Configuration file parsing failure', ); note "config merging"; my $m = Merging->new; # Check the 'application' top-level key; its the only key that # is currently a HoH in the test configurations is_deeply $m->config->{application}, { some_feature => 'bar', another_setting => 'baz', }, "full merging of configuration hashes"; note "config parsing"; is $f->config->{show_errors}, 0; is $f->config->{main}, 1; is $f->config->{charset}, 'utf-8', "normalized UTF-8 to utf-8"; ok( $f->has_setting('charset') ); ok( !$f->has_setting('foobarbaz') ); note "default values"; is $f->setting('apphandler'), 'Standalone'; like( exception { $f->_normalize_config( { charset => 'BOGUS' } ) }, qr{Charset defined in configuration is wrong : couldn't identify 'BOGUS'}, 'Configuration file charset failure', ); { package Foo; use Carp 'croak'; sub foo { croak "foo" } } is $f->setting('traces'), 0; unlike( exception { Foo->foo() }, qr{Foo::foo}, "traces are not enabled", ); $f->setting( traces => 1 ); like( exception { Foo->foo() }, qr{Foo::foo}, "traces are enabled", ); { my $tmpdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 ); $ENV{DANCER_CONFDIR} = $tmpdir; my $f = Prod->new; is $f->config_location, $tmpdir; } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/memory_cycles.t0000644000175000017500000000115112650351107021364 0ustar gregoagregoause strict; use warnings; use Test::More; use Test::Fatal; use Class::Load 'try_load_class'; use Plack::Test; try_load_class('Test::Memory::Cycle') or plan skip_all => 'Test::Memory::Cycle not present'; { package MyApp::Cycles; use Dancer2; set auto_page => 1; set serializer => 'JSON'; get '/**' => sub { return { hello => 'world' }; }; } my $app = MyApp::Cycles->to_app; my $runner = Dancer2->runner; Test::Memory::Cycle::memory_cycle_ok( $runner, "runner has no memory cycles" ); Test::Memory::Cycle::memory_cycle_ok( $app, "App has no memory cycles" ); done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/named_apps.t0000644000175000017500000000136312650351107020626 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Plack::Test; use HTTP::Request::Common; { package Foo; use Dancer2; hook before => sub { vars->{foo} = 'foo' }; post '/foo' => sub { return vars->{foo} . 'foo' . vars->{baz}; }; } { package Bar; use Dancer2 appname => 'Foo'; # Add routes and hooks to Foo. hook before => sub { vars->{baz} = 'baz' }; post '/bar' => sub { return vars->{foo} . 'bar' . vars->{baz}; } } my $app = Dancer2->psgi_app; test_psgi $app, sub { my $cb = shift; for my $path ( qw/foo bar/ ) { my $res = $cb->( POST "/$path" ); is $res->content, "foo${path}baz", "Got app content path $path"; } }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/classes/0000775000175000017500000000000012650351107017766 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-Serializer/0000775000175000017500000000000012650351107025140 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-Serializer/with.t0000644000175000017500000001201312650351107026273 0ustar gregoagregoause strict; use warnings; use Test::More tests => 5; use Test::Fatal; use_ok('Dancer2::Core::Hook'); { package Serializer::OK; use Moo; with 'Dancer2::Core::Role::Serializer'; has '+content_type' => ( default => sub {'plain/test'} ); sub serialize {'{'.$_[1].'}'} sub deserialize {'['.$_[1].']'} } subtest 'Successful' => sub { plan tests => 5; my $srl = Serializer::OK->new; isa_ok( $srl, 'Serializer::OK' ); $srl->add_hook( Dancer2::Core::Hook->new( name => 'engine.serializer.before', code => sub { my $content = shift; ::is( $content, 'foo', 'Correct content in before hook' ); }, ) ); $srl->add_hook( Dancer2::Core::Hook->new( name => 'engine.serializer.after', code => sub { my $content = shift; ::is( $content, '{foo}', 'Correct content in after hook' ); }, ) ); is( $srl->serialize('foo'), '{foo}', 'Serializing' ); is( $srl->deserialize('bar'), '[bar]', 'Deserializing' ); }; { package Serializer::NotOK; use Moo; with 'Dancer2::Core::Role::Serializer'; has '+content_type' => ( default => sub {'plain/test'} ); sub serialize { die '+' . $_[1] . '+' } sub deserialize { die '-' . $_[1] . '-' } } subtest 'Unsuccessful' => sub { plan tests => 21; use_ok('Dancer2::Logger::Capture'); { my $logger = Dancer2::Logger::Capture->new; isa_ok( $logger, 'Dancer2::Logger::Capture' ); my $srl = Serializer::NotOK->new( log_cb => sub { $logger->log(@_) } ); isa_ok( $srl, 'Serializer::NotOK' ); is( $srl->serialize('foo'), undef, 'Serialization result' ); my $trap = $logger->trapper; isa_ok( $trap, 'Dancer2::Logger::Capture::Trap' ); my $errors = $trap->read; isa_ok( $errors, 'ARRAY' ); is( scalar @{$errors}, 1, 'One error caught' ); my $msg = $errors->[0]; isa_ok( $msg, 'HASH' ); is( scalar keys %{$msg}, 3, 'Two items in the error' ); is( $msg->{'level'}, 'core', 'Correct level' ); like( $msg->{'message'}, qr{^Failed to serialize the request: \+foo\+}, 'Correct error message', ); } { my $logger = Dancer2::Logger::Capture->new; isa_ok( $logger, 'Dancer2::Logger::Capture' ); my $srl = Serializer::NotOK->new( log_cb => sub { $logger->log(@_) } ); isa_ok( $srl, 'Serializer::NotOK' ); is( $srl->deserialize('bar'), undef, 'Deserialization result' ); my $trap = $logger->trapper; isa_ok( $trap, 'Dancer2::Logger::Capture::Trap' ); my $errors = $trap->read; isa_ok( $errors, 'ARRAY' ); is( scalar @{$errors}, 1, 'One error caught' ); my $msg = $errors->[0]; isa_ok( $msg, 'HASH' ); is( scalar keys %{$msg}, 3, 'Two items in the error' ); is( $msg->{'level'}, 'core', 'Correct level' ); like( $msg->{'message'}, qr{^Failed to deserialize the request: \-bar\-}, 'Correct error message', ); } }; { package Serializer::Generic; use Moo; with 'Dancer2::Core::Role::Serializer'; has '+content_type' => ( default => 'plain/test' ); sub serialize {1} sub deserialize {1} } subtest 'support_content_type' => sub { plan tests => 7; my $srl = Serializer::Generic->new; isa_ok( $srl, 'Serializer::Generic' ); can_ok( $srl, 'support_content_type' ); is( $srl->support_content_type(), undef, 'Empty returns undef' ); is( $srl->support_content_type('plain/foo;plain/bar'), '', 'Content type not supported', ); is( $srl->support_content_type('plain/foo;plain/test'), '', 'Content type not supported (because not first)', ); is( $srl->support_content_type('plain/test'), 1, 'Content type supported when single', ); is( $srl->support_content_type('plain/test;plain/foo'), 1, 'Content type supported when first', ); }; { package Serializer::Empty; use Moo; with 'Dancer2::Core::Role::Serializer'; has '+content_type' => ( default => 'plain/test' ); sub serialize {'BAD SERIALIZE'} sub deserialize {'BAD DESERIALIZE'} } subtest 'Called with empty content' => sub { plan tests => 6; my $srl = Serializer::Empty->new; isa_ok( $srl, 'Serializer::Empty' ); can_ok( $srl, qw ); is( $srl->serialize(), undef, 'Do not try to serialize without input', ); is( $srl->serialize(''), '', 'Do not try to serialize with empty input', ); is( $srl->deserialize(), undef, 'Do not try to deserialize without input', ); is( $srl->deserialize(''), '', 'Do not try to deserialize with empty input', ); } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Hook/0000775000175000017500000000000012650351107023030 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Hook/new.t0000644000175000017500000000264312650351107024011 0ustar gregoagregoause strict; use warnings; use Test::More tests => 12; use Test::Fatal; use_ok('Dancer2::Core::Hook'); like( exception { Dancer2::Core::Hook->new( name => 'myname' ) }, qr/^Missing required arguments: code/, 'Must provide code attribute', ); like( exception { Dancer2::Core::Hook->new( code => sub {1} ) }, qr/^Missing required arguments: name/, 'Must provide name attribute', ); is( exception { Dancer2::Core::Hook->new( name => 'myname', code => sub {1} ) }, undef, 'Can create hook with name and code', ); { my $hook = Dancer2::Core::Hook->new( name => 'before_template', code => sub { my $input = shift; ::is( $input, 'input', 'Correct input for hook' ); return 'output'; }, ); isa_ok( $hook, 'Dancer2::Core::Hook' ); can_ok( $hook, qw ); is( $hook->name, 'before_template_render', 'before_template becomes before_template_render', ); isa_ok( $hook->code, 'CODE' ); is( $hook->code->('input'), 'output', 'Hook returned proper output', ); } { my $hook = Dancer2::Core::Hook->new( name => 'CrashingHook', code => sub { die 'dying' }, ); isa_ok( $hook, 'Dancer2::Core::Hook' ); like( exception { $hook->code->() }, qr/^Hook error: dying/, 'Hook crashing caught', ); } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Request/0000775000175000017500000000000012650351107023560 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Request/new.t0000644000175000017500000003006312650351107024536 0ustar gregoagregoause strict; use warnings; use Test::More tests => 9; use Test::Fatal; use Plack::Test; use HTTP::Request::Common; use Plack::Builder; use URI::Escape; BEGIN { use_ok('Dancer2::Core::Request') } sub psgi_ok { [ 200, [], ['OK'] ] } sub test_get_params { my %exp_params = ( 'name' => 'Alexis Sukrieh', 'IRC Nickname' => 'sukria', 'Project' => 'Perl Dancer2', 'hash' => [ 2, 4 ], int1 => 1, int2 => 0, ); my $test = Plack::Test->create( sub { my $env = shift; my $request = Dancer2::Core::Request->new( env => $env ); is( $request->path, '/', 'path is set' ); is( $request->method, 'GET', 'method is set' ); ok( $request->is_get, 'method is GET' ); is_deeply( scalar( $request->params ), \%exp_params, 'params are OK', ); is( $request->params->{'name'}, 'Alexis Sukrieh', 'params accessor works', ); my %params = $request->params; is_deeply( scalar( $request->params ), \%params, 'params wantarray works', ); return psgi_ok; } ); my $request_url = '/?' . join '&', map {; my $param = $_; ref $exp_params{$param} ? map +( uri_escape($param).'='.uri_escape($_) ), @{ $exp_params{$_} } : uri_escape($_).'='.uri_escape( $exp_params{$param} ); } keys %exp_params; ok( $test->request( GET $request_url )->is_success, 'Request successful', ); } sub test_post_params { my %exp_params = ( foo => 'bar', name => 'john', hash => [ 2, 4, 6 ], ); my $test = Plack::Test->create( sub { my $env = shift; my $request = Dancer2::Core::Request->new( env => $env ); is( $request->path, '/', 'path is set' ); is( $request->method, 'POST', 'method is set' ); ok( $request->is_post, 'method is POST' ); like( $request->to_string, qr{^\[\#\d+\] POST /}, 'Request presented well as string', ); is_deeply( scalar( $request->params ), \%exp_params, 'params are OK', ); my %params = $request->params; is_deeply( scalar( $request->params ), \%params, 'params wantarray works', ); is_deeply( scalar( $request->params ), \%params, 'params wantarray works', ); return psgi_ok; } ); my $req = POST '/', \%exp_params; ok( $test->request($req)->is_success, 'Request successful', ); } sub test_mixed_params { my $test = Plack::Test->create( sub { my $env = shift; my $request = Dancer2::Core::Request->new( env => $env ); my %exp_params = ( mixed => { x => 1, y => 2, meth => 'post', }, get => { y => 2, meth => 'get', }, post => { x => 1, meth => 'post', }, ); is( $request->path, '/', 'path is set' ); is( $request->method, 'POST', 'method is set' ); is_deeply( scalar( $request->params ), $exp_params{'mixed'}, 'params are OK', ); is_deeply( scalar( $request->params('body') ), $exp_params{'post'}, 'body params are OK', ); is_deeply( scalar( $request->params('query') ), $exp_params{'get'}, 'query params are OK', ); return psgi_ok; } ); my $req = POST '/?y=2&meth=get', { x => 1, meth => 'post' }; ok( $test->request($req)->is_success, 'Request successful', ); } sub test_all_params { test_get_params; test_post_params; test_mixed_params; } subtest 'Defaults' => sub { my $test = Plack::Test->create( sub { my $env = shift; my $request = Dancer2::Core::Request->new( env => $env ); isa_ok( $request, 'Dancer2::Core::Request' ); can_ok( $request, 'env' ); isa_ok( $request->env, 'HASH' ); # http env keys my @http_env_keys = qw< accept accept_charset accept_encoding accept_language connection keep_alive referer user_agent x_requested_with >; can_ok( $request, @http_env_keys ); is( $request->$_, $request->env->{"HTTP_$_"}, "HTTP ENV key $_", ) for @http_env_keys; is( $request->agent, $request->user_agent, 'agent as alias to user_agent', ); is( $request->remote_address, $request->address, 'remote_address as alias to address', ); # variables $request->var( foo => 'bar' ); is_deeply( $request->vars, { foo => 'bar' }, 'Setting variables using DSL', ); is( $request->var('foo'), 'bar', 'Read single variable' ); $request->var( foo => 'baz' ); is_deeply( $request->vars, { foo => 'baz' }, 'Overwriting variables using vars() method', ); is( $request->var('foo'), 'baz', 'Read variable' ); is( $request->path, '/defaults', 'Default path' ); is( $request->path_info, '/defaults', 'Default path_info' ); is( $request->method, 'GET', 'Default method' ); is( $request->id, 1, 'Correct request ID' ); my %aliases = ( address => 'REMOTE_ADDR', remote_host => 'REMOTE_HOST', protocol => 'SERVER_PROTOCOL', port => 'SERVER_PORT', request_uri => 'REQUEST_URI', user => 'REMOTE_USER', script_name => 'SCRIPT_NAME', ); is( $request->$_, $request->env->{ $aliases{$_} }, "$_ derived from $aliases{$_}", ) for keys %aliases; is( $request->to_string, '[#1] GET /defaults', 'Correct to_string', ); return psgi_ok; } ); ok( $test->request( GET '/defaults' )->is_success, 'Request successful', ); }; subtest 'Create with single env' => sub { isa_ok( Dancer2::Core::Request->new( env => {} ), 'Dancer2::Core::Request', 'Create with env hash', ); my $request; isa_ok( $request = Dancer2::Core::Request->new( env => { REQUEST_METHOD => 'X' } ), 'Dancer2::Core::Request', 'Create with single argument for env', ); is( $request->method, 'X', 'env() attribute populated successfully' ); }; subtest 'Serializer' => sub { { my $request = Dancer2::Core::Request->new( env => {} ); can_ok( $request, qw ); ok( ! $request->serializer, 'No serializer set' ); } { { package Nothing; use Moo; } # The type check fails - BUILD is not called, no increment of _count. ok( exception { Dancer2::Core::Request->new( env => {}, serializer => Nothing->new, ) }, 'Cannot send random object to request as serializer', ); { package Serializer; use Moo; with 'Dancer2::Core::Role::Serializer'; sub serialize {1} sub deserialize {1} has '+content_type' => ( default => sub {1} ); } my $request; is( exception { $request = Dancer2::Core::Request->new( env => { REQUEST_METHOD => 'GET' }, serializer => Serializer->new, ) }, undef, 'Can create request with serializer', ); ok( $request->serializer, 'Serializer set' ); isa_ok( $request->serializer, 'Serializer' ); } }; subtest 'Path when mounting' => sub { my $app = builder { mount '/mount' => sub { my $env = shift; my $request = Dancer2::Core::Request->new( env => $env ); is( $request->script_name, '/mount', 'Script name when mounted (script_name)', ); is( $request->request_uri, '/mount/mounted_path', 'Correct request_uri', ); is( $request->path, '/mounted_path', 'Full path when mounted (path)', ); is( $request->path_info, '/mounted_path', 'Mounted path when mounted (path_info)', ); return psgi_ok; } }; my $test = Plack::Test->create($app); ok( $test->request( GET '/mount/mounted_path' )->is_success, 'Request successful', ); }; subtest 'Different method' => sub { my $test = Plack::Test->create( sub { my $env = shift; my $request = Dancer2::Core::Request->new( env => $env ); is( $request->method, 'PUT', 'Correct method' ); is( $request->env->{'REQUEST_METHOD'}, $request->method, 'REQUEST_METHOD derived from env', ); return psgi_ok; } ); ok( $test->request( PUT '/' )->is_success, 'Request successful', ); }; # the calling order to this method matters because it checks # how many requests were run so far subtest 'Checking request ID' => sub { my $test = Plack::Test->create( sub { my $env = shift; my $request = Dancer2::Core::Request->new( env => $env ); is( $request->id, 8, 'Correct request id' ); return psgi_ok; } ); ok( $test->request( GET '/' )->is_success, 'Request successful', ); }; subtest 'is_$method (head/post/get/put/delete/patch' => sub { foreach my $http_method ( qw ) { my $test = Plack::Test->create( sub { my $env = shift; my $request = Dancer2::Core::Request->new( env => $env ); my $method = "is_$http_method"; ok( $request->$method, $method ); return psgi_ok; } ); ok( $test->request( HTTP::Request->new( ( uc $http_method ) => '/' ) )->is_success, 'Request successful', ); } }; subtest 'Parameters (body/query/route)' => sub { note $Dancer2::Core::Request::XS_URL_DECODE ? 'Running test with XS_URL_DECODE' : 'Running test without XS_URL_DECODE'; note $Dancer2::Core::Request::XS_PARSE_QUERY_STRING ? 'Running test with XS_PARSE_QUERY_STRING' : 'Running test without XS_PARSE_QUERY_STRING'; test_all_params; if ( $Dancer2::Core::Request::XS_PARSE_QUERY_STRING ) { note 'Running test without XS_PARSE_QUERY_STRING'; $Dancer2::Core::Request::XS_PARSE_QUERY_STRING = 0; test_all_params; } if ( $Dancer2::Core::Request::XS_URL_DECODE ) { note 'Running test without XS_URL_DECODE'; $Dancer2::Core::Request::XS_URL_DECODE = 0; test_all_params; } }; # more stuff to test # special methods: # forwarded_for_address # forwarded_protocol # forwarded_host # host #subtest 'Behind proxy (host/is_behind_proxy)' => sub { # my $test = Plack::Test->create( sub { psgi_ok } ); # # ok( # $test->request( GET '/dev/null' )->is_success, # 'Different method request successful', # ); #}; #subtest 'Path resolution methods' => sub { # my $test = Plack::Test->create( sub { # my $env = shift; # my $request = Dancer2::Core::Request->new( env => $env ); # # return psgi_ok; # } ); #}; #subtest 'Upload' => sub {1}; #subtest 'Scheme' => sub {1}; #subtest 'Cookies' => sub {1}; #subtest 'Headers' => sub {1}; libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Request/serializers.t0000644000175000017500000000333312650351107026301 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; use Class::Load 'try_load_class'; { package App::CBOR; ## no critic use Dancer2; # postpone sub setup { set serializer => 'CBOR'; post '/' => sub { ::is_deeply( +{ params() }, +{}, 'Empty parameters' ); ::is( request->data, 'Foo', 'Correct data using request->data' ); return 'ok'; }; } } subtest 'Testing with CBOR' => sub { try_load_class('CBOR::XS') or plan skip_all => 'CBOR::XS is needed for this test'; try_load_class('Dancer2::Serializer::CBOR') or plan skip_all => 'Dancer2::Serializer::CBOR is needed for this test'; App::CBOR->setup; my $app = Plack::Test->create( App::CBOR->to_app ); my $res = $app->request( POST '/', Content => CBOR::XS::encode_cbor('Foo'), ); ok( $res->is_success, 'Successful response' ); is( $res->content, CBOR::XS::encode_cbor('ok'), 'Correct response', ); }; { package App::JSON; ## no critic use Dancer2; set serializer => 'JSON'; post '/' => sub { ::is_deeply( +{ params() }, +{}, 'Empty parameters' ); ::is_deeply( request->data, [ qw ], 'Correct data using request->data', ); return [ qw ]; }; } subtest 'Testing with JSON' => sub { my $app = Plack::Test->create( App::JSON->to_app ); my $res = $app->request( POST '/', Content => '["foo","bar"]', ); ok( $res->is_success, 'Successful response' ); is( $res->content, '["foo","bar"]', 'Correct response', ); }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Runner/0000775000175000017500000000000012650351107023401 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Runner/new.t0000644000175000017500000001222712650351107024361 0ustar gregoagregoause strict; use warnings; use Test::More tests => 39; use_ok('Dancer2::Core::Runner'); is( $Dancer2::runner, undef, 'No runner defined in Dancer2 yet' ); { my $runner = Dancer2::Core::Runner->new(); isa_ok( $runner, 'Dancer2::Core::Runner' ); } note 'MIME types'; { my $runner = Dancer2::Core::Runner->new(); can_ok( $runner, 'mime_type' ); isa_ok( $runner->mime_type, 'Dancer2::Core::MIME' ); } ok( $Dancer2::runner, 'Have a runner (probably) in $Dancer2::runner' ); isa_ok( $Dancer2::runner, 'Dancer2::Core::Runner', 'Runner now defined' ); note 'BUILD setting $Carp::Verbose'; { my $runner = Dancer2::Core::Runner->new(); is( $runner->config->{'traces'}, 0, 'traces not turned on (default' ); is( $Carp::Verbose, 0, 'Carp Verbose not turned on (default)' ); } { local $ENV{DANCER_TRACES} = 1; my $runner = Dancer2::Core::Runner->new(); is( $runner->config->{'traces'}, 1, 'traces turned on' ); is( $Carp::Verbose, 1, 'Carp Verbose turned on (using DANCER_TRACES)' ); } note 'server'; { my $runner = Dancer2::Core::Runner->new( host => '1.2.3.4', port => 9543, timeout => 3, ); can_ok( $runner, qw ); my $server = $runner->server; isa_ok( $server, 'HTTP::Server::PSGI' ); can_ok( $server, 'run' ); foreach my $attr ( qw ) { is( $server->{$attr}, $runner->$attr, "$attr set correctly in Server" ); } is( $server->{'server_software'}, "Perl Dancer2 " . Dancer2->VERSION, 'server_software set correctly in Server', ); } note 'Environment'; { my $runner = Dancer2::Core::Runner->new(); is( $runner->environment, 'development', 'Default environment', ); } { local $ENV{DANCER_ENVIRONMENT} = 'foo'; my $runner = Dancer2::Core::Runner->new(); is( $runner->environment, 'foo', 'Successfully set envinronment using DANCER_ENVIRONMENT', ); $runner->config->{'apphandler'} = 'Standalone'; } { local $ENV{PLACK_ENV} = 'bar'; my $runner = Dancer2::Core::Runner->new(); is( $runner->environment, 'bar', 'Successfully set environment using PLACK_ENV', ); is( $runner->config->{'apphandler'}, 'PSGI', 'apphandler set to PSGI under PLACK_ENV', ); } { local $ENV{DANCER_APPHANDLER} = 'baz'; my $runner = Dancer2::Core::Runner->new(); is( $runner->config->{'apphandler'}, 'baz', 'apphandler set via DANCER_APPHANDLER', ); } note 'Server tokens'; { my $runner = Dancer2::Core::Runner->new(); is( $runner->config->{'no_server_tokens'}, 0, 'Default no_server_tokens', ); } { local $ENV{DANCER_NO_SERVER_TOKENS} = 1; my $runner = Dancer2::Core::Runner->new(); is( $runner->config->{'no_server_tokens'}, 1, 'Successfully set no_server_tokens using DANCER_NO_SERVER_TOKENS', ); } note 'Startup info'; { my $runner = Dancer2::Core::Runner->new(); is( $runner->config->{'startup_info'}, 1, 'Default startup_info', ); } { local $ENV{DANCER_STARTUP_INFO} = 0; my $runner = Dancer2::Core::Runner->new(); is( $runner->config->{'startup_info'}, 0, 'Successfully set startup_info using DANCER_STARTUP_INFO', ); } { { package App::Fake; use Moo; has name => ( is => 'ro', default => sub {__PACKAGE__}, ); has postponed_hooks => ( is => 'ro', default => sub { +{ before => 'that', after => 'this', } }, ); } my $runner = Dancer2::Core::Runner->new(); my $app = App::Fake->new(); can_ok( $runner, qw ); is_deeply( $runner->apps, [], 'Apps are empty at first', ); is_deeply( $runner->postponed_hooks, +{}, 'No postponed hooks at first', ); $runner->register_application($app); is_deeply( $runner->apps, [$app], 'Runner registered application', ); is_deeply( $runner->postponed_hooks, { 'App::Fake' => $app->postponed_hooks }, 'Runner registered the App\'s postponed hooks', ); } { my $runner = Dancer2::Core::Runner->new(); can_ok( $runner, qw ); $runner->config->{'apphandler'} = 'PSGI'; $runner->config->{'startup_info'} = 0; my $app = $runner->start; isa_ok( $app, 'CODE' ); { package Server::Fake; sub new { bless {}, 'Server::Fake' } sub run { my ( $self, $app ) = @_; ::isa_ok( $self, 'Server::Fake' ); ::isa_ok( $app, 'CODE' ); return 'OK'; } } $runner->{'server'} = Server::Fake->new; my $res = $runner->start_server($app); is( $res, 'OK', 'start_server works' ); } { my $runner = Dancer2::Core::Runner->new(); can_ok( $runner, 'start' ); $runner->config->{'apphandler'} = 'PSGI'; my $app = $runner->start; isa_ok( $app, 'CODE' ); } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Runner/environment.t0000644000175000017500000000144212650351107026131 0ustar gregoagregoause strict; use warnings; use Test::More tests => 6; use Dancer2::Core::Runner; { my $runner = Dancer2::Core::Runner->new(); isa_ok( $runner, 'Dancer2::Core::Runner' ); is( $runner->environment, 'development', 'Default environment', ); } { local $ENV{DANCER_ENVIRONMENT} = 'foo'; my $runner = Dancer2::Core::Runner->new(); isa_ok( $runner, 'Dancer2::Core::Runner' ); is( $runner->environment, 'foo', 'Successfully set envinronment using DANCER_ENVIRONMENT', ); } { local $ENV{PLACK_ENV} = 'bar'; my $runner = Dancer2::Core::Runner->new(); isa_ok( $runner, 'Dancer2::Core::Runner' ); is( $runner->environment, 'bar', 'Successfully set environment using PLACK_ENV', ); } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Runner/psgi_app.t0000644000175000017500000000435212650351107025372 0ustar gregoagregoause strict; use warnings; use Test::More tests => 25; use Plack::Test; use HTTP::Request::Common; { package App1; use Dancer2; get '/1' => sub {1}; } { package App2; use Dancer2; get '/2' => sub {2}; } { package App3; use Dancer2; get '/3' => sub {3}; } sub is_available { my ( $cb, @apps ) = @_; foreach my $app (@apps) { is( $cb->( GET "/$app" )->content, $app, "App$app available" ); } } sub isnt_available { my ( $cb, @apps ) = @_; foreach my $app (@apps) { is( $cb->( GET "/$app" )->code, 404, "App$app is not available", ); } } note 'All Apps'; { my $app = Dancer2->psgi_app; isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; is_available( $cb, 1, 2, 3 ); }; } note 'Specific Apps by parameters'; { my @apps = @{ Dancer2->runner->apps }[ 0, 2 ]; is( scalar @apps, 2, 'Took two apps from the Runner' ); my $app = Dancer2->psgi_app(\@apps); isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; is_available( $cb, 1, 3 ); isnt_available( $cb, 2 ); }; } note 'Specific Apps via App objects'; { my $app = App2->psgi_app; isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; is_available( $cb, 2 ); isnt_available( $cb, 1, 3 ); }; }; note 'Specific apps by App names'; { my $app = Dancer2->psgi_app( [ 'App1', 'App3' ] ); isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; isnt_available( $cb, 2 ); is_available( $cb, 1, 3 ); }; } note 'Specific apps by App names with regular expression, v1'; { my $app = Dancer2->psgi_app( [ qr/^App1$/, qr/^App3$/ ] ); isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; isnt_available( $cb, 2 ); is_available( $cb, 1, 3 ); }; } note 'Specific apps by App names with regular expression, v2'; { my $app = Dancer2->psgi_app( [ qr/^App(2|3)$/ ] ); isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; isnt_available( $cb, 1 ); is_available( $cb, 2, 3 ); }; } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-Handler/0000775000175000017500000000000012650351107024404 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-Handler/with.t0000644000175000017500000000056212650351107025545 0ustar gregoagregoause strict; use warnings; use Test::More tests => 3; { package Handler; use Moo; with 'Dancer2::Core::Role::Handler'; sub register {} } my $handler = Handler->new; isa_ok( $handler, 'Handler' ); can_ok( $handler, qw ); # attributes ok( $handler->DOES('Dancer2::Core::Role::Handler'), 'Handler consumes Dancer2::Core::Role::Handler', ); libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Route/0000775000175000017500000000000012650351107023226 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Route/base.t0000644000175000017500000000341212650351107024323 0ustar gregoagregoause strict; use warnings; use Test::More; use Test::Fatal; use Dancer2::Core::Route; plan tests => 3; my @no_leading_slash = ( 'no+leading+slash', '' ); my @leading_slash = ('/+leading+slash', '/', '//' ); subtest "no prefix, paths without a leading slash" => sub { for my $string ( @no_leading_slash ) { my $route; my $exception = exception { $route = Dancer2::Core::Route->new( regexp => $string, method => 'get', code => sub {1}, ); }; is( $exception, undef, "'$string' is a valid route pattern" ); is( $route->spec_route, "/$string", "undef prefix prepends '/' to spec_route" ); } }; subtest "no prefix, paths with a leading slash" => sub { for my $string ( @leading_slash ) { my $route; my $exception = exception { $route = Dancer2::Core::Route->new( regexp => $string, method => 'get', code => sub {1}, ); }; is( $exception, undef, "'$string' is a valid route pattern" ); is( $route->spec_route, $string, "undef prefix does not prepend '/' to spec_route" ); } }; subtest "prefix and paths append" => sub { my $prefix = '/prefix'; for my $string ( @no_leading_slash, @leading_slash) { my $route; my $exception = exception { $route = Dancer2::Core::Route->new( regexp => $string, prefix => $prefix, method => 'get', code => sub {1}, ); }; is( $exception, undef, "'$prefix$string' is a valid route pattern" ); } }; libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Route/deprecated_param_keys.t0000644000175000017500000000141012650351107027720 0ustar gregoagregoause strict; use warnings; use Test::More; use Capture::Tiny 0.12 'capture_stderr'; BEGIN { use_ok('Dancer2::Core::Route') } like( capture_stderr { Dancer2::Core::Route->new( regexp => '/:splat', code => sub {1}, method => 'get', ); }, qr{^Named placeholder 'splat' is deprecated}, 'Find deprecation of :splat', ); SKIP: { skip 'Need perl >= 5.10', 1 unless $] >= 5.010; like( capture_stderr { Dancer2::Core::Route->new( regexp => '/:captures', code => sub {1}, method => 'get', ); }, qr{^Named placeholder 'captures' is deprecated}, 'Find deprecation of :captures', ); } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Route/match.t0000644000175000017500000001415012650351107024506 0ustar gregoagregoause strict; use warnings; use Test::More; use Test::Fatal; use Dancer2::Core::Request; use Dancer2::Core::Route; my @tests = ( [ [ 'get', '/', sub {11} ], '/', [ {}, 11 ] ], [ [ 'get', '/', sub {11} ], '/failure', [ undef, 11 ] ], # token tests [ [ 'get', '/hello/:name', sub {22} ], '/hello/sukria', [ { name => 'sukria' }, 22 ] ], [ [ 'get', '/hello/:name?', sub {22} ], '/hello/', [ { name => undef }, 22 ] ], # prefix tests [ [ 'get', '/', sub {33}, '/forum' ], '/forum/', [ {}, 33 ] ], [ [ 'get', '/', sub {33}, '/forum' ], '/forum/', [ {}, 33 ] ], [ [ 'get', '/mywebsite', sub {33}, '/forum' ], '/forum/mywebsite', [ {}, 33 ] ], [ [ 'get', '', sub {'concat'}, '/' ], '/', [ {}, 'concat' ] ], # token in prefix tests [ [ 'get', 'name', sub {35}, '/hello/:' ], '/hello/sukria', [ { name => 'sukria' }, 35 ], ], [ [ 'get', '/', sub {36}, '/hello/:name' ], '/hello/sukria/', [ { name => 'sukria' }, 36 ], ], # splat test [ [ 'get', '/file/*.*', sub {44} ], '/file/dist.ini', [ { splat => [ 'dist', 'ini' ] }, 44 ] ], # splat in prefix [ [ 'get', '', sub {42}, '/forum/*'], '/forum/dancer', [ { splat => [ 'dancer' ] }, 42 ] ], # megasplat test [ [ 'get', '/file/**/*', sub {44} ], '/file/some/where/42', [ { splat => [ [ 'some', 'where' ], '42' ] }, 44 ] ], # mixed (mega)splat and tokens [ [ 'get', '/some/:id/**/*', sub {55} ], '/some/where/to/run/and/hide', [ { id => 'where', splat => [ [ 'to', 'run', 'and' ], 'hide' ] }, 55 ] ], [ [ 'get', '/some/*/**/:id?', sub {55} ], '/some/one/to/say/boo/', [ { id => undef, splat => [ 'one', [ 'to', 'say', 'boo' ] ] }, 55 ] ], # supplied regex [ [ 'get', qr{stuff(\d+)}, sub {44} ], '/stuff48', [ { splat => [48] }, 44 ] ], [ [ 'get', qr{/stuff(\d+)}, sub {44}, '/foo' ], '/foo/stuff48', [ { splat => [48] }, 44 ], ], ); plan tests => 73; for my $t (@tests) { my ( $route, $path, $expected ) = @$t; if ( ref($expected) eq 'Regexp' ) { like( exception { my $r = Dancer2::Core::Route->new( method => $route->[0], regexp => $route->[1], code => $route->[2], prefix => $route->[3], ); }, $expected, "got expected exception for $path", ); } else { my $r = Dancer2::Core::Route->new( method => $route->[0], regexp => $route->[1], code => $route->[2], prefix => $route->[3], ); isa_ok $r, 'Dancer2::Core::Route'; my $request = Dancer2::Core::Request->new( env => { PATH_INFO => $path, REQUEST_METHOD => $route->[0], } ); my $m = $r->match($request); is_deeply $m, $expected->[0], "got expected data for '$path'"; { package App; use Dancer2; ## no critic } use Dancer2::Core::App; use Dancer2::Core::Response; my $app = Dancer2::Core::App->new( request => $request, response => Dancer2::Core::Response->new, ); is $r->execute($app)->content, $expected->[1], "got expected result for '$path'"; # failing request my $failing_request = Dancer2::Core::Request->new( env => { PATH_INFO => '/something_that_doesnt_exist', REQUEST_METHOD => 'GET', }, ); $m = $r->match($failing_request); is $m, undef, "dont match failing request"; } } # captures test SKIP: { skip "Need perl >= 5.10", 1 unless $] >= 5.010; ## Regexp is parsed in compile time. So, eval with QUOTES to force to parse later. my $route_regex; ## no critic eval q{ $route_regex = qr{/(? user | content | post )/(? delete | find )/(? \d+ )}x; }; ## use critic my $r = Dancer2::Core::Route->new( regexp => $route_regex, code => sub { 'ok'; }, method => 'get', ); my $request = Dancer2::Core::Request->new( env => { PATH_INFO => '/user/delete/234', REQUEST_METHOD => 'GET', }, ); my $m = $r->match($request); is_deeply $m, { captures => { class => 'user', action => 'delete', id => 234 } }, "named captures work"; } note "routes with options"; { my $route_w_options = Dancer2::Core::Route->new( method => 'get', regexp => '/', code => sub {'options'}, options => { 'agent' => 'cURL' }, ); my $req = Dancer2::Core::Request->new( path => '/', method => 'get', env => { 'HTTP_USER_AGENT' => 'mozilla' }, ); my $m = $route_w_options->match($req); ok !defined $m, 'Route did not match'; $req = Dancer2::Core::Request->new( path => '/', method => 'get', env => { 'HTTP_USER_AGENT' => 'cURL' }, ); $m = $route_w_options->match($req); ok defined $m, 'Route matched'; $route_w_options = Dancer2::Core::Route->new( method => 'get', regexp => '/', code => sub {'options'}, options => { 'agent' => 'cURL', 'content_type' => 'foo', }, ); $req = Dancer2::Core::Request->new( path => '/', method => 'get', env => { 'HTTP_USER_AGENT' => 'cURL' }, ); # Check match more than once (each iterator wasn't reset, for loop is ok ) $m = $route_w_options->match($req); ok !defined $m, 'More options - Route did not match - test 1'; $m = $route_w_options->match($req); ok !defined $m, 'More options - Route did not match - test 2'; } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Response-Delayed/0000775000175000017500000000000012650351107025273 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Response-Delayed/new.t0000644000175000017500000000351712650351107026255 0ustar gregoagregoause strict; use warnings; use Test::More tests => 18; use Dancer2::Core::Runner; use Dancer2::Core::Request; use Dancer2::Core::Response; use_ok('Dancer2::Core::Response::Delayed'); my $runner = Dancer2::Core::Runner->new; isa_ok( $runner, 'Dancer2::Core::Runner' ); $Dancer2::runner = $runner; my $request = Dancer2::Core::Request->new( env => { PATH_INFO => '/foo' }, ); isa_ok( $request, 'Dancer2::Core::Request' ); my $response = Dancer2::Core::Response->new(); isa_ok( $response, 'Dancer2::Core::Response' ); my $test = 0; my $del_res = Dancer2::Core::Response::Delayed->new( request => $request, response => $response, cb => sub { ::isa_ok( $Dancer2::Core::Route::REQUEST, 'Dancer2::Core::Request', ); ::isa_ok( $Dancer2::Core::Route::RESPONSE, 'Dancer2::Core::Response', ); ::is( $Dancer2::Core::Route::REQUEST->path, '/foo', 'Correct path in the request', ); ::isa_ok( $Dancer2::Core::Route::RESPONDER, 'CODE', 'Got a responder callback', ); $test++; $Dancer2::Core::Route::RESPONDER->('OK'); }, ); isa_ok( $del_res, 'Dancer2::Core::Response::Delayed' ); can_ok( $del_res, qw ); can_ok( $del_res, qw ); is( $del_res->is_halted, 0, 'is_halted returns no' ); is( $del_res->has_passed, 0, 'has_passed returns no' ); my $res_cb = sub { is( $_[0], 'OK', 'Correct response asynchronously' ) }; my $psgi_res = $del_res->to_psgi(); is( $test, 0, 'Callback not run yet' ); $psgi_res->($res_cb); is( $test, 1, 'Callback run' ); is $del_res->status => 200, "we can access the response header"; isa_ok( $del_res->headers, "HTTP::Headers", "Able to retrieve headers"); libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Response-Delayed/after_hooks.t0000644000175000017500000000277512650351107027775 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; use HTTP::Cookies; # Tests to ensure a delayed ( but not async ) response # still have "after" hooks called, such as for session flushing { package App::Delayed; use Dancer2; set session => 'Simple', get '/' => sub { session file => __FILE__; open my $fh, "<", __FILE__; delayed { my $responder = $Dancer2::Core::Route::RESPONDER; my $res = $Dancer2::Core::Route::RESPONSE; return $responder->( [ $res->status, $res->headers_to_array, $fh ] ); }; }; get '/file' => sub { session 'file'; }; } my $jar = HTTP::Cookies->new(); my $base = 'http://localhost'; my $test = Plack::Test->create( App::Delayed->to_app ); subtest "delayed (not async) response" => sub { my $res = $test->request( GET "$base/" ); $jar->extract_cookies($res); ok $res->is_success, 'Successful request for /'; open my $fh, "<:raw", __FILE__; my $content = do { local $/; <$fh> }; is $res->content, $content, "response returned test file content"; }; subtest "after hook flushes session headers for delayed response" => sub { my $req = GET("$base/file"); $jar->add_cookie_header($req); my $res = $test->request($req); $jar->extract_cookies($res); ok $res->is_success, 'Successful request for /file'; is $res->content, __FILE__, "Session returned test file name"; }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core/0000775000175000017500000000000012650351107022132 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core/camelize.t0000644000175000017500000000061412650351107024107 0ustar gregoagregoause strict; use warnings; use Dancer2::Core; use Test::More tests => 4; my %tests = ( 'test' => 'Test', 'class_name' => 'ClassName', 'class_nAME' => 'ClassNAME', 'class_NAME' => 'ClassNAME', ); foreach my $test ( keys %tests ) { my $value = $tests{$test}; is( Dancer2::Core::camelize($test), $value, "$test camelized as $value", ); } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2/0000775000175000017500000000000012650351107021244 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2/import-pragmas.t0000644000175000017500000000060512650351107024372 0ustar gregoagregoause strict; use Test::More tests => 1; { package App::NoWarnings; ## no critic no warnings 'misc'; # masks earlier declaration use Dancer2 ':nopragmas'; local $@ = undef; my $got_warning; local $SIG{'__WARN__'} = sub { $got_warning++; }; eval 'my $var; my $var;'; ## no critic ::is( $got_warning, undef, 'warnings pragma not activated' ); } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2/import.t0000644000175000017500000001245012650351107022743 0ustar gregoagregoause strict; use warnings; use Test::More tests => 34; use Test::Fatal; use Scalar::Util 'refaddr'; use Plack::Test; use HTTP::Request::Common; BEGIN { require Dancer2; can_ok( Dancer2::, 'runner' ); is( Dancer2::->runner, undef, 'No runner by default' ); } { package App::CreatingRunner; use Dancer2; } isa_ok( Dancer2->runner, 'Dancer2::Core::Runner', 'Runner created' ); my $runner_refaddr = refaddr( Dancer2->runner ); { package App::NotRecreatingRunner; use Dancer2; } isa_ok( Dancer2->runner, 'Dancer2::Core::Runner', 'Runner created' ); is( refaddr( Dancer2->runner ), $runner_refaddr, 'Runner not recreated' ); { { package FakeRunner; sub psgi_app { ::isa_ok( $_[0], 'FakeRunner' ); ::is( $_[1], 'psgi_param', 'psgi_app calls Runner->psgi_app' ); return 'Got it'; } } local $Dancer2::runner = bless {}, 'FakeRunner'; ::is( Dancer2->psgi_app('psgi_param'), 'Got it', 'psgi_app works as expected', ); } { package App::ScriptAllowed; require Dancer2; ::is( ::exception { Dancer2->import(':script') }, undef, ':script is allowed', ); } { package App::TestsAllowed; require Dancer2; ::is( ::exception { Dancer2->import(':tests') }, undef, ':tests is allowed', ); } { package App::SyntaxAllowed; require Dancer2; ::is( ::exception { Dancer2->import(':syntax') }, undef, ':syntax is allowed', ); } { package App::KeyPairOnly; require Dancer2; ::like( ::exception { Dancer2->import('single') }, qr{^parameters must be key/value pairs}, 'Must import key/value pairs', ); ::like( ::exception { Dancer2->import(qw) }, qr{^parameters must be key/value pairs}, 'Must import key/value pairs', ); ::is( ::exception { Dancer2->import( '!unless' ) }, undef, 'Must import key/value pairs unless prefixed by !', ); ::is( ::exception { Dancer2->import( '!unless', '!prefixed', '!bythis' ) }, undef, 'Must import key/value pairs unless prefixed by !', ); } { package App::GettingDSL; use Dancer2; ::can_ok( __PACKAGE__, qw ); } { package App::GettingSelectiveDSL; use Dancer2 '!post'; # proper way ::can_ok( __PACKAGE__, 'get' ); # checking this would work too ::ok( __PACKAGE__->can('get'), 'get imported successfully' ); ::ok( ! __PACKAGE__->can('post'), 'Can import keywords selectively' ); } { package App::Main; use Dancer2; get '/main' => sub {1}; } { package App::ComposedToMain; use Dancer2 appname => 'App::Main'; get '/alsomain' => sub {1}; } { my $runner = Dancer2->runner; isa_ok( $runner, 'Dancer2::Core::Runner' ); my $apps = $runner->apps; cmp_ok( scalar @{$apps}, '==', 12, 'Correct number of Apps created so far', ); my @names = sort map +( $_->name ), @{$apps}; # this is the list of all Apps loaded in this test is_deeply( \@names, [qw< App::CreatingRunner App::GettingDSL App::GettingSelectiveDSL App::KeyPairOnly App::Main App::NoStrictNoWarningsNoUTF8 App::NotRecreatingRunner App::ScriptAllowed App::StrictAndWarningsAndUTF8 App::SyntaxAllowed App::TestsAllowed App::WithSettingsChanged >], 'All apps accounted for', ); my $app = App::Main->to_app; isa_ok( $app, 'CODE' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/main' )->content, 1, 'Got original app response', ); is( $cb->( GET '/alsomain' )->content, 1, 'Can compose apps with appname', ); }; } { package App::WithSettingsChanged; use Dancer2; } { App::WithSettingsChanged->import( with => { layout => 'mobile' } ); my ($app) = grep +( $_->name eq 'App::WithSettingsChanged' ), @{ Dancer2->runner->{'apps'} }; ::isa_ok( $app, 'Dancer2::Core::App' ); ::is( $app->template_engine->{'layout'}, 'mobile', 'Changed settings using with keyword', ); } { package App::NoStrictNoWarningsNoUTF8; use Dancer2; no strict; no warnings; no utf8; local $@ = undef; eval '$var = 30'; ::is( $@, '', 'no strict (control test)', ); local $SIG{'__WARN__'} = sub { ::is( $_[0], undef, 'no warning (control test)', ); }; eval 'my $var; my $var;'; my $str = "щука"; ::isnt( length $str, 4, 'utf8 pragma not imported' ); } { package App::StrictAndWarningsAndUTF8; use Dancer2; local $@ = undef; local $SIG{'__WARN__'} = sub { ::ok( $_[0], 'warnings pragma imported', ); }; eval '$var = 30;'; ::like( $@, qr/^Global symbol/, 'strict pragma imported', ); eval 'my $var; my $var;'; my $str = "щука"; ::is( length $str, 4, 'utf8 pragma imported' ); } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Response/0000775000175000017500000000000012650351107023726 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Response/new_from.t0000644000175000017500000000334212650351107025727 0ustar gregoagregoause strict; use warnings; use Test::More tests => 3; use Plack::Response; use Dancer2::Core::Response; sub normalize_headers { my $headers = shift; my %headers = (); while ( my ( $key, $val ) = splice @{$headers}, 0, 2 ) { $headers{$key} = $val; } return %headers; } can_ok( Dancer2::Core::Response::, qw ); my %default_headers = ( 'Content-Type' => 'text/plain', 'X-Test' => 'Val', ); subtest 'new_from_array' => sub { plan tests => 4; my $array = [ 200, [%default_headers], ['Foo'] ]; my $response = Dancer2::Core::Response->new_from_array($array); isa_ok( $response, 'Dancer2::Core::Response' ); is( $response->status, 200, 'Correct status' ); is( $response->content, 'Foo', 'Correct content' ); # hash randomization my %headers = normalize_headers( $response->headers_to_array ); is_deeply( \%headers, \%default_headers, 'All headers correct', ); }; subtest 'new_from_plack' => sub { plan tests => 5; my $plack = Plack::Response->new(); isa_ok( $plack, 'Plack::Response' ); $plack->status(200); $plack->body('Bar'); foreach my $header_name ( keys %default_headers ) { $plack->header( $header_name => $default_headers{$header_name} ); } my $response = Dancer2::Core::Response->new_from_plack($plack); isa_ok( $response, 'Dancer2::Core::Response' ); is( $response->status, 200, 'Correct status' ); is( $response->content, 'Bar', 'Correct content' ); # hash randomization my %headers = normalize_headers( $response->headers_to_array ); is_deeply( \%headers, \%default_headers, 'All headers correct', ); }; libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Factory/0000775000175000017500000000000012650351107023537 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Factory/new.t0000644000175000017500000000070712650351107024517 0ustar gregoagregoause strict; use warnings; use Test::More tests => 5; use_ok('Dancer2::Core::Factory'); my $factory = Dancer2::Core::Factory->new; isa_ok( $factory, 'Dancer2::Core::Factory' ); can_ok( $factory, 'create' ); my $template = Dancer2::Core::Factory->create( 'template', 'template_toolkit', layout => 'mylayout' ); isa_ok( $template, 'Dancer2::Template::TemplateToolkit' ); is( $template->{'layout'}, 'mylayout', 'Correct layout set in the template' ); libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-StandardResponses/0000775000175000017500000000000012650351107026471 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-StandardResponses/with.t0000644000175000017500000000575412650351107027642 0ustar gregoagregoause strict; use warnings; use Test::More tests => 24; { package Handler; use Moo; with 'Dancer2::Core::Role::StandardResponses'; } { package App; use Moo; has response => ( is => 'ro', default => sub { Response->new } ); } { package Response; use Moo; has status => (is => 'ro', reader => '_status'); has header => (is => 'ro', reader => '_header'); sub status { shift->_status->(@_) } sub header { shift->_header->(@_) } } note 'Checking our fake app'; { my $app = App->new; isa_ok( $app, 'App' ); can_ok( $app, 'response' ); isa_ok( $app->response, 'Response' ); } note 'Checking our fake response'; { my $response = Response->new( status => sub { my ( $self, $input ) = @_; ::isa_ok( $self, 'Response' ); ::is( $input, 'calling status', 'status called' ); return 'foo'; }, header => sub { my ( $self, $input ) = @_; ::isa_ok( $self, 'Response' ); ::is( $input, 'calling header', 'header called' ); return qw; }, ); isa_ok( $response, 'Response' ); is_deeply( [ $response->status('calling status') ], [ 'foo' ], 'status() works', ); is_deeply( [ $response->header('calling header') ], [ qw ], 'header() works', ); } my $handler = Handler->new; isa_ok( $handler, 'Handler' ); can_ok( $handler, qw ); note '->response'; { # set up status and header my $app = App->new( response => Response->new( status => sub { my ( $self, $code ) = @_; ::isa_ok( $self, 'Response' ); ::is( $code, '400', 'Correct status code' ); }, header => sub { my ( $self, $hdr_name, $hdr_content ) = @_; ::isa_ok( $self, 'Response' ); ::is( $hdr_name, 'Content-Type', 'Correct header name' ); ::is( $hdr_content, 'text/plain', 'Correct header value' ); }, ) ); is( $handler->response( $app, 400, 'Some Message' ), 'Some Message', 'Correct response created', ); } note '->standard_response'; { # set up status and header my $app = App->new( response => Response->new( status => sub { my ( $self, $code ) = @_; ::isa_ok( $self, 'Response' ); ::is( $code, '400', 'Correct status code' ); }, header => sub { my ( $self, $hdr_name, $hdr_content ) = @_; ::isa_ok( $self, 'Response' ); ::is( $hdr_name, 'Content-Type', 'Correct header name' ); ::is( $hdr_content, 'text/plain', 'Correct header value' ); }, ) ); is( $handler->standard_response( $app, 400 ), 'Bad Request', 'Correct response 400 created', ); } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/0000775000175000017500000000000012650351107025233 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/0000775000175000017500000000000012650351107027655 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/0000775000175000017500000000000012650351107030423 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/0000775000175000017500000000000012650351107031331 5ustar gregoagregoa././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootlibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/inner/libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/in0000775000175000017500000000000012650351107031660 5ustar gregoagregoa././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootlibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/inner/dir/libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/in0000775000175000017500000000000012650351107031660 5ustar gregoagregoa././@LongLink0000644000000000000000000000016400000000000011604 Lustar rootrootlibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/inner/dir/.existslibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/in0000644000175000017500000000000012650351107031646 0ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/bin/0000775000175000017500000000000012650351107030425 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/bin/.exists0000644000175000017500000000000012650351107031731 0ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/0000775000175000017500000000000012650351107030565 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/lib/0000775000175000017500000000000012650351107031333 5ustar gregoagregoa././@LongLink0000644000000000000000000000016000000000000011600 Lustar rootrootlibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/lib/fakescript.pllibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/lib/fa0000644000175000017500000000000012650351107031630 0ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/bin/0000775000175000017500000000000012650351107031335 5ustar gregoagregoa././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootlibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/bin/.existslibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/blib/bin/.e0000644000175000017500000000000012650351107031546 0ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/0000775000175000017500000000000012650351107030016 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/.dancer0000644000175000017500000000000012650351107031237 0ustar gregoagregoa././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootlibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/fakescript.pllibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/fakescript0000644000175000017500000000000012650351107032060 0ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-HasLocation/with.t0000644000175000017500000000435612650351107026401 0ustar gregoagregoause strict; use warnings; use File::Spec; use File::Basename; use Test::More tests => 11; { package App; use Moo; with 'Dancer2::Core::Role::HasLocation'; } note 'Defaults:'; { my $app = App->new(); isa_ok( $app, 'App' ); can_ok( $app, qw ); # attributes can_ok( $app, '_build_location' ); # methods ok( $app->DOES('Dancer2::Core::Role::HasLocation'), 'App consumes Dancer2::Core::Role::HasLocation', ); my $path = File::Spec->catfile(qw< t classes Dancer2-Core-Role-HasLocation with.t >); is( File::Spec->canonpath( $app->caller ), $path, 'Default caller', ); } my $basedir = dirname( File::Spec->rel2abs(__FILE__) ); note 'With lib/ and bin/:'; { my $app = App->new( caller => File::Spec->catfile( $basedir, qw ) ); isa_ok( $app, 'App' ); my $location = $app->location; $location =~ s/\/$//; my $path = File::Spec->rel2abs( File::Spec->catdir( File::Spec->curdir, qw, ) ); is( $location, $path, 'Got correct location with lib/ and bin/', ); } note 'With .dancer file:'; { my $app = App->new( caller => File::Spec->catfile( $basedir, qw ) ); isa_ok( $app, 'App' ); my $location = $app->location; my $path = File::Spec->rel2abs( File::Spec->catdir( File::Spec->curdir, qw, ) ); is( $location, $path, 'Got correct location with .dancer file' ); } note 'blib/ ignored:'; { my $app = App->new( caller => File::Spec->catfile( $basedir, qw ) ); isa_ok( $app, 'App' ); my $location = $app->location; $location =~ s/\/$//; my $path = File::Spec->rel2abs( File::Spec->catdir( File::Spec->curdir, qw, ) ); is( $location, $path, 'blib/ dir is ignored' ); } libdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-Engine/0000775000175000017500000000000012650351107024234 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/classes/Dancer2-Core-Role-Engine/with.t0000644000175000017500000000070512650351107025374 0ustar gregoagregoause strict; use warnings; use Test::More tests => 4; { package App; use Moo; with 'Dancer2::Core::Role::Engine'; sub hook_aliases { +{} } sub supported_hooks {} } my $app = App->new; isa_ok( $app, 'App' ); can_ok( $app, qw ); # attributes can_ok( $app, qw ); # methods ok( $app->DOES('Dancer2::Core::Role::Hookable'), 'App consumes Dancer2::Core::Role::Hookable', ); libdancer2-perl-0.166001+dfsg.orig/t/session_hooks.t0000644000175000017500000001314112650351107021402 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Cookies; use HTTP::Request::Common; my @hooks_to_test = qw( engine.session.before_retrieve engine.session.after_retrieve engine.session.before_create engine.session.after_create engine.session.before_destroy engine.session.after_destroy engine.session.before_flush engine.session.after_flush ); # we'll set a flag here when each hook is called. Then our test will then verify this my $test_flags = {}; { package App; use Dancer2; set( show_errors => 1, envoriment => 'production' ); setting( session => 'Simple' ); for my $hook (@hooks_to_test) { hook $hook => sub { $test_flags->{$hook} ||= 0; $test_flags->{$hook}++; } } get '/set_session' => sub { session foo => 'bar'; #setting causes a session flush return "ok"; }; get '/get_session' => sub { ::is session->read('foo'), 'bar', "Got the right session back"; return "ok"; }; get '/destroy_session' => sub { app->destroy_session; return "ok"; }; #setup each hook again and test whether they return the correct type #there is unfortunately quite some duplication here. hook 'engine.session.before_create' => sub { my ($response) = @_; ::isa_ok( $response, 'Dancer2::Core::Session' ); }; hook 'engine.session.after_create' => sub { my ($response) = @_; ::isa_ok( $response, 'Dancer2::Core::Session' ); }; hook 'engine.session.after_retrieve' => sub { my ($response) = @_; ::isa_ok( $response, 'Dancer2::Core::Session' ); }; } my $test = Plack::Test->create( App->to_app ); my $jar = HTTP::Cookies->new; my $url = "http://localhost"; is_deeply( $test_flags, {}, 'Make sure flag hash is clear' ); subtest set_session => sub { my $res = $test->request( GET "$url/set_session" ); is $res->content, "ok", "set_session ran ok"; $jar->extract_cookies($res); }; # we verify whether the hooks were called correctly. subtest 'verify hooks for session create and session flush' => sub { is $test_flags->{'engine.session.before_create'}, 1, "session.before_create called"; is $test_flags->{'engine.session.after_create'}, 1, "session.after_create called"; is $test_flags->{'engine.session.before_flush'}, 1, "session.before_flush called"; is $test_flags->{'engine.session.after_flush'}, 1, "session.after_flush called"; is $test_flags->{'engine.session.before_retrieve'}, undef, "session.before_retrieve not called"; is $test_flags->{'engine.session.after_retrieve'}, undef, "session.after_retrieve not called"; is $test_flags->{'engine.session.before_destroy'}, undef, "session.before_destroy not called"; is $test_flags->{'engine.session.after_destroy'}, undef, "session.after_destroy not called"; }; subtest 'verify Handler::File (static content) does not retrieve session' => sub { my $req = GET "$url/file.txt"; $jar->add_cookie_header($req); my $res = $test->request($req); $jar->extract_cookies($res); # These should not change from previous subtest is $test_flags->{'engine.session.before_create'}, 1, "session.before_create not called"; is $test_flags->{'engine.session.after_create'}, 1, "session.after_create not called"; is $test_flags->{'engine.session.before_retrieve'}, undef, "session.before_retrieve not called"; is $test_flags->{'engine.session.after_retrieve'}, undef, "session.after_retrieve not called"; }; subtest get_session => sub { my $req = GET "$url/get_session"; $jar->add_cookie_header($req); my $res = $test->request($req); is $res->content, "ok", "get_session ran ok"; $jar->extract_cookies($res); }; subtest 'verify hooks for session retrieve' => sub { is $test_flags->{'engine.session.before_retrieve'}, 1, "session.before_retrieve called"; is $test_flags->{'engine.session.after_retrieve'}, 1, "session.after_retrieve called"; is $test_flags->{'engine.session.before_create'}, 1, "session.before_create not called"; is $test_flags->{'engine.session.after_create'}, 1, "session.after_create not called"; is $test_flags->{'engine.session.before_flush'}, 1, "session.before_flush not called"; is $test_flags->{'engine.session.after_flush'}, 1, "session.after_flush not called"; is $test_flags->{'engine.session.before_destroy'}, undef, "session.before_destroy not called"; is $test_flags->{'engine.session.after_destroy'}, undef, "session.after_destroy not called"; }; subtest destroy_session => sub { my $req = GET "$url/destroy_session"; $jar->add_cookie_header($req); my $res = $test->request($req); is $res->content, "ok", "destroy_session ran ok"; }; subtest 'verify session destroy hooks' => sub { is $test_flags->{'engine.session.before_destroy'}, 1, "session.before_destroy called"; is $test_flags->{'engine.session.after_destroy'}, 1, "session.after_destroy called"; #not sure if before and after retrieve should be called when the session is destroyed. But this happens. is $test_flags->{'engine.session.before_retrieve'}, 2, "session.before_retrieve called"; is $test_flags->{'engine.session.after_retrieve'}, 2, "session.after_retrieve called"; is $test_flags->{'engine.session.before_create'}, 1, "session.before_create not called"; is $test_flags->{'engine.session.after_create'}, 1, "session.after_create not called"; is $test_flags->{'engine.session.before_flush'}, 1, "session.before_flush not called"; is $test_flags->{'engine.session.after_flush'}, 1, "session.after_flush not called"; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/0000775000175000017500000000000012650351107021207 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/template_tiny/03_samples.t0000644000175000017500000000461712650351107023350 0ustar gregoagregoa#!/usr/bin/env perl use strict; BEGIN { $| = 1; $^W = 1; } use vars qw{$VAR1 $VAR2}; use Test::More; use File::Spec::Functions ':ALL'; use Dancer2::Template::Implementation::ForkedTiny (); use FindBin qw($Bin); my $SAMPLES = catdir( $Bin, 'samples' ); unless ( -d $SAMPLES ) { die("Failed to find samples directory"); } opendir( DIR, $SAMPLES ) or die("opendir($SAMPLES): $!"); my @TEMPLATES = sort grep {/\.tt$/} readdir(DIR); closedir(DIR) or die("closedir($SAMPLES): $!"); plan( tests => scalar(@TEMPLATES) * 6 ); # Test the test classes #SCOPE: { # my $false = bless { }, 'False'; # my $string = $false . ''; # is( $string, 'Hello', 'False objects return ok as a string' ); # is( !!$false, '', 'False objects returns false during bool' ); #} ###################################################################### # Main Tests foreach my $template (@TEMPLATES) { $template =~ s/\.tt$//; my $file = catfile( $SAMPLES, $template ); my $tt_file = "$file.tt"; my $var_file = "$file.var"; my $txt_file = "$file.txt"; ok( -f $tt_file, "$template: Found $tt_file" ); ok( -f $txt_file, "$template: Found $txt_file" ); ok( -f $var_file, "$template: Found $var_file" ); # Load the resources my $tt = slurp($tt_file); my $var = slurp($var_file); my $txt = slurp($txt_file); eval $var; die $@ if $@; is( ref($VAR1), 'HASH', "$template: Loaded stash from file" ); # Create the processor normally my %params = ( INCLUDE_PATH => $SAMPLES, ); %params = ( %params, %$VAR2 ) if $VAR2; my $template = Dancer2::Template::Implementation::ForkedTiny->new(%params); isa_ok( $template, 'Dancer2::Template::Implementation::ForkedTiny' ); # Execute the template $template->process( \$tt, $VAR1, \my $out ); is( $out, $txt, "$template: Output matches expected" ); } sub slurp { my $f = shift; local $/ = undef; open( VAR, $f ) or die("open($f): $!"); my $buffer = ; close VAR; return $buffer; } ###################################################################### # Support Classes for object tests SCOPE: { package UpperCase; sub foo { uc $_[0]->{foo}; } 1; } SCOPE: { package False; use overload 'bool' => sub {0}; use overload '""' => sub {'Hello'}; 1; } SCOPE: { package Private; sub public {'foo'} sub _private {'foo'} 1; } libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/04_compat.t0000644000175000017500000000424112650351107023161 0ustar gregoagregoa#!/usr/bin/env perl use strict; BEGIN { $| = 1; $^W = 1; } use vars qw{$VAR1 $VAR2}; use Test::More; use File::Spec::Functions ':ALL'; eval "require Template"; if ($@) { plan( skip_all => 'Template Toolkit is not installed' ); } use FindBin qw($Bin); my $SAMPLES = catdir( $Bin, 'samples' ); unless ( -d $SAMPLES ) { die("Failed to find samples directory"); } opendir( DIR, $SAMPLES ) or die("opendir($SAMPLES): $!"); my @TEMPLATES = sort grep {/\.tt$/} readdir(DIR); closedir(DIR) or die("closedir($SAMPLES): $!"); plan( tests => scalar(@TEMPLATES) * 7 ); ###################################################################### # Main Tests foreach my $name (@TEMPLATES) { $name =~ s/\.tt$//; my $file = catfile( $SAMPLES, $name ); my $tt_file = "$file.tt"; my $var_file = "$file.var"; my $txt_file = "$file.txt"; ok( -f $tt_file, "$name: Found $tt_file" ); ok( -f $txt_file, "$name: Found $txt_file" ); ok( -f $var_file, "$name: Found $var_file" ); # Load the resources my $tt = slurp($tt_file); my $var = slurp($var_file); my $txt = slurp($txt_file); eval $var; die $@ if $@; is( ref($VAR1), 'HASH', "$name: Loaded stash from file" ); # Create the template processor my %params = ( INCLUDE_PATH => $SAMPLES, ); %params = ( %params, %$VAR2 ) if $VAR2; my $template = Template->new(%params); isa_ok( $template, 'Template' ); # Execute the template my $out = ''; ok( $template->process( \$tt, $VAR1, \$out ), "$name: ->process returns true" ); is( $out, $txt, "$name: Output matches expected" ); } sub slurp { my $f = shift; local $/ = undef; open( VAR, $f ) or die("open($f): $!"); my $buffer = ; close VAR; return $buffer; } ###################################################################### # Support Classes for object tests SCOPE: { package UpperCase; sub foo { uc $_[0]->{foo}; } 1; } SCOPE: { package False; use overload 'bool' => sub {0}; use overload '""' => sub {'Hello'}; 1; } SCOPE: { package Private; sub public {'foo'} sub _private {'foo'} 1; } libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/01_compile.t0000644000175000017500000000023312650351107023320 0ustar gregoagregoa#!/usr/bin/env perl use strict; BEGIN { $| = 1; $^W = 1; } use Test::More tests => 1; use_ok('Dancer2::Template::Implementation::ForkedTiny'); libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/05_preparse.t0000644000175000017500000000220112650351107023512 0ustar gregoagregoa#!/usr/bin/env perl use strict; BEGIN { $| = 1; $^W = 1; } use Test::More tests => 6; use Dancer2::Template::Implementation::ForkedTiny (); sub preprocess { my $template = $_[0]; my $expected = $_[1]; my $message = $_[2] || 'Template preprocessd ok'; my $prepared = Dancer2::Template::Implementation::ForkedTiny->new->preprocess( $template); is( $prepared, $expected, $message ); is( $template, $_[0], '->proprocess does not modify original template variable' ); } ###################################################################### # Main Tests preprocess( <<'END_TEMPLATE', <<'END_EXPECTED', 'Simple IF' ); foo [% IF foo %] foobar [% END %] bar END_TEMPLATE foo [% I1 foo %] foobar [% I1 %] bar END_EXPECTED preprocess( <<'END_TEMPLATE', <<'END_EXPECTED', 'Simple UNLESS' ); foo [% UNLESS foo %] foobar [% END %] bar END_TEMPLATE foo [% U1 foo %] foobar [% U1 %] bar END_EXPECTED preprocess( <<'END_TEMPLATE', <<'END_EXPECTED', 'Simple FOREACH' ); foo [% FOREACH element IN lists %] foobar [% END %] bar END_TEMPLATE foo [% F1 element IN lists %] foobar [% F1 %] bar END_EXPECTED libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/0000775000175000017500000000000012650351107022653 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/03_chomp.tt0000644000175000017500000000015212650351107024630 0ustar gregoagregoafoo[%- a -%]bar foo [%- a -%] bar foo [% a %] bar foo [%- a %] bar foo [% a -%] bar foo [%- a -%] bar libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/02_null.tt0000644000175000017500000000004012650351107024467 0ustar gregoagregoaa[% foo %]b[% bar %]c[% foo %]d libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/07_nesting.tt0000644000175000017500000000033612650351107025201 0ustar gregoagregoa[% IF true %] one [% END %] [% IF false %] two [% END %] [% IF true %] [% IF true %] three [% END %] [% IF false %] four [% END %] [% END %] [% IF true %] five [% END %] [% IF false %] six [% END %]libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/09_trim.tt0000644000175000017500000000001612650351107024502 0ustar gregoagregoa Hello World! libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/02_null.var0000644000175000017500000000005212650351107024633 0ustar gregoagregoa$VAR1 = { 'foo' => '', }; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/05_condition.txt0000644000175000017500000000005212650351107025701 0ustar gregoagregoaWorld! Hello! Hello! Hello World! foo FOO libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/01_hello.var0000644000175000017500000000006012650351107024762 0ustar gregoagregoa$VAR1 = { 'foo' => 'World' }; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/02_null.txt0000644000175000017500000000000512650351107024660 0ustar gregoagregoaabcd libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/04_nested.txt0000644000175000017500000000002212650351107025171 0ustar gregoagregoab 1 2 1 4 9 bar libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/06_object.tt0000644000175000017500000000017712650351107025002 0ustar gregoagregoa[% foo.foo %] [% bar %] [% IF bar %]true[% ELSE %]false[% END %] public = '[% baz.public %]' private = '[% baz._private %]' libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/04_nested.var0000644000175000017500000000034112650351107025146 0ustar gregoagregoa$VAR1 = { a => 'b', foo => { one => 1, two => 2, three => [ 1, 4, 9 ], _private => 'secret', }, bar => [ { foo => 'bar', }, ], }; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/09_trim.var0000644000175000017500000000004312650351107024643 0ustar gregoagregoa$VAR1 = {}; $VAR2 = { TRIM => 1 }; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/01_hello.tt0000644000175000017500000000012712650351107024625 0ustar gregoagregoaHello [% foo %]! Hello [%foo%]! Hello [% foo %]! Hello [% foo %]! Hello [% foo %]! libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/08_foreach.txt0000644000175000017500000000014112650351107025324 0ustar gregoagregoaPeople bar: Adam Kennedy Foo Cool People: Adam Kennedy Done! libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/06_object.var0000644000175000017500000000024612650351107025140 0ustar gregoagregoa$VAR1 = { foo => bless( { foo => 'bar' }, 'UpperCase' ), bar => bless( { }, 'False' ), baz => bless( { }, 'Private' ), }; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/07_nesting.var0000644000175000017500000000005512650351107025340 0ustar gregoagregoa$VAR1 = { true => 1, false => 0, }; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/05_condition.var0000644000175000017500000000010112650351107025645 0ustar gregoagregoa$VAR1 = { 'foo' => 1, 'bar' => 0, }; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/08_foreach.var0000644000175000017500000000044012650351107025277 0ustar gregoagregoa$VAR1 = { foo => 'bar', list => [ { name => 'Adam Kennedy', email => 'adamk@cpan.org', cool => 1, }, { name => 'Foo', email => 'No Fixed Address', cool => 0, }, ], }; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/01_hello.txt0000644000175000017500000000010112650351107025005 0ustar gregoagregoaHello World! Hello World! Hello World! Hello World! Hello World! libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/07_nesting.txt0000644000175000017500000000004712650351107025370 0ustar gregoagregoa one three five libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/03_chomp.txt0000644000175000017500000000006312650351107025021 0ustar gregoagregoafoobar foo bar foo bar foo bar foo bar foobar libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/03_chomp.var0000644000175000017500000000001512650351107024767 0ustar gregoagregoa$VAR1 = { }; libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/09_trim.txt0000644000175000017500000000001412650351107024670 0ustar gregoagregoaHello World!libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/08_foreach.tt0000644000175000017500000000030512650351107025136 0ustar gregoagregoaPeople [% foo %]: [% FOREACH item IN list %] [%- item.name %] <[% item.email %]> [% END -%] Cool People: [% FOREACH item IN list %] [%- IF item.cool %] [%- item.name %] [% END %] [%- END -%] Done! libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/06_object.txt0000644000175000017500000000005512650351107025165 0ustar gregoagregoaBAR Hello false public = 'foo' private = '' libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/05_condition.tt0000644000175000017500000000034612650351107025517 0ustar gregoagregoa [%- IF foo %]World[% END %]! Hello[% IF bar %] World[% END %]! Hello[% UNLESS foo %] World[% END %]! Hello[% UNLESS bar %] World[% END %]! [% IF foo -%] foo [%- ELSE -%] bar [%- END -%] [% IF bar %] BAR [% ELSE %] FOO [% END -%] libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/samples/04_nested.tt0000644000175000017500000000025312650351107025007 0ustar gregoagregoa[% a %] [% foo.one %] [% foo.two %] [% foo.three.0 %] [% foo.three.1 %] [% foo.three.2 %] [% foo._private %] [% bar.0.foo %] [% bar.bad %] libdancer2-perl-0.166001+dfsg.orig/t/template_tiny/02_trivial.t0000644000175000017500000000130012650351107023337 0ustar gregoagregoa#!/usr/bin/env perl use strict; BEGIN { $| = 1; $^W = 1; } use Test::More tests => 1; use Dancer2::Template::Implementation::ForkedTiny (); sub process { my $stash = shift; my $input = shift; my $expected = shift; my $message = shift || 'Template processed ok'; my $output = ''; Dancer2::Template::Implementation::ForkedTiny->new->process( \$input, $stash, \$output ); is( $output, $expected, $message ); } ###################################################################### # Main Tests process( { foo => 'World' }, <<'END_TEMPLATE', <<'END_EXPECTED', 'Trivial ok' ); Hello [% foo %]! END_TEMPLATE Hello World! END_EXPECTED libdancer2-perl-0.166001+dfsg.orig/t/types.t0000644000175000017500000001134412650351107017663 0ustar gregoagregoause strict; use warnings; use Test::More tests => 46; use Test::Fatal; use Dancer2::Core::Types; ok( exception { Str->(undef) }, 'Str does not accept undef value', ); is( exception { Str->('something') }, undef, 'Str', ); like( exception { Str->( { foo => 'something' } ) }, qr{HASH\(\w+\) is not a string}, 'Str', ); is( exception { Num->(34) }, undef, 'Num', ); ok( exception { Num->(undef) }, 'Num does not accept undef value', ); like( exception { Num->('not a number') }, qr{(?i:not a number is not a Number)}, 'Num fail', ); is( exception { Bool->(1) }, undef, 'Bool true value', ); is( exception { Bool->(0) }, undef, 'Bool false value', ); is( exception { Bool->(undef) }, undef, 'Bool does accepts undef value', ); like( exception { Bool->('2') }, qr{2 is not a Boolean}, 'Bool fail', ); is( exception { RegexpRef->(qr{.*}) }, undef, 'Regexp', ); like( exception { RegexpRef->('/.*/') }, qr{\Q/.*/\E is not a RegexpRef}, 'Regexp fail', ); ok( exception { RegexpRef->(undef) }, 'Regexp does not accept undef value', ); is( exception { HashRef->( { goo => 'le' } ) }, undef, 'HashRef', ); like( exception { HashRef->('/.*/') }, qr{\Q/.*/\E is not a HashRef}, 'HashRef fail', ); ok( exception { HashRef->(undef) }, 'HashRef does not accept undef value', ); is( exception { ArrayRef->( [ 1, 2, 3, 4 ] ) }, undef, 'ArrayRef', ); like( exception { ArrayRef->('/.*/') }, qr{\Q/.*/\E is not an ArrayRef}, 'ArrayRef fail', ); ok( exception { ArrayRef->(undef) }, 'ArrayRef does not accept undef value', ); is( exception { CodeRef->( sub {44} ); }, undef, 'CodeRef', ); like( exception { CodeRef->('/.*/') }, qr{\Q/.*/\E is not a CodeRef}, 'CodeRef fail', ); ok( exception { CodeRef->(undef) }, 'CodeRef does not accept undef value', ); { package InstanceChecker::zad7; use Moo; use Dancer2::Core::Types; has foo => ( is => 'ro', isa => InstanceOf ['Foo'] ); } is( exception { InstanceChecker::zad7->new( foo => bless {}, 'Foo' ) }, undef, 'InstanceOf', ); like( exception { InstanceChecker::zad7->new( foo => bless {}, 'Bar' ) }, qr{Bar=HASH\(\w+\) is not an instance of the class: Foo}, 'InstanceOf fail', ); ok( exception { InstanceOf('Foo')->(undef) }, 'InstanceOf does not accept undef value', ); is( exception { Dancer2Prefix->('/foo') }, undef, 'Dancer2Prefix', ); like( exception { Dancer2Prefix->('bar/something') }, qr{bar/something is not a Dancer2Prefix}, 'Dancer2Prefix fail', ); # see Dancer2Prefix definition, undef is a valid value like( exception { Dancer2Prefix->(undef) }, qr/undef is not a Dancer2Prefix/, 'Dancer2Prefix does not accept undef value', ); is( exception { Dancer2AppName->('Foo') }, undef, 'Dancer2AppName', ); is( exception { Dancer2AppName->('Foo::Bar') }, undef, 'Dancer2AppName', ); is( exception { Dancer2AppName->('Foo::Bar::Baz') }, undef, 'Dancer2AppName', ); like( exception { Dancer2AppName->('Foo:Bar') }, qr{Foo:Bar is not a Dancer2AppName}, 'Dancer2AppName fails with single colons', ); like( exception { Dancer2AppName->('Foo:::Bar') }, qr{Foo:::Bar is not a Dancer2AppName}, 'Dancer2AppName fails with tripe colons', ); like( exception { Dancer2AppName->('7Foo') }, qr{7Foo is not a Dancer2AppName}, 'Dancer2AppName fails with beginning number', ); like( exception { Dancer2AppName->('Foo::45Bar') }, qr{Foo::45Bar is not a Dancer2AppName}, 'Dancer2AppName fails with beginning number', ); like( exception { Dancer2AppName->('-F') }, qr{-F is not a Dancer2AppName}, 'Dancer2AppName fails with special character', ); like( exception { Dancer2AppName->('Foo::-') }, qr{Foo::- is not a Dancer2AppName}, 'Dancer2AppName fails with special character', ); like( exception { Dancer2AppName->('Foo^') }, qr{\QFoo^\E is not a Dancer2AppName}, 'Dancer2AppName fails with special character', ); ok( exception { Dancer2AppName->(undef) }, 'Dancer2AppName does not accept undef value', ); like( exception { Dancer2AppName->('') }, qr{Empty string is not a Dancer2AppName}, 'Dancer2AppName fails an empty string value', ); is( exception { Dancer2Method->('post') }, undef, 'Dancer2Method', ); like( exception { Dancer2Method->('POST') }, qr{POST is not a Dancer2Method}, 'Dancer2Method fail', ); ok( exception { Dancer2Method->(undef) }, 'Dancer2Method does not accept undef value', ); is( exception { Dancer2HTTPMethod->('POST') }, undef, 'Dancer2HTTPMethod', ); like( exception { Dancer2HTTPMethod->('post') }, qr{post is not a Dancer2HTTPMethod}, 'Dancer2HTTPMethod fail', ); ok( exception { Dancer2HTTPMethod->(undef) }, 'Dancer2Method does not accept undef value', ); libdancer2-perl-0.166001+dfsg.orig/t/roles/0000775000175000017500000000000012650351107017455 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/roles/hook.t0000644000175000017500000000263112650351107020602 0ustar gregoagregoause strict; use warnings; use Test::More tests => 8; use Test::Fatal; use Dancer2::Core::Hook; my $h = Dancer2::Core::Hook->new( name => 'before_template', code => sub {'BT'} ); is $h->name, 'before_template_render'; is $h->code->(), 'BT'; { package Foo; use Moo; with 'Dancer2::Core::Role::Hookable'; sub hook_aliases { +{} } sub supported_hooks {'foobar'} } my $f = Foo->new; like( exception { $f->execute_hook() }, qr{execute_hook needs a hook name}, 'execute_hook needs a hook name', ); my $count = 0; my $some_hook = Dancer2::Core::Hook->new( name => 'foobar', code => sub { $count++; } ); ok( !exception { $f->add_hook($some_hook) }, 'Supported hook can be installed', ); like( exception { $f->add_hook( Dancer2::Core::Hook->new( name => 'unknown_hook', code => sub { $count++; } ) ); }, qr{Unsupported hook 'unknown_hook'}, 'Unsupported hook cannot be installed', ); $f->execute_hook('foobar'); is $count, 1; like( exception { $f->replace_hook( 'doesnotexist', [] ) }, qr{Hook 'doesnotexist' must be installed first}, 'Nonexistent hook fails', ); my $new_hooks = [ sub { $count-- }, sub { $count-- }, sub { $count-- } ]; $f->replace_hook( 'foobar', $new_hooks ); $f->execute_hook('foobar'); is $count, -2, 'replaced hooks were installed and executed'; libdancer2-perl-0.166001+dfsg.orig/t/template_simple.t0000644000175000017500000000526512650351107021710 0ustar gregoagregoause Test::More tests => 9; use strict; use warnings; use Dancer2::FileUtils 'path'; use Dancer2::Template::Simple; { package Foo; use Moo; has x => ( is => 'rw'); has y => ( is => 'rw'); sub method { "yeah" } } # variable interpolation, with file-based template my $engine = Dancer2::Template::Simple->new; my $template = path('t', 'views', 'template_simple_index.tt'); my $result = $engine->render( $template, { var1 => "xxx", var2 => "yyy", foo => 'one', bar => 'two', baz => 'three'}); my $expected = 'this is var1="xxx" and var2=yyy'."\n\nanother line\n\n one two three\n\nxxx/xxx\n"; is $result, $expected, "template got processed successfully"; # variable interpolation, with scalar-based template $expected = "one=1, two=2, three=3 - 77"; $template = "one=<% one %>, two=<% two %>, three=<% three %> - <% hash.key %>"; eval { $engine->render($template, { one => 1, two => 2, three => 3}) }; like $@, qr/Can't open .* using mode '<'/, "prototype failure detected"; $result = $engine->render(\$template, { one => 1, two => 2, three => 3, hash => { key => 77 }, }); is $result, $expected, "processed a template given as a scalar ref"; # complex variable interpolation (object, coderef and hash) my $foo = Foo->new; $foo->x(42); $template = 'foo->x == <% foo.x %> foo.method == <% foo.method %> foo.dumb=\'<% foo.dumb %>\''; $expected = 'foo->x == 42 foo.method == yeah foo.dumb=\'\''; $result = $engine->render(\$template, { foo => $foo }); is $result, $expected, 'object are interpolated in templates'; $template = 'code = <% code %>, code <% hash.code %>'; $expected = 'code = 42, code 42'; $result = $engine->render(\$template, { code => sub { 42 }, hash => { code => sub { 42 } } }); is $result, $expected, 'code ref are interpolated in templates'; $template = 'array: <% array %>, hash.array: <% hash.array %>'; $expected = 'array: 1 2 3 4 5, hash.array: 6 7 8'; $result = $engine->render(\$template, { array => [1, 2, 3, 4, 5], hash => { array => [6, 7, 8] }}); is $result, $expected, "arrayref are interpolated in templates"; # if-then-else $template = '<% if want %>hello<% else %>goodbye<% end %> world'; $result = $engine->render(\$template, {want => 1}); is $result, 'hello world', "true boolean condition matched"; $result = $engine->render(\$template, {want => 0}); is $result, 'goodbye world', "false boolean condition matched"; $template = 'one: 1 two: <% two %> three : <% three %>'; $result = $engine->render(\$template, {two => 2, three => 3 }); is $result, 'one: 1 two: 2 three : 3', "multiline template processed"; libdancer2-perl-0.166001+dfsg.orig/t/author-pod-syntax.t0000644000175000017500000000050312650351107022120 0ustar gregoagregoa#!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use strict; use warnings; use Test::More; use Test::Pod 1.41; all_pod_files_ok(); libdancer2-perl-0.166001+dfsg.orig/t/dsl.t0000644000175000017500000000070512650351107017300 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Plack::Test; use HTTP::Request::Common; use Dancer2; any [ 'get', 'post' ], '/' => sub { request->method; }; my $app = __PACKAGE__->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/' )->content, 'GET', 'GET / correct content' ); is( $cb->( POST '/' )->content, 'POST', 'POST / correct content' ); }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/session_forward.t0000644000175000017500000001157212650351107021731 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Cookies; use HTTP::Request::Common; { package Test::Forward::Single; use Dancer2; set session => 'Simple'; get '/main' => sub { session foo => 'Single/main'; forward '/outer'; }; get '/outer' => sub { session bar => 'Single/outer'; forward '/inner'; }; get '/inner' => sub { session baz => 'Single/inner'; return join ':', map +( session($_) || '' ), qw; }; get '/clear' => sub { session foo => undef; session bar => undef; session baz => undef; }; } { package Test::Forward::Multi::SameCookieName; use Dancer2; set session => 'Simple'; prefix '/same'; get '/main' => sub { session foo => 'SameCookieName/main'; forward '/outer'; }; get '/bad_chain' => sub { session foo => 'SameCookieName/bad_chain'; forward '/other/main'; }; } { package Test::Forward::Multi::OtherCookieName; use Dancer2; set engines => { session => { Simple => { cookie_name => 'session.dancer' } } }; set session => 'Simple'; prefix '/other'; get '/main' => sub { session foo => 'OtherCookieName/main'; # Forwards to another app with different cookie name forward '/outer'; }; get '/clear' => sub { session foo => undef; session bar => undef; session baz => undef; }; } # base uri for all requests. my $base = 'http://localhost'; subtest 'Forwards within a single app' => sub { my $test = Plack::Test->create( Test::Forward::Single->to_app ); my $jar = HTTP::Cookies->new; { my $res = $test->request( GET "$base/main" ); is( $res->content, q{Single/main:Single/outer:Single/inner}, 'session value preserved after chained forwards', ); $jar->extract_cookies($res); } { my $req = GET "$base/inner"; $jar->add_cookie_header($req); my $res = $test->request($req); is( $res->content, q{Single/main:Single/outer:Single/inner}, 'session values preserved between calls', ); $jar->extract_cookies($res); } { my $req = GET "$base/clear"; $jar->add_cookie_header($req); my $res = $test->request( GET "$base/clear" ); $jar->extract_cookies($res); } { my $req = GET "$base/outer"; $jar->add_cookie_header($req); my $res = $test->request( GET "$base/outer" ); is( $res->content, q{:Single/outer:Single/inner}, 'session value preserved after forward from route', ); $jar->extract_cookies($res); } }; subtest 'Forwards between multiple apps using the same cookie name' => sub { my $test = Plack::Test->create( Dancer2->psgi_app ); my $jar = HTTP::Cookies->new; { my $res = $test->request( GET "$base/same/main" ); is( $res->content, q{SameCookieName/main:Single/outer:Single/inner}, 'session value preserved after chained forwards between apps', ); $jar->extract_cookies($res); } { my $req = GET "$base/outer"; $jar->add_cookie_header($req); my $res = $test->request($req); is( $res->content, q{SameCookieName/main:Single/outer:Single/inner}, 'session value preserved after forward from route', ); } }; subtest 'Forwards between multiple apps using different cookie names' => sub { my $test = Plack::Test->create( Dancer2->psgi_app ); my $jar = HTTP::Cookies->new; my $res = $test->request( GET "$base/other/main" ); is( $res->content, q{:Single/outer:Single/inner}, 'session value only from forwarded app', ); }; # we need to make sure B doesn't override A when forwarding to C # A -> B -> C # This means that A (cookie_name "Homer") # forwarding to B (cookie_name "Marge") # forwarding to C (cookie_name again "Homer") # will cause a problem because we will lose "Homer" session data, # because it will be overwritten by "Marge" session data. # Suddenly A and C cannot communicate because it was flogged. # # if A -> Single, B -> OtherCookieName, C -> SameCookieName # call A, create session, then forward to B, create session, # then forward to C, check has values as in A and C subtest 'Forwards between multiple apps using multiple different cookie names' => sub { my $test = Plack::Test->create( Dancer2->psgi_app ); my $jar = HTTP::Cookies->new; my $res = $test->request( GET "$base/same/bad_chain" ); is( $res->content, q{SameCookieName/bad_chain:Single/outer:Single/inner}, 'session value only from apps with same session cookie name', ); }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/corpus/0000775000175000017500000000000012650351107017644 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/corpus/pretty/0000775000175000017500000000000012650351107021173 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/corpus/pretty/505.tt0000644000175000017500000000010012650351107022042 0ustar gregoagregoaTemplate selected. message: [% content %] status: [% status %] libdancer2-perl-0.166001+dfsg.orig/t/corpus/pretty/relative.tt0000644000175000017500000000006412650351107023355 0ustar gregoagregoaTemplate [% component.name %] [% INCLUDE 505.tt %] libdancer2-perl-0.166001+dfsg.orig/t/corpus/pretty_public/0000775000175000017500000000000012650351107022531 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/corpus/pretty_public/510.html0000644000175000017500000000001512650351107023716 0ustar gregoagregoaStatic page. libdancer2-perl-0.166001+dfsg.orig/t/corpus/pretty_public/404.html0000644000175000017500000000006412650351107023724 0ustar gregoagregoa

Yup, you're lost

libdancer2-perl-0.166001+dfsg.orig/t/corpus/static/0000775000175000017500000000000012650351107021133 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/corpus/static/1x1.png0000644000175000017500000000013712650351107022251 0ustar gregoagregoaPNG  IHDR%VPLTEz=tRNS@f IDATc`!3IENDB`libdancer2-perl-0.166001+dfsg.orig/t/corpus/static/index.html0000644000175000017500000000021312650351107023122 0ustar gregoagregoa Unicode test

Hello, UTF-8

áéíóú

libdancer2-perl-0.166001+dfsg.orig/t/multi_apps_forward.t0000644000175000017500000000332612650351107022421 0ustar gregoagregoa#!perl use strict; use warnings; use Test::More tests => 9; use Plack::Test; use HTTP::Request::Common; { package App1; use Dancer2; get '/' => sub {'App1'}; get '/forward' => sub { forward '/'; ::ok( 0, 'Foward not returning right away!' ); }; get '/forward_to_new' => sub { forward '/new'; ::ok( 0, 'Foward not returning right away!' ); }; } { package App2; use Dancer2; get '/' => sub {'App2'}; get '/new' => sub {'New'}; } { # test each single app my $app1 = App1->to_app; test_psgi $app1, sub { my $cb = shift; is( $cb->( GET '/' )->code, 200, '[GET /] OK' ); is( $cb->( GET '/' )->content, 'App1', '[GET /] OK content' ); is( $cb->( GET '/forward' )->code, 200, '[GET /forward] OK' ); is( $cb->( GET '/forward' )->content, 'App1', '[GET /forward] OK content' ); is( $cb->( GET '/forward_to_new' )->code, 404, 'Cannot find /new', ); }; my $app2 = App2->to_app; test_psgi $app2, sub { my $cb = shift; is( $cb->( GET '/' )->code, 200, '[GET /] OK' ); is( $cb->( GET '/' )->content, 'App2', '[GET /] OK content' ); }; } note 'Old format using psgi_app to loop over multiple apps'; { # test global my $app = Dancer2->psgi_app; test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/forward_to_new' )->code, 200, '[GET /forward_to_new] OK', ); is( $cb->( GET '/forward_to_new' )->content, 'New', '[GET /forward_to_new] OK content', ); }; } libdancer2-perl-0.166001+dfsg.orig/t/00-report-prereqs.t0000644000175000017500000001273112650351107021727 0ustar gregoagregoa#!perl use strict; use warnings; # This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.021 use Test::More tests => 1; use ExtUtils::MakeMaker; use File::Spec; # from $version::LAX my $lax_version_re = qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )? | (?:\.[0-9]+) (?:_[0-9]+)? ) | (?: v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )? | (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)? ) )/x; # hide optional CPAN::Meta modules from prereq scanner # and check if they are available my $cpan_meta = "CPAN::Meta"; my $cpan_meta_pre = "CPAN::Meta::Prereqs"; my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic # Verify requirements? my $DO_VERIFY_PREREQS = 1; sub _max { my $max = shift; $max = ( $_ > $max ) ? $_ : $max for @_; return $max; } sub _merge_prereqs { my ($collector, $prereqs) = @_; # CPAN::Meta::Prereqs object if (ref $collector eq $cpan_meta_pre) { return $collector->with_merged_prereqs( CPAN::Meta::Prereqs->new( $prereqs ) ); } # Raw hashrefs for my $phase ( keys %$prereqs ) { for my $type ( keys %{ $prereqs->{$phase} } ) { for my $module ( keys %{ $prereqs->{$phase}{$type} } ) { $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module}; } } } return $collector; } my @include = qw( ); my @exclude = qw( ); # Add static prereqs to the included modules list my $static_prereqs = do 't/00-report-prereqs.dd'; # Merge all prereqs (either with ::Prereqs or a hashref) my $full_prereqs = _merge_prereqs( ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ), $static_prereqs ); # Add dynamic prereqs to the included modules list (if we can) my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; if ( $source && $HAS_CPAN_META ) { if ( my $meta = eval { CPAN::Meta->load_file($source) } ) { $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); } } else { $source = 'static metadata'; } my @full_reports; my @dep_errors; my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs; # Add static includes into a fake section for my $mod (@include) { $req_hash->{other}{modules}{$mod} = 0; } for my $phase ( qw(configure build test runtime develop other) ) { next unless $req_hash->{$phase}; next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING}); for my $type ( qw(requires recommends suggests conflicts modules) ) { next unless $req_hash->{$phase}{$type}; my $title = ucfirst($phase).' '.ucfirst($type); my @reports = [qw/Module Want Have/]; for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) { next if $mod eq 'perl'; next if grep { $_ eq $mod } @exclude; my $file = $mod; $file =~ s{::}{/}g; $file .= ".pm"; my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC; my $want = $req_hash->{$phase}{$type}{$mod}; $want = "undef" unless defined $want; $want = "any" if !$want && $want == 0; my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required"; if ($prefix) { my $have = MM->parse_version( File::Spec->catfile($prefix, $file) ); $have = "undef" unless defined $have; push @reports, [$mod, $want, $have]; if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) { if ( $have !~ /\A$lax_version_re\z/ ) { push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)"; } elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) { push @dep_errors, "$mod version '$have' is not in required range '$want'"; } } } else { push @reports, [$mod, $want, "missing"]; if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) { push @dep_errors, "$mod is not installed ($req_string)"; } } } if ( @reports ) { push @full_reports, "=== $title ===\n\n"; my $ml = _max( map { length $_->[0] } @reports ); my $wl = _max( map { length $_->[1] } @reports ); my $hl = _max( map { length $_->[2] } @reports ); if ($type eq 'modules') { splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports; } else { splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports; } push @full_reports, "\n"; } } } if ( @full_reports ) { diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; } if ( @dep_errors ) { diag join("\n", "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n", "The following REQUIRED prerequisites were not satisfied:\n", @dep_errors, "\n" ); } pass; # vim: ts=4 sts=4 sw=4 et: libdancer2-perl-0.166001+dfsg.orig/t/lib/0000775000175000017500000000000012650351107017077 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/lib/DancerPlugin.pm0000644000175000017500000000066112650351107022011 0ustar gregoagregoapackage t::lib::DancerPlugin; use strict; use warnings; use Dancer2::Plugin; my $counter = 0; register around_get => sub { my $dsl = shift; $dsl->get( '/foo/plugin' => sub { 'foo plugin'; } ); }; register install_hooks => sub { my $dsl = shift; $dsl->hook( 'before' => sub { $dsl->session( before_plugin => ++$counter ); } ); }; register_plugin; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/TestApp.pm0000644000175000017500000000471112650351107021016 0ustar gregoagregoapackage t::lib::TestApp; use Dancer2; # this app is intended to cover 100% of the DSL! # set some MIME aliases... mime->add_type( foo => 'text/foo' ); mime->add_alias( f => 'foo' ); set 'default_mime_type' => 'text/bar'; # hello route get '/' => sub { app->name }; # /haltme should bounce to / hook 'before' => sub { if ( request->path_info eq '/haltme' ) { redirect '/'; halt; } }; get '/haltme' => sub {"should not be there"}; hook 'after' => sub { my $response = shift; if ( request->path_info eq '/rewrite_me' ) { $response->content("rewritten!"); } }; get '/rewrite_me' => sub {"body should not be this one"}; # some settings set some_var => 1; setting some_other_var => 1; set multiple_vars => 4, can_be_set => 2; get '/config' => sub { return config->{some_var} . ' ' . config->{some_other_var} . ' and ' . setting('multiple_vars') . setting('can_be_set'); }; if ( $] >= 5.010 ) { # named captures get qr{/(? usr | content | post )/(? delete | find )/(? \d+ )}x => sub { join( ":", sort %{ captures() } ); }; } # chained routes with pass get '/user/**' => sub { my $user = params->{splat}; var user => $user->[0][0]; pass; }; get '/user/*/home' => sub { my $user = var('user'); # should be set by the previous route "hello $user"; }; # post & dirname post '/dirname' => sub { dirname('/etc/passwd'); }; # header get '/header/:name/:value' => sub { header param('name') => param('value'); 1; }; # push_header get '/header/:name/:valueA/:valueB' => sub { push_header param('name') => param('valueA'); push_header param('name') => param('valueB'); 1; }; # header get '/header_twice/:name/:valueA/:valueB' => sub { header param('name') => param('valueA'); header param('name') => param('valueB'); 1; }; # any any [ 'get', 'post' ], '/any' => sub { "Called with method " . request->method; }; # true and false get '/booleans' => sub { join( ":", true, false ); }; # mimes get '/mime/:name' => sub { mime->for_name( param('name') ); }; # content_type get '/content_type/:type' => sub { content_type param('type'); 1; }; # prefix prefix '/prefix' => sub { get '/bar' => sub {'/prefix/bar'}; prefix '/prefix1' => sub { get '/bar' => sub {'/prefix/prefix1/bar'}; }; prefix '/prefix2'; get '/foo' => sub {'/prefix/prefix2/foo'}; }; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/SubApp1.pm0000644000175000017500000000022112650351107020701 0ustar gregoagregoapackage t::lib::SubApp1; use strict; use warnings; use Dancer2; use t::lib::DancerPlugin; install_hooks; get '/subapp1' => sub { 1; }; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/FooPlugin.pm0000644000175000017500000000275712650351107021350 0ustar gregoagregoapackage t::lib::FooPlugin; use Dancer2::Plugin; on_plugin_import { my $dsl = shift; $dsl->get( '/sitemap' => sub { _html_sitemap($dsl) } ); }; sub _html_sitemap { join( ', ', _retrieve_get_urls(@_) ); } register foo_wrap_request => sub { my ($self) = plugin_args(@_); return $self->request; }, { is_global => 0 }; register foo_route => sub { my ($self) = plugin_args(@_); $self->get( '/foo', sub {'foo'} ); } => { is_global => 1, prototype => '$@' }; register p_config => sub { my $dsl = shift; my $config = plugin_setting; return $config; }; # taken from SiteMap sub _retrieve_get_urls { my $dsl = shift; my ( $route, @urls ); for my $app ( @{ $dsl->runner->apps } ) { my $routes = $app->routes; # push the static get routes into an array. get_route: for my $get_route ( @{ $routes->{get} } ) { my $regexp = $get_route->regexp; # If the pattern is a true comprehensive regexp or the route # has a :variable element to it, then omit it. next get_route if ( $regexp =~ m/[()[\]|]|:\w/ ); # If there is a wildcard modifier, then drop it and have the # full route. $regexp =~ s/\?//g; # Other than that, its cool to be added. push( @urls, $regexp ) if !grep { $regexp =~ m/$_/i } @$Dancer2::Plugin::SiteMap::OMIT_ROUTES; } } return sort(@urls); } register_plugin; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/Hookee.pm0000644000175000017500000000042412650351107020645 0ustar gregoagregoapackage t::lib::Hookee; use Dancer2::Plugin; register_hook 'start_hookee', 'stop_hookee'; register_hook 'third_hook'; register some_keyword => sub { execute_hook('start_hookee'); }; register some_other => sub { execute_hook('third_hook'); }; register_plugin; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/SubApp2.pm0000644000175000017500000000022112650351107020702 0ustar gregoagregoapackage t::lib::SubApp2; use strict; use warnings; use Dancer2; use t::lib::DancerPlugin; install_hooks; get '/subapp2' => sub { 2; }; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/TestPod.pm0000644000175000017500000000112712650351107021016 0ustar gregoagregoapackage t::lib::TestPod; use Dancer2; =head1 NAME TestPod =head2 ROUTES =over =cut =item get "/in_testpod" testpod =cut get '/in_testpod' => sub { # code; }; =item get "/hello" testpod =cut get '/hello' => sub { # code; }; =item post '/in_testpod/*' post in_testpod =cut post '/in_testpod/*' => sub { return 'post in_testpod'; }; =back =head2 SPECIALS =head3 PUBLIC =over =item get "/me:id" =cut get "/me:id" => sub { # code; }; =back =head3 PRIVAT =over =item post "/me:id" post /me:id =cut post "/me:id" => sub { # code; }; =back =cut 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/OnPluginImport.pm0000644000175000017500000000106212650351107022360 0ustar gregoagregoapackage t::lib::OnPluginImport; use Dancer2::Plugin; # register keyword register some_import => sub { shift->dancer_version }; # register hook register_hook qw(imported_plugin); # add hook. This triggers the $dsl->hooks attribute # to be built plugins added after this should still # be able to register and add hooks. See #889. on_plugin_import { my $dsl = shift; $dsl->app->add_hook( Dancer2::Core::Hook->new( name => 'imported_plugin', code => sub { $dsl->dancer_version } ) ); }; register_plugin; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/EmptyPlugin.pm0000644000175000017500000000021212650351107021703 0ustar gregoagregoapackage t::lib::EmptyPlugin; use Dancer2::Plugin; # This plugin does nothing. # Based on test from @e11it in #510 register_plugin; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/App2.pm0000644000175000017500000000024212650351107020233 0ustar gregoagregoapackage t::lib::App2; use strict; use warnings; use Dancer2; use t::lib::DancerPlugin; install_hooks; get '/app2' => sub { session 'before_plugin'; }; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/PluginWithImport.pm0000644000175000017500000000103112650351107022713 0ustar gregoagregoapackage t::lib::PluginWithImport; # ABSTRACT: a plugin that implement its own import method =head1 DESCRIPTION In order to demonstrate that Dancer2::Plugin won't loose the original import method of the plugin. =cut use strict; use warnings; use Dancer2; use Dancer2::Plugin; my $_stuff = {}; sub stuff {$_stuff} no warnings 'redefine'; sub import { my $class = shift; $_stuff->{$class} = 'imported'; } register dancer_plugin_with_import_keyword => sub { 'dancer_plugin_with_import_keyword'; }; register_plugin; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/MyDancerDSL.pm0000644000175000017500000000176112650351107021505 0ustar gregoagregoapackage MyDancerDSL; use Moo; use Dancer2::Core::Hook; use Dancer2::Core::Error; use Dancer2::FileUtils; use Carp; extends 'Dancer2::Core::DSL'; around dsl_keywords => sub { my $orig = shift; my $keywords = $orig->(@_); $keywords->{gateau} = { is_global => 0 }; # cookie $keywords->{moteur} = { is_global => 1 }; # engine $keywords->{stop} = { is_global => 0 }; # halt $keywords->{prend} = { is_global => 1, prototype => '@' }; # get $keywords->{envoie} = { is_global => 1, prototype => '$&' }; # post $keywords->{entete} = { is_global => 0 }; #header $keywords->{proto} = { is_global => 1, prototype => '&' }; # prototype return $keywords; }; sub gateau { goto &Dancer2::Core::DSL::cookie } sub moteur { goto &Dancer2::Core::DSL::engine } sub stop { goto &Dancer2::Core::DSL::halt } sub prend { goto &Dancer2::Core::DSL::get } sub envoie { goto &Dancer2::Core::DSL::post } sub entete { goto &Dancer2::Core::DSL::header } sub proto { $_[1]->() } 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/App1.pm0000644000175000017500000000024212650351107020232 0ustar gregoagregoapackage t::lib::App1; use strict; use warnings; use Dancer2; use t::lib::DancerPlugin; install_hooks; get '/app1' => sub { session 'before_plugin'; }; 1; libdancer2-perl-0.166001+dfsg.orig/t/lib/Foo.pm0000644000175000017500000000012612650351107020155 0ustar gregoagregoapackage t::lib::Foo; use Dancer2; get '/in_foo' => sub { session('test'); }; 1; libdancer2-perl-0.166001+dfsg.orig/t/time.t0000644000175000017500000000417312650351107017457 0ustar gregoagregoa# time.t use strict; use warnings; use Test::More; use Class::Load 'try_load_class'; my $mocked_epoch = 1355676244; # "Sun, 16-Dec-2012 16:44:04 GMT" # The order is important! try_load_class('Test::MockTime') or plan skip_all => 'Test::MockTime not present'; Test::MockTime::set_fixed_time($mocked_epoch); require Dancer2::Core::Time; my @tests = ( [ "1h" => 3600 => "Sun, 16-Dec-2012 17:44:04 GMT" ], [ "1 hour" => 3600 => "Sun, 16-Dec-2012 17:44:04 GMT" ], [ "+1 hour" => 3600 => "Sun, 16-Dec-2012 17:44:04 GMT" ], [ "-1h" => -3600 => "Sun, 16-Dec-2012 15:44:04 GMT" ], [ "1 hours" => 3600 => "Sun, 16-Dec-2012 17:44:04 GMT" ], [ "1d" => ( 3600 * 24 ) => "Mon, 17-Dec-2012 16:44:04 GMT" ], [ "1 day" => ( 3600 * 24 ) => "Mon, 17-Dec-2012 16:44:04 GMT" ], ); foreach my $test (@tests) { my ( $expr, $secs, $gmt_string ) = @$test; subtest "Expression: \"$expr\"" => sub { my $t = Dancer2::Core::Time->new( expression => $expr ); is $t->seconds, $secs, "\"$expr\" is $secs seconds"; is $t->epoch, ( $t->seconds + $mocked_epoch ), "... its epoch is " . $t->epoch; is $t->gmt_string, $gmt_string, "... and its GMT string is $gmt_string"; }; } subtest "Forcing another epoch in the object should work" => sub { my $t = Dancer2::Core::Time->new( epoch => 1, expression => "1h" ); is $t->seconds, 3600, "...1h is still 3600 seconds"; is $t->epoch, 1, "... epoch is 1"; is $t->gmt_string, 'Thu, 01-Jan-1970 00:00:01 GMT', "... and is expressed as Thu, 01-Jan-1970 00:00:01 GMT"; }; subtest "unparsable strings should be kept" => sub { for my $t ( [ "something silly", "something silly", "something silly" ], [ "+2 something", "+2 something", "+2 something" ], ) { my ( $expr, $secs, $gmt ) = @$t; my $t = Dancer2::Core::Time->new( expression => $expr ); is $t->seconds, $secs, "\"$expr\" is $secs seconds"; is $t->epoch, $expr, "... its epoch is $expr"; is $t->gmt_string, $gmt, "... and its GMT string is $gmt"; } }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/multiapp_template_hooks.t0000644000175000017500000001171612650351107023453 0ustar gregoagregoa#!perl use strict; use warnings; use File::Spec; use File::Basename 'dirname'; use Test::More tests => 32; use Plack::Test; use HTTP::Request::Common; my $views = File::Spec->rel2abs( File::Spec->catfile( dirname(__FILE__), 'views' ) ); my %called_hooks = (); my $hook_name = 'engine.template.before_render'; { package App1; use Dancer2; set views => $views; hook before => sub { $called_hooks{'App1'}{'before'}++ }; hook before_template => sub { my $tokens = shift; ::isa_ok( $tokens, 'HASH', '[App1] Tokens' ); my $app = app; ::isa_ok( $app, 'Dancer2::Core::App', 'Got app object inside App1' ); # we accept anything that goes to App1, even if not only to App1 ::like( $tokens->{'request'}->param('to'), qr/^App1/, 'Request reached to correct App (App1)', ); ::is( scalar @{ $app->template_engine->hooks->{$hook_name} }, 1, 'App1 has a single before_template hook defined', ); $tokens->{'myname'} = 'App1'; $called_hooks{'App1'}{'before_template'}++; }; get '/' => sub { template beforetemplate => { it => 'App1' }, { layout => undef }; }; } { package App2; use Dancer2; set views => $views; hook before => sub { $called_hooks{'App2'}{'before'}++ }; hook before_template => sub { my $tokens = shift; ::isa_ok( $tokens, 'HASH', '[App2] Tokens' ); my $app = app; ::isa_ok( $app, 'Dancer2::Core::App', 'Got app object inside App2' ); ::is( $tokens->{'request'}->param('to'), 'App2', 'Request reached to correct App (App2)', ); ::is( scalar @{ $app->template_engine->hooks->{$hook_name} }, 1, 'App2 has a single before_template hook defined', ); $tokens->{'myname'} = 'App2'; $called_hooks{'App2'}{'before_template'}++; }; get '/' => sub { template beforetemplate => { it => 'App2' }, { layout => undef }; }; get '/2' => sub { template beforetemplate => { it => 'App2' }, { layout => undef }; }; } note 'Check App1 only calls first hook, not both'; { # clear %called_hooks = (); my $app = App1->to_app; isa_ok( $app, 'CODE', 'Got app for test' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/?to=App1' ); is( $res->code, 200, '[GET /] Successful' ); is( $res->content, "App is App1, again, it is App1\n", '[GET /] Correct content', ); is_deeply( \%called_hooks, { App1 => { before => 1, before_template => 1 } }, 'Only App1\'s before_template hook was called', ); }; } note 'Check App2 only calls second hook, not both'; { # clear %called_hooks = (); my $app = App2->to_app; isa_ok( $app, 'CODE', 'Got app for test' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/?to=App2' ); is( $res->code, 200, '[GET /] Successful' ); is( $res->content, "App is App2, again, it is App2\n", '[GET /] Correct content', ); is_deeply( \%called_hooks, { App2 => { before => 1, before_template => 1 } }, 'Only App2\'s before_template hook was called', ); }; } note 'Check both apps only call the first hook (correct app), not both'; { # clear %called_hooks = (); my $app = Dancer2->psgi_app; isa_ok( $app, 'CODE', 'Got app for test' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/?to=App1:App2' ); is( $res->code, 200, '[GET /] Successful' ); is( $res->content, "App is App1, again, it is App1\n", '[GET /] Correct content', ); is_deeply( \%called_hooks, { App1 => { before => 1, before_template => 1 } }, 'Only App1\'s before_template hook was called (full PSGI app)', ); }; } note 'Check both apps only call the second hook (correct app), not both'; { # clear %called_hooks = (); my $app = Dancer2->psgi_app; isa_ok( $app, 'CODE', 'Got app for test' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/2?to=App2' ); is( $res->code, 200, '[GET /2] Successful' ); is( $res->content, "App is App2, again, it is App2\n", '[GET /2] Correct content', ); # INFO: %called_hooks does not contain any counts for App1; # no routes match, so no hooks are called. is_deeply( \%called_hooks, { App2 => { before => 1, before_template => 1 }, }, 'Only App2\'s before_template hook was called (full PSGI app)', ); }; } libdancer2-perl-0.166001+dfsg.orig/t/engine.t0000644000175000017500000000263612650351107017770 0ustar gregoagregoause strict; use warnings; use Test::More; use Test::Fatal; use Dancer2::Core::App; use Dancer2::Template::Tiny; { my $f = Dancer2::Template::Tiny->new(); isa_ok( $f, 'Dancer2::Template::Tiny' ); ok( $f->does('Dancer2::Core::Role::Engine'), 'Consumed Role::Engine', ); ok( $f->does('Dancer2::Core::Role::Template'), 'Consumed Role::Template', ); is( $f->name, 'Tiny', 'Correct engine name' ); } # checks for validity of engine names my $app = Dancer2::Core::App->new(); isa_ok( $app, 'Dancer2::Core::App' ); { no warnings qw; *Dancer2::Core::Factory::create = sub { $_[1] }; } foreach my $engine_type ( qw ) { note($engine_type); my $engine; my $build_method = "_build_${engine_type}_engine"; is( exception { $engine = $app->$build_method( undef, { $engine_type => 'Fake43Thing' } ); }, undef, "Built $engine_type successfully with proper name", ); like( exception { $engine = $app->$build_method( undef, { $engine_type => '7&&afail' } ); }, qr/^Cannot load $engine_type engine '7&&afail': illegal module name/, "Failed creating $engine_type with illegal name", ); is( $engine, $engine_type, 'Correct response from override' ); } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/factory.t0000644000175000017500000000102012650351107020154 0ustar gregoagregoause strict; use warnings; use Test::More; use Test::Fatal; use Dancer2::Core; use Dancer2::Core::Factory; is Dancer2::Core::camelize('foo_bar_baz'), 'FooBarBaz'; is Dancer2::Core::camelize('FooBarBaz'), 'FooBarBaz'; like( exception { my $l = Dancer2::Core::Factory->create( unknown => 'stuff' ) }, qr{Unable to load class for Unknown component Stuff:}, 'Failure to load nonexistent class', ); my $l = Dancer2::Core::Factory->create( logger => 'console' ); isa_ok $l, 'Dancer2::Logger::Console'; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/mime.t0000644000175000017500000000230012650351107017436 0ustar gregoagregoause strict; use warnings; use Test::More tests => 12; BEGIN { use_ok 'Dancer2::Core::MIME'; } my $mime = Dancer2::Core::MIME->new(); is_deeply( $mime->custom_types, {}, 'user defined mime_types are empty' ); $mime->add_type( foo => 'text/foo' ); is_deeply( $mime->custom_types, { foo => 'text/foo' }, 'text/foo is saved' ); is( $mime->for_name('foo'), 'text/foo', 'mime type foo is found' ); $mime->add_alias( bar => 'foo' ); is( $mime->for_name('bar'), 'text/foo', 'mime type bar is found' ); is( $mime->for_file('foo.bar'), 'text/foo', 'mime type for extension .bar is found' ); is( $mime->for_file('foobar'), $mime->default, 'mime type for no extension is the default' ); is( $mime->add_alias( xpto => 'BAR' ), 'text/foo', 'mime gets correctly lowercased for user types' ); is $mime->add_alias( xpto => 'SVG' ) => 'image/svg+xml', 'mime gets correctly lowercased for system types'; is $mime->add_alias( zbr => 'baz' ) => $mime->default, 'alias of unkown mime type gets default mime type'; is $mime->name_or_type("text/zbr") => "text/zbr", 'name_or_type does not change if it seems a mime type string'; is $mime->name_or_type("svg") => "image/svg+xml", 'name_or_type knows svg'; libdancer2-perl-0.166001+dfsg.orig/t/caller.t0000644000175000017500000000076312650351107017764 0ustar gregoagregoa#!perl use strict; use warnings; use Test::More tests => 2; use Plack::Test; use HTTP::Request::Common; use File::Spec; { package App; use Dancer2; get '/' => sub { app->caller }; } my $app = App->to_app; test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/' ); is( $res->code, 200, '[GET /] Successful' ); is( File::Spec->canonpath( $res->content), File::Spec->catfile(t => 'caller.t'), 'Correct App name from caller', ); }; libdancer2-perl-0.166001+dfsg.orig/t/session_engines.t0000644000175000017500000000620412650351107021711 0ustar gregoagregoause strict; use warnings; use Test::More; use YAML; use Plack::Test; use HTTP::Cookies; use HTTP::Request::Common; use File::Spec; use File::Basename 'dirname'; my $SESSION_DIR; BEGIN { $SESSION_DIR = File::Spec->catfile( dirname(__FILE__), 'sessions' ); } { package App; use Dancer2; my @to_destroy; set engines => { session => { YAML => { session_dir => $SESSION_DIR } } }; hook 'engine.session.before_destroy' => sub { my $session = shift; push @to_destroy, $session; }; get '/set_session/*' => sub { my ($name) = splat; session name => $name; }; get '/read_session' => sub { my $name = session('name') || ''; "name='$name'"; }; get '/clear_session' => sub { session name => undef; return exists( session->data->{'name'} ) ? "failed" : "cleared"; }; get '/cleanup' => sub { app->destroy_session; return scalar(@to_destroy); }; setting session => 'Simple'; set( show_errors => 1, environment => 'production', ); } my $url = "http://localhost"; my $test = Plack::Test->create( App->to_app ); my $app = Dancer2->runner->apps->[0]; my @clients = qw(one two three); for my $engine ( qw(YAML Simple) ) { # clear current session engine, and rebuild for the test # This is *really* messy, playing in object hashrefs.. delete $app->{session_engine}; $app->config->{session} = $engine; $app->session_engine; # trigger a build # run the tests for this engine for my $client (@clients) { my $jar = HTTP::Cookies->new; subtest "[$engine][$client] Empty session" => sub { my $res = $test->request( GET "$url/read_session" ); like $res->content, qr/name=''/, "empty session for client $client"; $jar->extract_cookies($res); }; subtest "[$engine][$client] set_session" => sub { my $req = GET "$url/set_session/$client"; $jar->add_cookie_header($req); my $res = $test->request($req); ok( $res->is_success, "set_session for client $client" ); $jar->extract_cookies($res); }; subtest "[$engine][$client] session for client" => sub { my $req = GET "$url/read_session"; $jar->add_cookie_header($req); my $res = $test->request($req); like $res->content, qr/name='$client'/, "session looks good for client $client"; $jar->extract_cookies($res); }; subtest "[$engine][$client] delete session" => sub { my $req = GET "$url/clear_session"; $jar->add_cookie_header($req); my $res = $test->request($req); like $res->content, qr/cleared/, "deleted session key"; }; subtest "[$engine][$client] cleanup" => sub { my $req = GET "$url/cleanup"; $jar->add_cookie_header($req); my $res = $test->request($req); ok( $res->is_success, "cleanup done for $client" ); ok( $res->content, "session hook triggered" ); }; } } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/request_upload.t0000644000175000017500000001416112650351107021553 0ustar gregoagregoause strict; use warnings FATAL => 'all'; use Test::More; use Test::Fatal; use Dancer2::Core::Request; use Carp; use File::Temp 0.22; use File::Basename qw/dirname basename/; use File::Spec; use Encode qw(encode_utf8); diag "If you want extra speed, install URL::Encode::XS" if !$Dancer2::Core::Request::XS_URL_DECODE; diag "If you want extra speed, install CGI::Deurl::XS" if !$Dancer2::Core::Request::XS_PARSE_QUERY_STRING; sub test_path { my ( $file, $dir ) = @_; is dirname($file), $dir, "dir of $file is $dir"; } sub run_test { my $filename = "some_\x{1A9}_file.txt"; my $content = qq{------BOUNDARY Content-Disposition: form-data; name="test_upload_file"; filename="$filename" Content-Type: text/plain SHOGUN ------BOUNDARY Content-Disposition: form-data; name="test_upload_file"; filename="yappo2.txt" Content-Type: text/plain SHOGUN2 ------BOUNDARY Content-Disposition: form-data; name="test_upload_file3"; filename="yappo3.txt" Content-Type: text/plain SHOGUN3 ------BOUNDARY Content-Disposition: form-data; name="test_upload_file4"; filename="yappo4.txt" Content-Type: text/plain SHOGUN4 ------BOUNDARY Content-Disposition: form-data; name="test_upload_file4"; filename="yappo5.txt" Content-Type: text/plain SHOGUN4 ------BOUNDARY Content-Disposition: form-data; name="test_upload_file6"; filename="yappo6.txt" Content-Type: text/plain SHOGUN6 ------BOUNDARY-- }; $content =~ s/\r\n/\n/g; $content =~ s/\n/\r\n/g; $content = encode_utf8($content); do { open my $in, '<', \$content; my $req = Dancer2::Core::Request->new( env => { 'psgi.input' => $in, CONTENT_LENGTH => length($content), CONTENT_TYPE => 'multipart/form-data; boundary=----BOUNDARY', REQUEST_METHOD => 'POST', SCRIPT_NAME => '/', SERVER_PORT => 80, } ); my @undef = $req->upload('undef'); is @undef, 0, 'non-existent upload as array is empty'; my $undef = $req->upload('undef'); is $undef, undef, '... and non-existent upload as scalar is undef'; my @uploads = $req->upload('test_upload_file'); like $uploads[0]->content, qr|^SHOGUN|, "content for first upload is ok, via 'upload'"; like $uploads[1]->content, qr|^SHOGUN|, "... content for second as well"; is $req->uploads->{'test_upload_file4'}[0]->content, 'SHOGUN4', "... content for other also good"; note "headers"; is_deeply $uploads[0]->headers, { 'Content-Disposition' => qq[form-data; name="test_upload_file"; filename="$filename"], 'Content-Type' => 'text/plain', }; note "type"; is $uploads[0]->type, 'text/plain'; my $test_upload_file3 = $req->upload('test_upload_file3'); is $test_upload_file3->content, 'SHOGUN3', "content for upload #3 as a scalar is good, via req->upload"; my @test_upload_file6 = $req->upload('test_upload_file6'); is $test_upload_file6[0]->content, 'SHOGUN6', "content for upload #6 is good"; is $test_upload_file6[0]->content(':raw'), 'SHOGUN6'; my $upload = $req->upload('test_upload_file6'); isa_ok $upload, 'Dancer2::Core::Request::Upload'; is $upload->filename, 'yappo6.txt', 'filename is ok'; ok $upload->file_handle, 'file handle is defined'; is $req->params->{'test_upload_file6'}, 'yappo6.txt', "filename is accessible via params"; # copy_to, link_to my $dest_dir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 ); my $dest_file = File::Spec->catfile( $dest_dir, $upload->basename ); $upload->copy_to($dest_file); ok( ( -f $dest_file ), "file '$dest_file' has been copied" ); my $dest_file_link = File::Spec->catfile( $dest_dir, "hardlink" ); $upload->link_to($dest_file_link); ok( ( -f $dest_file_link ), "hardlink '$dest_file_link' has been created" ); # make sure cleanup is performed when the HTTP::Body object is purged my $file = $upload->tempname; ok( ( -f $file ), 'temp file exists while HTTP::Body lives' ); undef $req->{_http_body}; SKIP: { skip "Win32 can't remove file/link while open, deadlock with HTTP::Body", 1 if ( $^O eq 'MSWin32' ); ok( ( !-f $file ), 'temp file is removed when HTTP::Body object dies' ); } note "testing failing open for tempfile"; { # mocking open_file to make it fail my $upload_file_coderef; { no strict 'refs'; $upload_file_coderef = *{"Dancer2::Core::Request::Upload::open_file"}{CODE}; no warnings 'redefine'; *{"Dancer2::Core::Request::Upload::open_file"} = sub { croak "Can't open mocked-tempfile using mode '<'"; }; } $upload->{_fh} = undef; like( exception { $upload->file_handle }, qr{Can't open.* using mode '<'}, ); # unmock open_file { no strict 'refs'; no warnings 'redefine'; *{"Dancer2::Core::Request::Upload::open_file"} = $upload_file_coderef; } } unlink($file) if ( $^O eq 'MSWin32' ); }; } note "Run test with XS_URL_DECODE" if $Dancer2::Core::Request::XS_URL_DECODE; note "Run test with XS_PARSE_QUERY_STRING" if $Dancer2::Core::Request::XS_PARSE_QUERY_STRING; run_test(); if ($Dancer2::Core::Request::XS_PARSE_QUERY_STRING) { note "Run test without XS_PARSE_QUERY_STRING"; $Dancer2::Core::Request::XS_PARSE_QUERY_STRING = 0; $Dancer2::Core::Request::_count = 0; run_test(); } if ($Dancer2::Core::Request::XS_URL_DECODE) { note "Run test without XS_URL_DECODE"; $Dancer2::Core::Request::XS_URL_DECODE = 0; $Dancer2::Core::Request::_count = 0; run_test(); } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/app/0000775000175000017500000000000012650351107017111 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/app/t1/0000775000175000017500000000000012650351107017435 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/app/t1/lib/0000775000175000017500000000000012650351107020203 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/app/t1/lib/Sub/0000775000175000017500000000000012650351107020734 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/app/t1/lib/Sub/App2.pm0000644000175000017500000000007612650351107022075 0ustar gregoagregoapackage Sub::App2; use strict; use warnings; use Dancer2; 1; libdancer2-perl-0.166001+dfsg.orig/t/app/t1/lib/App1.pm0000644000175000017500000000007112650351107021336 0ustar gregoagregoapackage App1; use strict; use warnings; use Dancer2; 1; libdancer2-perl-0.166001+dfsg.orig/t/app/t1/config.yml0000644000175000017500000000002412650351107021417 0ustar gregoagregoaapp: config: ok libdancer2-perl-0.166001+dfsg.orig/t/app/t1/bin/0000775000175000017500000000000012650351107020205 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/app/t1/bin/app.psgi0000644000175000017500000000004712650351107021650 0ustar gregoagregoa#!perl use Dancer2; use App1; start; libdancer2-perl-0.166001+dfsg.orig/t/app/t2/0000775000175000017500000000000012650351107017436 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/app/t2/.dancer0000644000175000017500000000000112650351107020660 0ustar gregoagregoa libdancer2-perl-0.166001+dfsg.orig/t/app/t2/lib/0000775000175000017500000000000012650351107020204 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/app/t2/lib/App3.pm0000644000175000017500000000007012650351107021340 0ustar gregoagregoapackage App3; use strict; use warnings; use Dancer2; 1; libdancer2-perl-0.166001+dfsg.orig/t/app/t2/config.yml0000644000175000017500000000002412650351107021420 0ustar gregoagregoaapp: config: ok libdancer2-perl-0.166001+dfsg.orig/t/multi_apps.t0000644000175000017500000000177712650351107020705 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Builder; use Plack::Test; use HTTP::Request::Common; { package MyTestWiki; use Dancer2; get '/' => sub { __PACKAGE__ }; get '/wiki' => sub {'WIKI'}; package MyTestForum; use Dancer2; get '/' => sub { __PACKAGE__ }; get '/forum' => sub {'FORUM'}; } { my $app = builder { mount '/wiki' => MyTestWiki->to_app; mount '/forum' => MyTestForum->to_app; }; isa_ok( $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/wiki' )->content, 'MyTestWiki', "Got wiki root" ); is( $cb->( GET '/forum' )->content, 'MyTestForum', "Got forum root" ); }; } { my $app = Dancer2->psgi_app; isa_ok( $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/wiki' )->content, 'WIKI', 'Got /wiki path' ); is( $cb->( GET '/forum' )->content, 'FORUM', 'Got /forum path' ); }; } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/config.yml0000644000175000017500000000011312650351107020312 0ustar gregoagregoalog: "info" logger: "Note" plugins: "t::lib::FooPlugin": plugin: 42 libdancer2-perl-0.166001+dfsg.orig/t/session_object.t0000644000175000017500000000223312650351107021525 0ustar gregoagregoa# session_object.t use strict; use warnings; use Test::More; use Test::Fatal; use Dancer2::Core::Session; use Dancer2::Session::Simple; use Class::Load 'try_load_class'; my $ENGINE = Dancer2::Session::Simple->new; my $CPRNG_AVAIL = try_load_class('Math::Random::ISAAC::XS') && try_load_class('Crypt::URandom'); note $CPRNG_AVAIL ? "Crypto strength tokens" : "Default strength tokens"; subtest 'session attributes' => sub { my $s1 = $ENGINE->create; my $id = $s1->id; ok defined($id), 'id is defined'; is(exception { $s1->id("new_$id") }, undef, 'id can be set'); is($s1->id, "new_$id", '... new value found for id'); my $s2 = $ENGINE->create; isnt($s1->id, $s2->id, "IDs are not the same"); }; my $count = 10_000; subtest "$count session IDs and no dups" => sub { my $seen = {}; my $iteration = 0; foreach my $i (1 .. $count) { my $s1 = $ENGINE->create; my $id = $s1->id; if (exists $seen->{$id}) { last; } $seen->{$id} = 1; $iteration++; } is $iteration, $count, "no duplicate ID after $count iterations (done $iteration)"; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/forward_before_hook.t0000644000175000017500000000222312650351107022521 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass'], tests => 4; use Dancer2; use Plack::Test; use HTTP::Request::Common; get '/' => sub { return 'Forbidden'; }; get '/default' => sub { return 'Default'; }; get '/redirect' => sub { return 'Secret stuff never seen'; }; hook before => sub { return if request->dispatch_path eq '/default'; # Add some content to the response response->content("SillyStringIsSilly"); # redirect - response should include the above content return redirect '/default' if request->dispatch_path eq '/redirect'; # The response object will get replaced by the result of the forward. forward '/default'; }; my $app = __PACKAGE__->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; like( $cb->( GET '/' )->content, qr{Default}, 'forward in before hook', ); my $r = $cb->( GET '/redirect' ); # redirect in before hook is( $r->code, 302, 'redirect in before hook' ); is( $r->content, 'SillyStringIsSilly', '.. and the response content is correct', ); }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/uri_for.t0000644000175000017500000000077712650351107020174 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; get '/foo' => sub { return uri_for('/foo'); }; } my $app = App->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/foo' )->code, 200, '/foo code okay' ); is( $cb->( GET '/foo' )->content, 'http://localhost/foo', 'uri_for works as expected', ); }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/00-compile.t0000644000175000017500000001002512650351107020357 0ustar gregoagregoause 5.006; use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::Compile 2.054 use Test::More; plan tests => 58 + ($ENV{AUTHOR_TESTING} ? 1 : 0); my @module_files = ( 'Dancer2.pm', 'Dancer2/CLI.pm', 'Dancer2/CLI/Command/gen.pm', 'Dancer2/CLI/Command/version.pm', 'Dancer2/Core.pm', 'Dancer2/Core/App.pm', 'Dancer2/Core/Cookie.pm', 'Dancer2/Core/DSL.pm', 'Dancer2/Core/Dispatcher.pm', 'Dancer2/Core/Error.pm', 'Dancer2/Core/Factory.pm', 'Dancer2/Core/HTTP.pm', 'Dancer2/Core/Hook.pm', 'Dancer2/Core/MIME.pm', 'Dancer2/Core/Request.pm', 'Dancer2/Core/Request/Upload.pm', 'Dancer2/Core/Response.pm', 'Dancer2/Core/Response/Delayed.pm', 'Dancer2/Core/Role/ConfigReader.pm', 'Dancer2/Core/Role/DSL.pm', 'Dancer2/Core/Role/Engine.pm', 'Dancer2/Core/Role/Handler.pm', 'Dancer2/Core/Role/HasLocation.pm', 'Dancer2/Core/Role/Hookable.pm', 'Dancer2/Core/Role/Logger.pm', 'Dancer2/Core/Role/Serializer.pm', 'Dancer2/Core/Role/SessionFactory.pm', 'Dancer2/Core/Role/SessionFactory/File.pm', 'Dancer2/Core/Role/StandardResponses.pm', 'Dancer2/Core/Role/Template.pm', 'Dancer2/Core/Route.pm', 'Dancer2/Core/Runner.pm', 'Dancer2/Core/Session.pm', 'Dancer2/Core/Time.pm', 'Dancer2/Core/Types.pm', 'Dancer2/FileUtils.pm', 'Dancer2/Handler/AutoPage.pm', 'Dancer2/Handler/File.pm', 'Dancer2/Logger/Capture.pm', 'Dancer2/Logger/Capture/Trap.pm', 'Dancer2/Logger/Console.pm', 'Dancer2/Logger/Diag.pm', 'Dancer2/Logger/File.pm', 'Dancer2/Logger/Note.pm', 'Dancer2/Logger/Null.pm', 'Dancer2/Plugin.pm', 'Dancer2/Serializer/Dumper.pm', 'Dancer2/Serializer/JSON.pm', 'Dancer2/Serializer/Mutable.pm', 'Dancer2/Serializer/YAML.pm', 'Dancer2/Session/Simple.pm', 'Dancer2/Session/YAML.pm', 'Dancer2/Template/Implementation/ForkedTiny.pm', 'Dancer2/Template/Simple.pm', 'Dancer2/Template/TemplateToolkit.pm', 'Dancer2/Template/Tiny.pm', 'Dancer2/Test.pm' ); my @scripts = ( 'script/dancer2' ); # no fake home requested my $inc_switch = -d 'blib' ? '-Mblib' : '-Ilib'; use File::Spec; use IPC::Open3; use IO::Handle; open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!"; my @warnings; for my $lib (@module_files) { # see L my $stderr = IO::Handle->new; my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]"); binmode $stderr, ':crlf' if $^O eq 'MSWin32'; my @_warnings = <$stderr>; waitpid($pid, 0); is($?, 0, "$lib loaded ok"); shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/ and not eval { require blib; blib->VERSION('1.01') }; if (@_warnings) { warn @_warnings; push @warnings, @_warnings; } } foreach my $file (@scripts) { SKIP: { open my $fh, '<', $file or warn("Unable to open $file: $!"), next; my $line = <$fh>; close $fh and skip("$file isn't perl", 1) unless $line =~ /^#!\s*(?:\S*perl\S*)((?:\s+-\w*)*)(?:\s*#.*)?$/; my @flags = $1 ? split(' ', $1) : (); my $stderr = IO::Handle->new; my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, @flags, '-c', $file); binmode $stderr, ':crlf' if $^O eq 'MSWin32'; my @_warnings = <$stderr>; waitpid($pid, 0); is($?, 0, "$file compiled ok"); shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/ and not eval { require blib; blib->VERSION('1.01') }; # in older perls, -c output is simply the file portion of the path being tested if (@_warnings = grep { !/\bsyntax OK$/ } grep { chomp; $_ ne (File::Spec->splitpath($file))[2] } @_warnings) { warn @_warnings; push @warnings, @_warnings; } } } is(scalar(@warnings), 0, 'no warnings found') or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ) if $ENV{AUTHOR_TESTING}; libdancer2-perl-0.166001+dfsg.orig/t/logger.t0000644000175000017500000000425012650351107017774 0ustar gregoagregoause Test::More; use strict; use warnings; BEGIN { # Freeze time at Tue, 15-Jun-2010 00:00:00 GMT *CORE::GLOBAL::time = sub { return 1276560000 } } my $_logs = []; { package Dancer2::Logger::Test; use Moo; with 'Dancer2::Core::Role::Logger'; sub log { my ( $self, $level, $message ) = @_; push @$_logs, $self->format_message( $level, $message ); } } my $logger = Dancer2::Logger::Test->new( app_name => 'test' ); is $logger->log_level, 'debug'; $logger->debug("foo"); # Hard to make caller(6) work when we deal with the logger directly, # so do not check for a specific filename. like $_logs->[0], qr{debug \@2010-06-1\d \d\d:\d\d:00> foo in }; subtest 'log level and capture' => sub { use Dancer2::Logger::Capture; use Dancer2; # NOTE: this will read the config.yml under t/ that defines log level as info set logger => 'capture'; warning "Danger! Warning!"; info "Tango, Foxtrot"; debug "I like pie."; my $trap = dancer_app->engine('logger')->trapper; my $msg = $trap->read; delete $msg->[0]{'formatted'}; delete $msg->[1]{'formatted'}; is_deeply $msg, [ { level => "warning", message => "Danger! Warning!", }, { level => "info", message => "Tango, Foxtrot", }, ]; # each call to read cleans the trap is_deeply $trap->read, []; }; subtest 'logger file' => sub { use Dancer2; use File::Temp qw/tempdir/; my $dir = tempdir( CLEANUP => 1 ); set engines => { logger => { File => { log_dir => $dir, file_name => 'test', } } }; # XXX this sucks, we need to set the engine *before* the logger # - Franck, 2013/08/03 set logger => 'file'; warning "Danger! Warning!"; open my $log_file, '<', File::Spec->catfile($dir, 'test'); my $txt = <$log_file>; like $txt, qr/Danger! Warning!/; }; # Explicitly close the logger file handle for those systems that # do not allow "open" files to be unlinked (Windows). GH#424. my $log_engine = engine('logger'); close $log_engine->fh; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/scope_problems/0000775000175000017500000000000012650351107021345 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/scope_problems/views/0000775000175000017500000000000012650351107022502 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/scope_problems/views/500.tt0000644000175000017500000000003712650351107023355 0ustar gregoagregoaThis is a dummy error template libdancer2-perl-0.166001+dfsg.orig/t/scope_problems/dispatcher_internal_request.t0000644000175000017500000000124212650351107027321 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common qw/GET/; use Dancer2; { package Test::App; use Dancer2; use Data::Dumper; set behind_proxy => 1; set views => 't/views'; # The 'die' was causing the Runners' internal_request # object to not get cleaned up when returning from dispatch. hook before => sub { die "Nope, Nope, Nope" }; get '/' => sub { send_error "Yes yes YES!"; }; } my $test = Plack::Test->create(Dancer2->psgi_app); my $res = $test->request(GET '/'); is( Dancer2->runner->{'internal_request'}, undef, "Runner internal request cleaned up" ); done_testing; libdancer2-perl-0.166001+dfsg.orig/t/scope_problems/session_is_cleared.t0000644000175000017500000000377112650351107025375 0ustar gregoagregoa#!/usr/bin/env perl ## This test will first cause a (legitimate) error in a ## before_template_render hook ## Then it will fetch an unrelated route that should return normally. ## However, this route is now using the wrong with_return block. ## This is because the first route, errors in rendering the *error* page. ## This cause the block to die, and with_return is never unset. ## This test uses two template files package MyTestApp; use Dancer2; hook before_template_render => sub { my $path = request->path; if ( $path =~ m!route_with_renderer_error! ) { die session->id; } }; get '/route_with_renderer_error' => sub { ## This route first gets called, then template fires the above hook. ## This hook errors, causing Dancer2::Core::App, to throw an error ## which *also* fires the hook, crashing the server. session->write('bob' => "I SHOULD NOT BE IN THE NEXT SESSION"); my $tt = session->id; template \"$tt"; }; get '/normal_route' => sub { ## This should issue normally if ( !session('bob') ) { session('bob' => "test" . rand()); } return session('bob'); }; package main; use strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common qw/GET/; use Dancer2; my $test = Plack::Test->create(Dancer2->psgi_app); ## This route works fine ## Just a sanity check my $res1 = $test->request(GET '/normal_route'); ok($res1->is_success, '/normal_route does not error'); ## This route should die and cause a broken state my $res2 = $test->request(GET '/route_with_renderer_error'); ok(! $res2->is_success, '/route_with_renderer_error errors errors'); ## This route will now have the same session as the previous route. ## Despite not having any cookies... my $res3 = $test->request(GET '/normal_route'); ok($res3->is_success, '/normal_route does not error'); my $session_value = $res3->decoded_content; isnt($session_value, "I SHOULD NOT BE IN THE NEXT SESSION", '3rd route does not have session value from second route'); done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/scope_problems/config.yml0000644000175000017500000000001712650351107023331 0ustar gregoagregoalogger: "Note" libdancer2-perl-0.166001+dfsg.orig/t/scope_problems/keywords_before_template_hook.t0000644000175000017500000000165512650351107027643 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common qw/GET/; use File::Basename 'dirname'; use File::Spec; my $views; BEGIN { $views = File::Spec->rel2abs( File::Spec->catfile( dirname(__FILE__), 'views' ) ); } eval { require Template; Template->import(); 1 } or plan skip_all => 'Template::Toolkit probably missing.'; { package Test::App; use Dancer2; set views => $views; set logger => 'Note'; set template => 'template_toolkit'; hook before_template_render => sub { my $tokens = shift; var some_var => 21; # var can only be used in a route handler.. }; get '/' => sub { die "Yes yes YES!"; }; } my $test = Plack::Test->create(Test::App->to_app); my $res = $test->request(GET '/'); is($res->code, 500, "Got 500 response"); like( $res->content, qr/This is a dummy error template/, "with the template content" ); done_testing; libdancer2-perl-0.166001+dfsg.orig/t/scope_problems/with_return_dies.t0000644000175000017500000000476012650351107025115 0ustar gregoagregoa#!/usr/bin/env perl ## This test will first cause a (legitimate) error in a ## before_template_render hook ## Then it will fetch an unrelated route that should return normally. ## However, this route is now using the wrong with_return block. ## This is because the first route, errors in rendering the *error* page. ## This cause the block to die, and with_return is never unset. ## This test uses two template files package MyTestApp; use Dancer2; use Scalar::Util qw/refaddr/; hook before_template_render => sub { my $path = request->path; my $refadd = refaddr(app->with_return); if ( $path =~ m!route_with_renderer_error! ) { die $refadd; } }; get '/route_with_renderer_error' => sub { ## This route first gets called, then template fires the above hook. ## This hook errors, causing Dancer2::Core::App, to throw an error ## which *also* fires the hook, crashing the server. my $addr = refaddr(app->with_return); template \$addr; }; get '/normal_route' => sub { ## This should issue normally # my $addr = refaddr(app->with_return); # template \$addr; return refaddr(app->with_return); }; package main; use strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common qw/GET/; use Dancer2; my $test = Plack::Test->create(Dancer2->psgi_app); ## This route works fine my $res1 = $test->request(GET '/normal_route'); ok($res1->is_success, '/normal_route does not error'); my $refaddr1 = $res1->decoded_content; ## This route should die my $res2 = $test->request(GET '/route_with_renderer_error'); ok(! $res2->is_success, '/route_with_renderer_error errors errors'); my ($refaddr2) = $res2->decoded_content =~ /Hook error: (\d+)/; ## The first route now errors ## I can't seem to force with_return to fail in this test, even though I have ## it failing in production. ## So instead I'll check the refaddr of the with_return ## If refaddr of with_return is the same between route2 and route3, then this ## demonstrates that with_return has not been cleared between the two routes ## And that /normal_route is now using the wrong with_return. ## Possibly the old with_return hasn't been cleaned up? not sure. my $res3 = $test->request(GET '/normal_route'); ok($res3->is_success, '/normal_route does not error'); my $refaddr3 = $res3->decoded_content; isnt($refaddr1, $refaddr3, 'The 3rd request has a different with_return from the first run'); isnt($refaddr2, $refaddr3, 'The 3rd request has a different with_return from the second run'); done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/sessions/0000775000175000017500000000000012650351107020177 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg064wAAJ9kQ4eZCIrRZYn2MHmDG9gdR.yml0000644000175000017500000000000712650351107026004 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/VZnfBAAAM1uzNFM805U0WYIBH6g9O9sP.yml0000644000175000017500000000000712650351107025631 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/VZnfBAAAM1vX474E7L8-IKj6yGKXydT6.yml0000644000175000017500000000000712650351107025633 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg064wAAJ9lUqjejJGWqSsvCik0IMkXR.yml0000644000175000017500000000001612650351107026301 0ustar gregoagregoa--- name: one libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg064wAAJ9kplKAlXLoTRgcwpA4SHS7p.yml0000644000175000017500000000000712650351107026202 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/VZnmcwAAQCzAiy3r3BF_Y9nl17qh9xWZ.yml0000644000175000017500000000000712650351107026342 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg064wAAJ9laQxRh3IZuFLenkVBgIk9I.yml0000644000175000017500000000000712650351107026157 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/VZnjPwAAO6k-BdDf7U1asyu8L3IiwLPH.yml0000644000175000017500000000000712650351107026175 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/VZnjPwAAO6mvnV4jszDm0R5-aWeczZvi.yml0000644000175000017500000000000712650351107026514 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg064wAAJ9kdprsPF4Sv3csep-q5vNcS.yml0000644000175000017500000000002012650351107026254 0ustar gregoagregoa--- name: three libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg04TQAAIh7D5x7ePVh0dCf2cIkxpaxw.yml0000644000175000017500000000000712650351107026205 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg04TQAAIh5f8_rJkoZU-jF0X0Ju1tUT.yml0000644000175000017500000000002012650351107026011 0ustar gregoagregoa--- name: three libdancer2-perl-0.166001+dfsg.orig/t/sessions/VZnmcwAAQCxW6LW-ZL8Xt8U8jJfvzYQE.yml0000644000175000017500000000000712650351107026264 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/VZnjPwAAO6k9bW5FauLnPe6HtecLdTl7.yml0000644000175000017500000000000712650351107026320 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg04TQAAIh5ip4atDSSzR5k8O0kUe8xe.yml0000644000175000017500000000000712650351107026123 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg04TQAAIh6p0AWJuzbIW1SGm4EYmG3M.yml0000644000175000017500000000001612650351107025734 0ustar gregoagregoa--- name: one libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg04TQAAIh5Z2I-GTU_wKFHO4feGKLE_.yml0000644000175000017500000000000712650351107025633 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/VZnfBAAAM1tKFkfDZ4IUwyKrWceQJRkE.yml0000644000175000017500000000000712650351107026262 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg064wAAJ9kOJP85EngBszwmwHbWlNSI.yml0000644000175000017500000000001612650351107026213 0ustar gregoagregoa--- name: two libdancer2-perl-0.166001+dfsg.orig/t/sessions/Vg04TQAAIh6LD69zbMVWaoqIU23Crkdm.yml0000644000175000017500000000001612650351107026065 0ustar gregoagregoa--- name: two libdancer2-perl-0.166001+dfsg.orig/t/sessions/VZnmcwAAQCzZczgTm1OVACmWHKa_8Ba3.yml0000644000175000017500000000000712650351107026317 0ustar gregoagregoa--- {} libdancer2-perl-0.166001+dfsg.orig/t/session_config.t0000644000175000017500000000400712650351107021525 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Cookies; use HTTP::Request::Common; { package App; use Dancer2; setting( engines => { session => { Simple => { cookie_name => 'dancer.sid', cookie_path => '/foo', cookie_duration => '1 hour', is_http_only => 0, # will not show up in cookie }, }, } ); setting( session => 'Simple' ); get '/has_session' => sub { return app->has_session; }; get '/foo/set_session/*' => sub { my ($name) = splat; session name => $name; }; get '/foo/read_session' => sub { my $name = session('name') || ''; "name='$name'"; }; get '/foo/destroy_session' => sub { my $name = session('name') || ''; app->destroy_session; return "destroyed='$name'"; }; } my $test = Plack::Test->create( App->to_app ); my $url = 'http://localhost'; my $jar = HTTP::Cookies->new; subtest 'Set session' => sub { my $res = $test->request( GET "$url/foo/set_session/larry" ); ok( $res->is_success, '/foo/set_session/larry' ); $jar->extract_cookies($res); ok( $jar->as_string, 'session cookie set' ); my ( $expires, $domain, $path, $opts ); my $cookie = $jar->scan( sub { ( $expires, $domain, $path, $opts ) = @_[ 8, 4, 3 ]; } ); my $httponly = $opts->{'HttpOnly'}; ok $expires - time > 3540, "cookie expiration is in future"; is $domain, 'localhost.local', "cookie domain set"; is $path, '/foo', "cookie path set"; is $httponly, undef, "cookie has not set HttpOnly"; # read value back }; subtest 'Read session' => sub { my $req = GET "$url/foo/read_session"; $jar->add_cookie_header($req); my $res = $test->request($req); ok $res->is_success, "/foo/read_session"; like $res->content, qr/name='larry'/, "session value looks good"; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/http_methods.t0000644000175000017500000000242212650351107021216 0ustar gregoagregoause strict; use warnings; use Test::More tests => 12; use Plack::Test; use HTTP::Request; use Dancer2; my %method = ( get => 'GET', post => 'POST', del => 'DELETE', patch => 'PATCH', put => 'PUT', options => 'OPTIONS', ); my $app = __PACKAGE__->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; while ( my ( $method, $http ) = each %method ) { eval "$method '/' => sub { '$method' }"; is( $cb->( HTTP::Request->new( $http => '/' ) )->content, $method, "$http /", ); } eval "get '/head' => sub {'HEAD'}"; my $res = $cb->( HTTP::Request->new( HEAD => '/head' ) ); is( $res->content, '', 'HEAD /' ); # HEAD requests have no content is( $res->headers->content_length, 4, 'Content-Length for HEAD' ); # Testing invalid HTTP methods. { my $req = HTTP::Request->new( "ILLEGAL" => '/' ); my $res = $cb->( $req ); ok( !$res->is_success, "Response->is_success is false when using illegal HTTP method" ); is( $res->code, 405, "Illegal method should return 405 code" ); like( $res->content, qr, q ); } }; libdancer2-perl-0.166001+dfsg.orig/t/request_make_forward_to.t0000644000175000017500000000130612650351107023427 0ustar gregoagregoause strict; use warnings; use Test::More tests=>1; use Plack::Test; use HTTP::Request::Common; use JSON; { package ContentLengthTestApp; use Dancer2; set serializer => 'JSON'; post '/foo' => sub { forward('/not_authorized'); }; any '/not_authorized' => sub { status 401; { access => 'denied' }; }; } { my $url = 'http://localhost'; my $test = Plack::Test->create( ContentLengthTestApp->to_app ); my $response = $test->request( POST( '/foo', Content => encode_json( { target => [ 'foo', 'bar' ] } ), ) ); is( $response->code, 401, 'Access denied to unauthorized merge' ); } libdancer2-perl-0.166001+dfsg.orig/t/00-report-prereqs.dd0000644000175000017500000001115212650351107022047 0ustar gregoagregoado { my $x = { 'configure' => { 'requires' => { 'ExtUtils::MakeMaker' => '0', 'File::ShareDir::Install' => '0.06' } }, 'develop' => { 'requires' => { 'Test::CPAN::Meta' => '0', 'Test::More' => '0', 'Test::NoTabs' => '0', 'Test::Pod' => '1.41' } }, 'runtime' => { 'recommends' => { 'CGI::Deurl::XS' => '0', 'Crypt::URandom' => '0', 'JSON::XS' => '0', 'Math::Random::ISAAC::XS' => '0', 'Pod::Simple::Search' => '0', 'Pod::Simple::SimpleTree' => '0', 'Scope::Upper' => '0', 'Test::Builder' => '0', 'Test::More' => '0', 'URL::Encode::XS' => '0' }, 'requires' => { 'App::Cmd::Setup' => '0', 'Carp' => '0', 'Class::Load' => '0', 'Config::Any' => '0', 'Digest::SHA' => '0', 'Encode' => '0', 'Exporter' => '5.57', 'File::Basename' => '0', 'File::Copy' => '0', 'File::Spec' => '0', 'HTTP::Body' => '0', 'HTTP::Date' => '0', 'HTTP::Headers::Fast' => '0', 'HTTP::Tiny' => '0', 'Hash::Merge::Simple' => '0', 'Import::Into' => '0', 'JSON' => '0', 'MIME::Base64' => '3.13', 'Moo' => '2.000000', 'Moo::Role' => '0', 'MooX::Types::MooseLike' => '0', 'POSIX' => '0', 'Plack' => '1.0035', 'Plack::Middleware::FixMissingBodyInRedirect' => '0', 'Plack::Middleware::RemoveRedundantBody' => '0', 'Return::MultiLevel' => '0', 'Role::Tiny' => '2.000000', 'Safe::Isa' => '0', 'Template::Tiny' => '0', 'URI::Escape' => '0', 'parent' => '0' }, 'suggests' => { 'Class::Load::XS' => '0', 'Fcntl' => '0', 'MIME::Types' => '0', 'YAML' => '0.86' } }, 'test' => { 'recommends' => { 'CPAN::Meta' => '2.120900' }, 'requires' => { 'Capture::Tiny' => '0.12', 'ExtUtils::MakeMaker' => '0', 'File::Spec' => '0', 'HTTP::Body' => '0', 'HTTP::Cookies' => '0', 'HTTP::Headers' => '0', 'IO::Handle' => '0', 'IPC::Open3' => '0', 'Template' => '0', 'Test::Fatal' => '0', 'Test::More' => '0.92', 'YAML' => '0.86' } } }; $x; }libdancer2-perl-0.166001+dfsg.orig/t/psgi_app_forward_and_pass.t0000644000175000017500000000146712650351107023722 0ustar gregoagregoa#!/usr/bin/env perl use strict; use warnings; use Test::More tests => 4; use Plack::Test; use HTTP::Request::Common; { package App1; use Dancer2; get '/' => sub {'App1'}; } { package App2; use Dancer2; get '/pass' => sub { pass }; } { package App3; use Dancer2; get '/pass' => sub {'App3'}; get '/forward' => sub { forward '/' }; } # pass from App2 to App3 # forward from App3 to App1 my $app = Dancer2->psgi_app; isa_ok( $app, 'CODE' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/' )->content, 'App1', 'Simple request' ); is( $cb->( GET '/pass' )->content, 'App3', 'Passing from App to App works', ); is( $cb->( GET '/forward' )->content, 'App1', 'Forwarding from App to App works', ); }; libdancer2-perl-0.166001+dfsg.orig/t/dancer-test.t0000644000175000017500000000755112650351107020735 0ustar gregoagregoa# who test the tester? We do! use strict; use warnings; use File::Spec; use File::Basename qw/dirname/; BEGIN { # Disable route handlers so we can actually test route_exists # and route_doesnt_exist. Use config that disables default route handlers. $ENV{DANCER_CONFDIR} = File::Spec->catdir(dirname(__FILE__), 'dancer-test'); } use Test::More tests => 49; use Dancer2; use Dancer2::Test; use Dancer2::Core::Request; use File::Temp; use Encode; use URI::Escape; $Dancer2::Test::NO_WARN = 1; my @routes = ( '/foo', [ GET => '/foo' ], Dancer2::Core::Request->new( env => { 'psgi.url_scheme' => 'http', REQUEST_METHOD => 'GET', QUERY_STRING => '', SERVER_NAME => 'localhost', SERVER_PORT => 5000, SERVER_PROTOCOL => 'HTTP/1.1', SCRIPT_NAME => '', PATH_INFO => '/foo', REQUEST_URI => '/foo', } ), ); my $fighter = Dancer2::Core::Response->new( content => 'fighter', status => 404, ); route_doesnt_exist $_ for (@routes, $fighter); get '/foo' => sub {'fighter'}; route_exists $_, "route $_ exists" for @routes; $fighter->status(200); push @routes, $fighter; for (@routes) { my $response = dancer_response $_; isa_ok $response => 'Dancer2::Core::Response'; is $response->content => 'fighter'; } response_content_is $_ => 'fighter', "response_content_is with $_" for @routes; response_content_isnt $_ => 'platypus', "response_content_isnt with $_" for @routes; response_content_like $_ => qr/igh/ for @routes; response_content_unlike $_ => qr/ought/ for @routes; response_status_is $_ => 200 for @routes; response_status_isnt $_ => 203 for @routes; response_headers_include $_ => [ Server => "Perl Dancer2 " . Dancer2->VERSION ] for @routes; ## Check parameters get through ok get '/param' => sub { param('test') }; my $param_response = dancer_response( GET => '/param', { params => { test => 'hello' } } ); is $param_response->content, 'hello', 'PARAMS get echoed by route'; post '/upload' => sub { my $file = upload('test'); return $file->content; }; ## Check we can upload files my $file_response = dancer_response( POST => '/upload', { files => [ { filename => 'test.txt', name => 'test', data => 'testdata' } ] } ); is $file_response->content, 'testdata', 'file uploaded with supplied data'; my $temp = File::Temp->new; print $temp 'testfile'; close($temp); $file_response = dancer_response( POST => '/upload', { files => [ { filename => $temp->filename, name => 'test' } ] } ); is $file_response->content, 'testfile', 'file uploaded with supplied filename'; ## Check multiselect/multi parameters get through ok get '/multi' => sub { my $t = param('test'); return 'bad' if ref($t) ne 'ARRAY'; my $p = join( '', @$t ); return $p; }; $param_response = dancer_response( GET => '/multi', { params => { test => [ 'foo', 'bar' ] } } ); is $param_response->content, 'foobar', 'multi values for same key get echoed back'; my $russian_test = decode( 'UTF-8', uri_unescape("%D0%B8%D1%81%D0%BF%D1%8B%D1%82%D0%B0%D0%BD%D0%B8%D0%B5") ); $param_response = dancer_response( GET => '/multi', { params => { test => [ 'test/', $russian_test ] } } ); is $param_response->content, 'test/' . encode( 'UTF-8', $russian_test ), 'multi utf8 value properly merge'; get '/headers' => sub { join " : ", request->header('X-Sent-By'), request->cookies->{foo}; }; note "extra headers in request"; { my $sent_by = 'Dancer2::Test'; my $headers_test = dancer_response( GET => '/headers', { headers => [ [ 'X-Sent-By' => $sent_by ], [ 'Cookie' => "foo=bar" ], ], } ); is $headers_test->content, "$sent_by : bar", "extra headers included in request"; } libdancer2-perl-0.166001+dfsg.orig/t/psgi_app.t0000644000175000017500000000436312650351107020324 0ustar gregoagregoa#!perl use strict; use warnings; use Test::More tests => 25; use Plack::Test; use HTTP::Request::Common; { package App1; use Dancer2; get '/1' => sub {1}; } { package App2; use Dancer2; get '/2' => sub {2}; } { package App3; use Dancer2; get '/3' => sub {3}; } sub is_available { my ( $cb, @apps ) = @_; foreach my $app (@apps) { is( $cb->( GET "/$app" )->content, $app, "App$app available" ); } } sub isnt_available { my ( $cb, @apps ) = @_; foreach my $app (@apps) { is( $cb->( GET "/$app" )->code, 404, "App$app is not available", ); } } note 'All Apps'; { my $app = Dancer2->psgi_app; isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; is_available( $cb, 1, 2, 3 ); }; } note 'Specific Apps by parameters'; { my @apps = @{ Dancer2->runner->apps }[ 0, 2 ]; is( scalar @apps, 2, 'Took two apps from the Runner' ); my $app = Dancer2->psgi_app(\@apps); isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; is_available( $cb, 1, 3 ); isnt_available( $cb, 2 ); }; } note 'Specific Apps via App objects'; { my $app = App2->psgi_app; isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; is_available( $cb, 2 ); isnt_available( $cb, 1, 3 ); }; }; note 'Specific apps by App names'; { my $app = Dancer2->psgi_app( [ 'App1', 'App3' ] ); isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; isnt_available( $cb, 2 ); is_available( $cb, 1, 3 ); }; } note 'Specific apps by App names with regular expression, v1'; { my $app = Dancer2->psgi_app( [ qr/^App1$/, qr/^App3$/ ] ); isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; isnt_available( $cb, 2 ); is_available( $cb, 1, 3 ); }; } note 'Specific apps by App names with regular expression, v2'; { my $app = Dancer2->psgi_app( [ qr/^App(2|3)$/ ] ); isa_ok( $app, 'CODE', 'Got PSGI app' ); test_psgi $app, sub { my $cb = shift; isnt_available( $cb, 1 ); is_available( $cb, 2, 3 ); }; } libdancer2-perl-0.166001+dfsg.orig/t/plugin_import.t0000644000175000017500000000220112650351107021377 0ustar gregoagregoa# plugin_import.t use strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; { use Dancer2; use t::lib::PluginWithImport; get '/test' => sub { dancer_plugin_with_import_keyword; }; } my $app = __PACKAGE__->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/test' )->content, 'dancer_plugin_with_import_keyword', 'the plugin exported its keyword', ); }; is_deeply( t::lib::PluginWithImport->stuff, { 't::lib::PluginWithImport' => 'imported' }, "the original import method of the plugin is still there" ); subtest 'import flags' => sub { eval " package Some::Plugin; use Dancer2::Plugin ':no_dsl'; register 'foo' => sub { request }; "; like $@, qr{Bareword "request" not allowed while "strict subs"}, "with :no_dsl, the Dancer's dsl is not imported."; eval " package Some::Plugin; use Dancer2::Plugin; register 'foo' => sub { request }; "; is $@, '', "without any import flag, the DSL is imported"; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/request.t0000644000175000017500000002314212650351107020206 0ustar gregoagregoause strict; use warnings; use Test::More; use Dancer2::Core::App; use Dancer2::Core::Request; diag "If you want extra speed, install URL::Encode::XS" if !$Dancer2::Core::Request::XS_URL_DECODE; diag "If you want extra speed, install CGI::Deurl::XS" if !$Dancer2::Core::Request::XS_PARSE_QUERY_STRING; sub run_test { my $env = { 'psgi.url_scheme' => 'http', REQUEST_METHOD => 'GET', SCRIPT_NAME => '/foo', PATH_INFO => '/bar/baz', REQUEST_URI => '/foo/bar/baz', QUERY_STRING => 'foo=42&bar=12&bar=13&bar=14', SERVER_NAME => 'localhost', SERVER_PORT => 5000, SERVER_PROTOCOL => 'HTTP/1.1', REMOTE_ADDR => '127.0.0.1', HTTP_X_FORWARDED_FOR => '127.0.0.2', HTTP_X_FORWARDED_HOST => 'secure.frontend', HTTP_X_FORWARDED_PROTOCOL => 'https', REMOTE_HOST => 'localhost', HTTP_USER_AGENT => 'Mozilla', REMOTE_USER => 'sukria', HTTP_COOKIE => 'cookie.a=foo=bar; cookie.b=1234abcd; no.value.cookie', }; my $req = Dancer2::Core::Request->new( env => $env ); note "tests for accessors"; is $req->agent, 'Mozilla'; is $req->user_agent, 'Mozilla'; is $req->remote_address, '127.0.0.1'; is $req->address, '127.0.0.1'; is $req->forwarded_for_address, '127.0.0.2'; is $req->remote_host, 'localhost'; is $req->protocol, 'HTTP/1.1'; is $req->port, 5000; is $req->request_uri, '/foo/bar/baz'; is $req->uri, '/foo/bar/baz'; is $req->user, 'sukria'; is $req->script_name, '/foo'; is $req->scheme, 'http'; is $req->referer, undef; ok( !$req->secure ); is $req->method, 'GET'; is $req->request_method, 'GET'; ok( $req->is_get ); ok( !$req->is_post ); ok( !$req->is_put ); ok( !$req->is_delete ); ok( !$req->is_patch ); ok( !$req->is_head ); is $req->id, 1; is $req->to_string, '[#1] GET /bar/baz'; note "tests params"; is_deeply { $req->params }, { foo => 42, bar => [ 12, 13, 14 ] }; note "tests cookies"; is( keys %{ $req->cookies }, 3, "multiple cookies extracted" ); my $forward = Dancer2::Core::App->new( request => $req ) ->make_forward_to('/somewhere'); is $forward->path_info, '/somewhere'; is $forward->method, 'GET'; note "tests for uri_for"; is $req->base, 'http://localhost:5000/foo'; is $req->uri_for( 'bar', { baz => 'baz' } ), 'http://localhost:5000/foo/bar?baz=baz'; is $req->uri_for('/bar'), 'http://localhost:5000/foo/bar'; is $req->uri_for( '/bar', undef, 1 ), 'http://localhost:5000/foo/bar', 'uri_for returns a URI (with $dont_escape)'; is $req->request_uri, '/foo/bar/baz'; is $req->path_info, '/bar/baz'; { local $env->{SCRIPT_NAME} = ''; is $req->uri_for('/foo'), 'http://localhost:5000/foo'; } { local $env->{SERVER_NAME} = 0; is $req->base, 'http://0:5000/foo'; local $env->{HTTP_HOST} = 'oddhostname:5000'; is $req->base, 'http://oddhostname:5000/foo'; } note "testing behind proxy"; { my $req = Dancer2::Core::Request->new( env => $env, is_behind_proxy => 1 ); is $req->secure, 1; is $req->host, $env->{HTTP_X_FORWARDED_HOST}; is $req->scheme, 'https'; } note "testing behind proxy when optional headers are not set"; { # local modifications to env: local $env->{HTTP_HOST} = 'oddhostname:5000'; delete local $env->{'HTTP_X_FORWARDED_FOR'}; delete local $env->{'HTTP_X_FORWARDED_HOST'}; delete local $env->{'HTTP_X_FORWARDED_PROTOCOL'}; my $req = Dancer2::Core::Request->new( env => $env, is_behind_proxy => 1 ); is ! $req->secure, 1; is $req->host, 'oddhostname:5000'; is $req->scheme, 'http'; } note "testing path, dispatch_path and uri_base"; { # Base env used for path, dispatch_path and uri_base tests my $base = { 'psgi.url_scheme' => 'http', REQUEST_METHOD => 'GET', QUERY_STRING => '', SERVER_NAME => 'localhost', SERVER_PORT => 5000, SERVER_PROTOCOL => 'HTTP/1.1', }; # PATH_INFO not set my $env = { %$base, SCRIPT_NAME => '/foo', PATH_INFO => '', REQUEST_URI => '/foo', }; my $req = Dancer2::Core::Request->new( env => $env ); is( $req->path, '/', 'path corrent when empty PATH_INFO' ); is( $req->uri_base, 'http://localhost:5000/foo', 'uri_base correct when empty PATH_INFO' ); is( $req->dispatch_path, '/', 'dispatch_path correct when empty PATH_INFO' ); # SCRIPT_NAME not set $env = { %$base, SCRIPT_NAME => '', PATH_INFO => '/foo', REQUEST_URI => '/foo', }; $req = Dancer2::Core::Request->new( env => $env ); is( $req->path, '/foo', 'path corrent when empty SCRIPT_NAME' ); is( $req->uri_base, 'http://localhost:5000', 'uri_base handles empty SCRIPT_NAME' ); is( $req->dispatch_path, '/foo', 'dispatch_path handles empty SCRIPT_NAME' ); # Both SCRIPT_NAME and PATH_INFO set # PSGI spec does not allow SCRIPT_NAME='/', PATH_INFO='/some/path' $env = { %$base, SCRIPT_NAME => '/foo', PATH_INFO => '/bar/baz/', REQUEST_URI => '/foo/bar/baz/', }; $req = Dancer2::Core::Request->new( env => $env ); is( $req->path, '/bar/baz/', 'path corrent when both PATH_INFO and SCRIPT_NAME set' ); is( $req->uri_base, 'http://localhost:5000/foo', 'uri_base correct when both PATH_INFO and SCRIPT_NAME set', ); is( $req->dispatch_path, '/bar/baz/', 'dispatch_path correct when both PATH_INFO and SCRIPT_NAME set' ); # Neither SCRIPT_NAME or PATH_INFO set $env = { %$base, SCRIPT_NAME => '', PATH_INFO => '', REQUEST_URI => '/foo/', }; $req = Dancer2::Core::Request->new( env => $env ); is( $req->path, '/', 'path corrent when calculated from REQUEST_URI' ); is( $req->uri_base, 'http://localhost:5000', 'uri_base correct when calculated from REQUEST_URI', ); is( $req->dispatch_path, '/', 'dispatch_path correct when calculated from REQUEST_URI' ); } note "testing forward"; $env = { 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/', 'PATH_INFO' => '/', 'QUERY_STRING' => 'foo=bar&number=42', }; $req = Dancer2::Core::Request->new( env => $env ); is $req->path, '/', 'path is /'; is $req->method, 'GET', 'method is get'; is_deeply scalar( $req->params ), { foo => 'bar', number => 42 }, 'params are parsed'; $req = Dancer2::Core::App->new( request => $req ) ->make_forward_to('/new/path'); is $req->path, '/new/path', 'path is changed'; is $req->method, 'GET', 'method is unchanged'; is_deeply scalar( $req->params ), { foo => 'bar', number => 42 }, 'params are not touched'; $req = Dancer2::Core::App->new( request => $req ) ->make_forward_to( '/new/path', undef, { method => 'POST' }, ); is $req->path, '/new/path', 'path is changed'; is $req->method, 'POST', 'method is changed'; is_deeply scalar( $req->params ), { foo => 'bar', number => 42 }, 'params are not touched'; note "testing unicode params"; $env = { 'REQUEST_METHOD' => 'GET', 'REQUEST_URI' => '/', 'PATH_INFO' => '/', 'QUERY_STRING' => "M%C3%BCller=L%C3%BCdenscheid", }; $req = Dancer2::Core::Request->new( env => $env ); is_deeply scalar( $req->params ), { "M\N{U+00FC}ller", "L\N{U+00FC}denscheid" }, 'multi byte unicode chars work in param keys and values'; { note "testing private _decode not to mangle hash"; my @warnings; local $SIG{__WARN__} = sub { push @warnings, @_; }; my $h = { zzz => undef, }; for ( 'aaa' .. 'fff' ) { $h->{$_} = $_; } my $i = Dancer2::Core::Request::_decode($h); is_deeply( $i, $h, 'hash not mangled' ); ok( !@warnings, 'no warnings were issued' ); } } note "Run test with XS_URL_DECODE" if $Dancer2::Core::Request::XS_URL_DECODE; note "Run test with XS_PARSE_QUERY_STRING" if $Dancer2::Core::Request::XS_PARSE_QUERY_STRING; run_test(); if ($Dancer2::Core::Request::XS_PARSE_QUERY_STRING) { note "Run test without XS_PARSE_QUERY_STRING"; $Dancer2::Core::Request::XS_PARSE_QUERY_STRING = 0; $Dancer2::Core::Request::_id = 0; run_test(); } if ($Dancer2::Core::Request::XS_URL_DECODE) { note "Run test without XS_URL_DECODE"; $Dancer2::Core::Request::XS_URL_DECODE = 0; $Dancer2::Core::Request::_id = 0; run_test(); } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/plugin_syntax.t0000644000175000017500000000721712650351107021427 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Plack::Test; use HTTP::Request::Common; use JSON; subtest 'global and route keywords' => sub { { package App1; use Dancer2; use t::lib::FooPlugin; sub location {'/tmp'} get '/' => sub { foo_wrap_request->env->{'PATH_INFO'}; }; get '/app' => sub { app->name }; get '/plugin_setting' => sub { to_json(p_config) }; foo_route; } my $app = App1->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/' )->content, '/', 'route defined by a plugin', ); is( $cb->( GET '/foo' )->content, 'foo', 'DSL keyword wrapped by a plugin', ); is( $cb->( GET '/plugin_setting' )->content, encode_json( { plugin => "42" } ), 'plugin_setting returned the expected config' ); is( $cb->( GET '/app' )->content, 'App1', 'app name is correct', ); }; }; subtest 'plugin old syntax' => sub { { package App2; use Dancer2; use t::lib::DancerPlugin; around_get; } my $app = App2->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/foo/plugin' )->content, 'foo plugin', 'foo plugin', ); }; }; subtest caller_dsl => sub { my $app = App1->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/sitemap' )->content, '^\/$, ^\/app$, ^\/foo$, ^\/foo\/plugin$, ^\/plugin_setting$, ^\/sitemap$', 'Correct content', ); }; }; subtest 'hooks in plugins' => sub { my $counter = 0; { package App3; use Dancer2; use t::lib::OnPluginImport; use t::lib::Hookee; use t::lib::EmptyPlugin; hook 'third_hook' => sub { var( hook => 'third hook' ); }; hook 'start_hookee' => sub { 'this is the start hook'; }; get '/hook_with_var' => sub { some_other(); # executes 'third_hook' ::is var('hook') => 'third hook', "Vars preserved from hooks"; }; get '/hooks_plugin' => sub { $counter++; some_keyword(); # executes 'start_hookee' 'hook for plugin'; }; get '/hook_returns_stuff' => sub { some_keyword(); # executes 'start_hookee' }; get '/on_import' => sub { some_import(); # execute 'plugin_import' } } my $app = App3->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $counter, 0, 'the hook has not been executed' ); is( $cb->( GET '/hooks_plugin' )->content, 'hook for plugin', '... route is rendered', ); is( $counter, 1, '... and the hook has been executed exactly once' ); is( $cb->( GET '/hook_returns_stuff' )->content, '', '... hook does not influence rendered content by return value', ); # call the route that has an additional test $cb->( GET '/hook_with_var' ); is ( $cb->( GET '/on_import' )->content, Dancer2->VERSION, 'hooks added by on_plugin_import dont stop hooks being added later' ); }; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/serializer_mutable.t0000644000175000017500000000532212650351107022400 0ustar gregoagregoause strict; use warnings; use Test::More tests => 41; use Dancer2::Serializer::Mutable; use Plack::Test; use HTTP::Request::Common; use Encode; use JSON; use YAML; { package MyApp; use Dancer2; set serializer => 'Mutable'; get '/serialize' => sub { +{ bar => 'baz' } }; post '/deserialize' => sub { return request->data && ref request->data eq 'HASH' && request->data->{bar} ? { bar => request->data->{bar} } : { ret => '?' }; }; } my $app = MyApp->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; # Configure all test cases my $d = { yaml => { types => [ qw(text/x-yaml text/html) ], value => encode('UTF-8', YAML::Dump({ bar => 'baz' })), last_val => "---bar:baz", }, dumper => { types => [ qw(text/x-data-dumper) ], value => Data::Dumper::Dumper({ bar => 'baz' }), last_val => "\$VAR1={'bar'=>'baz'};", }, json => { types => [ qw(text/x-json application/json) ], value => JSON::to_json({ bar => 'baz' }), last_val => '{"bar":"baz"}', }, }; { for my $format (keys %$d) { note("Format: $format"); my $s = $d->{$format}; # Response with implicit call to the serializer for my $content_type ( @{ $s->{types} } ) { for my $ct (qw/Content-Type Accept/) { # Test getting the value serialized in the correct format my $res = $cb->( GET '/serialize', $ct => $content_type ); is( $res->code, 200, "[/$format] Correct status" ); is( $res->content, $s->{value}, "[/$format] Correct content" ); is( $res->headers->content_type, $content_type, "[/$format] Correct content-type headers", ); } # Test sending the value serialized in the correct format # needs to be de-serialized and returned my $req = $cb->( POST '/deserialize', 'Content-Type' => $content_type, content => $s->{value} ); my $content = $req->content; $content =~ s/\s//g; is( $req->code, 200, "[/$format] Correct status" ); is( $content, $s->{last_val}, "[/$format] Correct content" ); } #/ for my $content_type } #/ for my $format } } libdancer2-perl-0.166001+dfsg.orig/t/issues/0000775000175000017500000000000012650351107017644 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-797.t0000644000175000017500000000236512650351107020757 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; use JSON; { package App; use Dancer2; set serializer => 'JSON'; post '/' => sub { my $post_params = params('body'); # should work even with empty post body my $foo = $post_params->{'foo'}; return { foo => $foo }; }; } my $test = Plack::Test->create( App->to_app ); my %headers; subtest 'Basic response failing' => sub { TODO: { local $TODO = '500 when deserializing bad input'; my $res = $test->request( POST '/', { foo => 'bar' }, %headers ); is( $res->code, 500, '[POST /] Failed when sending regular params' ); } }; subtest 'Basic response' => sub { my $res = $test->request( POST '/', %headers, Content => encode_json { foo => 'bar' } ); is( $res->code, 200, '[POST /] Correct response code' ); my $response_data = decode_json( $res->decoded_content ); is($response_data->{foo}, 'bar', "[POST /] Correct response data"); }; subtest 'Empty POST' => sub { my $res = $test->request( POST '/', {}, %headers ); is( $res->code, 200, '[POST /] Correct response code with empty post body', ); }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-1070.t0000644000175000017500000000074412650351107021017 0ustar gregoagregoause strict; use warnings; use Test::More tests => 2; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; set show_errors => 1; } my $test = Plack::Test->create( App->to_app ); my $content = $test->request( GET '/nonexistent_pathcrazy' )->content; like $content, qr{/nonexistent_path<strong>crazy</strong>}, "Escaped message"; unlike $content, qr{/nonexistent_pathcrazy}, "No unescaped message"; libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-936/0000775000175000017500000000000012650351107020561 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-936/views/0000775000175000017500000000000012650351107021716 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-936/views/error.tt0000644000175000017500000000004212650351107023412 0ustar gregoagregoa*CUSTOM ERROR TEMPLATE GOES HERE* libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-762/0000775000175000017500000000000012650351107020556 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-762/views/0000775000175000017500000000000012650351107021713 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-762/views/404.tt0000644000175000017500000000010012650351107022560 0ustar gregoagregoaTemplate selected. message: [% content %] status: [% status %] libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-936.t0000644000175000017500000000122012650351107020737 0ustar gregoagregoause warnings; use strict; use Test::More; use Plack::Test; use HTTP::Request::Common; { package TestApp; use Dancer2; set views => 't/issues/gh-936/views'; set error_template => 'error'; get '/does-not-exist' => sub { send_error "not found", 404; }; } my $test = Plack::Test->create( Dancer2->psgi_app ); for my $path ( qw{does-not-exist anywhere} ) { subtest "$path" => sub { my $res = $test->request( GET "/$path" ); is $res->code, 404, 'status is 404'; like $res->content, qr{CUSTOM ERROR TEMPLATE GOES HERE}, 'Error message looks good'; }; } done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-762.t0000644000175000017500000000176012650351107020745 0ustar gregoagregoause Test::More; use Plack::Test; use HTTP::Request::Common; { package FourOhFour; use Dancer2; set views => 't/issues/gh-762/views'; get '/error' => sub { send_error "oh my", 404; }; } my $fourohfour_app = FourOhFour->to_app; my $fourohfour_test = Plack::Test->create($fourohfour_app); subtest "/error" => sub { my $res = $fourohfour_test->request( GET '/error' ); is $res->code, 404, 'send_error sets the status to 404'; like $res->content, qr{Template selected}, 'Error message looks good'; like $res->content, qr{message: oh my}; like $res->content, qr{status: 404}; }; subtest 'FourOhFour with views template' => sub { my $path = "/middle/of/nowhere"; my $res = $fourohfour_test->request( GET $path ); is $res->code, 404, 'unknown route => 404'; like $res->content, qr{Template selected}, 'Error message looks good'; like $res->content, qr{message: $path}; like $res->content, qr{status: 404}; }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-799.t0000644000175000017500000000313412650351107020754 0ustar gregoagregoause strict; use warnings; use Test::More tests => 1; use Test::Fatal; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; set log => 'core'; set engines => { logger => { Capture => { log_format => '%{x-test}h %i' } }, }; set logger => 'Capture'; get '/' => sub { my $req = app->request; ::isa_ok( $req, 'Dancer2::Core::Request' ); my $logger = app->engine('logger'); ::isa_ok( $logger, 'Dancer2::Logger::Capture' ); ::can_ok( $logger, 'format_message' ); my $trap = $logger->trapper; ::isa_ok( $trap, 'Dancer2::Logger::Capture::Trap' ); my $msg = $trap->read; ::is_deeply( $msg, [ { level => 'core', message => 'looking for get /', formatted => "- 1\n", }, { level => 'core', message => 'Entering hook core.app.before_request', formatted => "- 1\n", }, ], 'Messages logged successfully', ); ::can_ok( $logger, 'format_message' ); my $fmt_str = $logger->format_message( $msg->[0]{'debug'}, $msg->[0]{'message'} ); ::is( $fmt_str, "- 1\n", 'Correct formatted message created' ); return; }; } my $test = Plack::Test->create( App->to_app ); subtest 'Logger can access request' => sub { my $res = $test->request( GET '/' ); ok( $res->is_success, 'Successful request' ); }; libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-650/0000775000175000017500000000000012650351107020552 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-650/views/0000775000175000017500000000000012650351107021707 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-650/views/environment_setting.tt0000644000175000017500000000003312650351107026353 0ustar gregoagregoa[% settings.environment %] libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-650/gh-650.t0000644000175000017500000000142512650351107021645 0ustar gregoagregoa#!/usr/bin/env perl use strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; { package MyApp; use Dancer2; set template => 'template_toolkit'; get '/foo' => sub { template 'environment_setting' }; get '/bar' => sub { set environment => 'development'; template 'environment_setting' }; } my $app = Dancer2->psgi_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $res; $res = $cb->(GET '/foo'); is $res->code, 200, 'Successful request'; like $res->content, qr/development/, 'Correct content'; $res = $cb->(GET '/bar'); is $res->code, 200, 'Successful request'; like $res->content, qr/development/, 'Correct content'; }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-730.t0000644000175000017500000000255312650351107020741 0ustar gregoagregoause strict; use warnings; use Test::More tests => 3; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; get '/' => sub { request->is_behind_proxy }; } my $app = App->to_app; isa_ok( $app, 'CODE' ); my $test = Plack::Test->create($app); subtest 'Runner config' => sub { plan tests => 5; is( Dancer2->runner->config->{'behind_proxy'}, 0, 'No default behind_proxy', ); is( scalar @{ Dancer2->runner->apps }, 1, 'Single app registered', ); isa_ok( Dancer2->runner->apps->[0], 'Dancer2::Core::App', 'Correct app registered', ); is( Dancer2->runner->apps->[0]->setting('behind_proxy'), 0, 'behind_proxy not defined by default in an app', ); Dancer2->runner->apps->[0]->config->{'behind_proxy'} = 1; is( Dancer2->runner->apps->[0]->setting('behind_proxy'), 1, 'Set behind_proxy locally in the app to one', ); }; subtest 'Using App-level settings' => sub { plan tests => 3; is( Dancer2->runner->config->{'behind_proxy'}, 0, 'Runner\'s behind_proxy is still the default', ); my $res = $test->request( GET '/' ); is( $res->code, 200, '[GET /] Correct code' ); is( $res->content, '1', '[GET /] Local value achieved' ); }; libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-931.t0000644000175000017500000000307612650351107020745 0ustar gregoagregoa# this test checks the order of parameters precedence # we run a few request to a route # first we check that the route parameters have precedence # then we check that the body parameters have the next # and finally, when others aren't available, query parameters use strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; { package App; ## no critic use Dancer2; sub query_ok { ::is( params('query')->{'var'}, 'QueryVar', 'Query variable exists', ); } sub body_ok { ::is( params('body')->{'var'}, 'BodyVar', 'Body variable exists', ); } sub route_ok { ::is( params('route')->{'var'}, 'RouteVar', 'Route variable exists', ); } post '/:var' => sub { query_ok(); body_ok(); route_ok(); ::is( params->{'var'}, 'RouteVar', 'Route variable wins', ); }; post '/' => sub { query_ok(); body_ok(); ::is( params->{'var'}, 'BodyVar', 'Body variable wins', ); }; } my $test = Plack::Test->create( App->to_app ); subtest 'Route takes precedence over all other parameters' => sub { $test->request( POST '/RouteVar?var=QueryVar', [ var => 'BodyVar' ] ); }; subtest 'When route parameters not available, POST takes precedence' => sub { $test->request( POST '/?var=QueryVar', [ var => 'BodyVar' ] ); }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-811.t0000644000175000017500000000245112650351107020736 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Cookies; use HTTP::Request::Common; eval { require Dancer2::Session::Cookie; 1 } or plan skip_all => 'Dancer2::Session::Cookie probably missing.'; { package App; use Dancer2; set engines => { session => { Cookie => { secret_key => 'you cannot buy happiness' } } }; set session => 'Cookie'; get '/set' => sub { session foo => 'bar'; redirect '/get'; }; get '/get' => sub { my $data = session->data; return to_json $data; }; } my $test = Plack::Test->create( App->to_app ); my $jar = HTTP::Cookies->new; my $url = 'http://localhost'; my $redir; subtest 'Creating a session' => sub { my $res = $test->request( GET "$url/set" ); ok( $res->is_redirect, 'Request causes redirect' ); ($redir) = $res->header('Location'); is( $redir, "$url/get", 'Redirects to correct url' ); $jar->extract_cookies($res); ok( $jar->as_string, 'Received a session cookie' ); }; subtest 'Retrieving a session' => sub { my $req = GET $redir; $jar->add_cookie_header($req); my $res = $test->request($req); ok( $res->is_success, 'Successful request' ); is( $res->content, '{"foo":"bar"}', 'Correct response' ); }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/issues/config.yml0000644000175000017500000000001712650351107021630 0ustar gregoagregoalogger: "Note" libdancer2-perl-0.166001+dfsg.orig/t/issues/memleak/0000775000175000017500000000000012650351107021257 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/memleak/die_in_hooks.t0000644000175000017500000000300012650351107024065 0ustar gregoagregoa# reported memory leak without GH issue or RT ticket use strict; use warnings; use Test::More tests => 6; use Plack::Test; use Capture::Tiny 'capture_stderr'; use HTTP::Request::Common; my $called; { package Foo::Destroy; sub DESTROY { $called++ } } ## no critic { package App; ## no critic use Dancer2; my $env_key = 'psgix.ignoreme.refleak'; hook before => sub { request->env->{$env_key} = bless {}, 'Foo::Destroy'; }; hook before => sub { ::ok( request->env->{$env_key}, 'Object exists' ); ::isa_ok( request->env->{$env_key}, 'Foo::Destroy', 'It is an object' ); die "whoops"; }; get '/' => sub {'OK'}; } my $test = Plack::Test->create( App->to_app ); my $res; my $stderr = capture_stderr { $res = $test->request( GET '/' ) }; ok( ! $res->is_success, 'Request failed' ); is( $res->code, 500, 'Failure status' ); is( $called, 1, 'Memory cleaned' ); # double check stderr # '[App:21992] error @2015-03-03 16:39:07> Exception caught in 'core.app.before_request' filter: Hook error: whoops at t/issues/memleak/die_in_hooks.t line 25. # at lib/Dancer2/Core/App.pm line 848. in (eval 117) l. 1 # at ... # ' like( $stderr, qr{ ^ \[App:\d+\] \s error \s [\@\-\d\s:]+> \s \QException caught in 'core.app.before_request' filter:\E \s \QHook error: whoops\E \s [^\n]+ \n \s* # everything until newline + newline at [^\n]+ \n # another such line (there could be more) }x, 'Correct error', ); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-596.t0000644000175000017500000000066112650351107020751 0ustar gregoagregoause strict; use warnings; use Test::More tests => 2; use Plack::Test; use HTTP::Request::Common; BEGIN { $ENV{'DANCER_NO_SERVER_TOKENS'} = 'foo' } { package App; use Dancer2; get '/' => sub { config->{'no_server_tokens'} }; } my $test = Plack::Test->create( App->to_app ); my $res = $test->request( GET '/' ); ok( $res->is_success, 'Successful' ); is( $res->content, 'foo', 'Correct server tokens configuration' ); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-1013/0000775000175000017500000000000012650351107020624 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-1013/views/0000775000175000017500000000000012650351107021761 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-1013/views/t.tt0000644000175000017500000000001112650351107022563 0ustar gregoagregoa<% hi %> libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-1013/gh-1013.t0000644000175000017500000000120512650351107021765 0ustar gregoagregoause strict; use warnings; use Test::More; use Test::Fatal; use Plack::Test; use HTTP::Request::Common; { ## no critic package TestApp; use Dancer2; my $app = app; hook before_template => sub { 1; }; set template => 'simple'; get '/' => sub { template t => { hi => 'hello' }, }; }; my $test = Plack::Test->create( TestApp->to_app ); my $res; is( exception { $res = $test->request( GET '/' ); }, undef, 'Request does not crash', ); ok( $res->is_success, 'Request successful' ); chomp( my $content = $res->content ); is( $content, 'hello', 'Correct content' ); done_testing; libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-794.t0000644000175000017500000000076312650351107020754 0ustar gregoagregoause strict; use warnings; use Test::More tests => 2; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; set serializer => 'JSON'; post '/' => sub { request->data }; } my $test = Plack::Test->create( App->to_app ); is( $test->request( POST '/', Content => '{"foo":42}' )->content, '{"foo":42}', 'Correct JSON content in POST', ); is( $test->request( POST '/', Content => 'invalid' )->code, 500, 'Failed to decode invalid content', ); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-723.t0000644000175000017500000000225512650351107020742 0ustar gregoagregoause strict; use warnings; use Test::More tests => 4; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; get '/' => sub {'OK'}; } { package App::Extended; use Dancer2; prefix '/test'; get '/' => sub {'Also OK'}; post '/' => sub { my $params = params; ::isa_ok( $params, 'HASH' ); ::is( $params->{'foo'}, 'bar', 'Got params' ); return $params->{'foo'}; }; } my $app = Dancer2->psgi_app; isa_ok( $app, 'CODE' ); my $test = Plack::Test->create($app); subtest 'GET /' => sub { plan tests => 2; my $res = $test->request( GET '/' ); is( $res->code, 200, 'Correct code' ); is( $res->content, 'OK', 'Correct content' ); }; subtest 'GET /test/' => sub { plan tests => 2; my $res = $test->request( GET '/test/' ); is( $res->code, 200, 'Correct code' ); is( $res->content, 'Also OK', 'Correct content' ); }; subtest 'Missing POST params' => sub { plan tests => 4; my $res = $test->request( POST '/test/', { foo => 'bar' }, ); is( $res->code, 200, 'Correct code' ); is( $res->content, 'bar', 'Correct content' ); }; libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-634.t0000644000175000017500000000446612650351107020751 0ustar gregoagregoause strict; use warnings; use Test::More tests=> 3; use File::Temp qw/tempdir/; use File::Spec; my $log_dir = tempdir( CLEANUP => 1 ); { package LogDirSpecified; use Dancer2; set engines => { logger => { File => { log_dir => $log_dir, file_name => 'test_log.log', } } }; set logger => 'file'; } { package NonExistLogDirSpecified; use Dancer2; set engines => { logger => { File => { log_dir => "$log_dir/notexist", file_name => 'test_log.log', } } }; set logger => 'file'; } { package LogDirNotSpecified; use Dancer2; set logger => 'file'; } my $check_cb = sub { my ( $app, $dir, $file ) = @_; my $logger = $app->logger_engine; isa_ok( $logger, 'Dancer2::Logger::File' ); is( $logger->environment, $app->environment, 'Logger got correct environment', ); is( $logger->location, $app->config_location, 'Logger got correct location', ); is( $logger->log_dir, $dir, 'Logger got correct log directory', ); is( $logger->file_name, $file, 'Logger got correct filename', ); is( $logger->log_file, File::Spec->catfile( $dir, $file ), 'Logger got correct log file', ); }; subtest 'test Logger::File with log_dir specified' => sub { plan tests => 6; my $app = [ grep { $_->name eq 'LogDirSpecified' } @{ Dancer2->runner->apps } ]->[0]; $check_cb->( $app, $log_dir, 'test_log.log' ); }; subtest 'test Logger::File with log_dir NOT specified' => sub { plan tests => 6; my $app = [ grep { $_->name eq 'LogDirNotSpecified' } @{ Dancer2->runner->apps } ]->[0]; $check_cb->( $app, File::Spec->catdir( $app->config_location, 'logs' ), $app->environment . '.log', ); }; subtest 'test Logger::File with non-existent log_dir specified' => sub { plan tests => 6; my $app = [ grep { $_->name eq 'NonExistLogDirSpecified'} @{ Dancer2->runner->apps } ]->[0]; my $logger = $app->logger_engine; $check_cb->( $app, "$log_dir/notexist", 'test_log.log', ); }; libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-944.t0000644000175000017500000000203212650351107020740 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; { package RouteContentTest; ## no critic use Dancer2; set serializer => 'JSON'; hook before => sub { return if request->dispatch_path eq '/content'; response->content({ foo => 'bar' }); response->halt; }; get '/' => sub {1}; get '/content' => sub { response->content({ foo => 'bar' }); return 'this is ignored'; }; } my $test = Plack::Test->create( RouteContentTest->to_app ); subtest "response set in before hook" => sub { my $res = $test->request( GET '/' ); ok( $res->is_success, 'Successful request' ); is( $res->content, '{"foo":"bar"}', 'Correct content' ); }; subtest "response content set in route" => sub { my $res = $test->request( GET '/content' ); ok( $res->is_success, 'Successful request' ); isnt( $res->content, 'this is ignored', 'route return value ignored' ); is( $res->content, '{"foo":"bar"}', 'Correct content' ); }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-1098.t0000644000175000017500000000462012650351107021026 0ustar gregoagregoause Test::More tests => 3; use Test::Fatal; use Dancer2::Core::Error; use Dancer2::Core::Response; use Dancer2::Serializer::JSON; use HTTP::Headers::Fast; use JSON; subtest 'Core::Error serializer isa tests' => sub { plan tests => 5; is exception { Dancer2::Core::Error->new }, undef, "Error->new lived"; like exception { Dancer2::Core::Error->new(show_errors => []) }, qr/not.+boolean/i, "Error->new(show_errors => []) died"; is exception { Dancer2::Core::Error->new(serializer => undef) }, undef, "Error->new(serializer => undef) lived"; is exception { Dancer2::Core::Error->new(serializer => Dancer2::Serializer::JSON->new) }, undef, "Error->new(serializer => Dancer2::Serializer::JSON->new) lived"; like exception { Dancer2::Core::Error->new(serializer => JSON->new) }, qr/does not have role/, "Error->new(serializer => JSON->new) died"; }; subtest 'Core::Response headers isa tests' => sub { plan tests => 5; is exception { Dancer2::Core::Response->new }, undef, "Response->new lived"; is exception { Dancer2::Core::Response->new(headers => [Header => 'Content']) }, undef, "Response->new( headers => [ Header => 'Content' ] ) lived"; is exception { Dancer2::Core::Response->new(headers => HTTP::Headers->new) }, undef, "Response->new( headers => HTTP::Headers->new ) lived"; is exception { Dancer2::Core::Response->new(headers => HTTP::Headers::Fast->new) }, undef, "Response->new( headers => HTTP::Headers::Fast->new ) lived"; like exception { Dancer2::Core::Response->new(headers => JSON->new) }, qr/coercion.+failed.+not.+array/i, "Response->new( headers => JSON->new ) died"; }; subtest 'Core::Role::Logger log_level isa tests' => sub { plan tests => 1 + 6 + 1; { package TestLogger; use Moo; with 'Dancer2::Core::Role::Logger'; sub log { } } is exception { TestLogger->new }, undef, "Logger->new lived"; my @levels = qw/core debug info warn warning error/; foreach my $level (@levels) { is exception { TestLogger->new(log_level => $level) }, undef, "Logger->new(log_level => $level) lives"; } like exception { TestLogger->new(log_level => 'BadLevel') }, qr/isa.+failed.+must be one of: core/, "Logger->new(log_level => 'BadLevel') died"; }; libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-639/0000775000175000017500000000000012650351107020561 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-639/succeeds/0000775000175000017500000000000012650351107022357 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-639/succeeds/.dancer0000644000175000017500000000000012650351107023600 0ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-639/succeeds/issue.t0000644000175000017500000000025512650351107023674 0ustar gregoagregoause strict; use warnings; use Test::More tests => 1; use Test::Fatal; require Dancer2; is( exception { Dancer2->import() }, undef, 'No compilation issue', ); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-639/succeeds/config.yml0000644000175000017500000000007112650351107024343 0ustar gregoagregoaengines: template: foo: bar: baz libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-639/fails/0000775000175000017500000000000012650351107021657 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-639/fails/.dancer0000644000175000017500000000000012650351107023100 0ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/issues/gh-639/fails/issue.t0000644000175000017500000000032012650351107023165 0ustar gregoagregoause strict; use warnings; use Test::More tests => 1; use Test::Fatal; require Dancer2; like( exception { Dancer2->import() }, qr{Engine 'foo' is not supported}, 'Correct compilation issue', ); libdancer2-perl-0.166001+dfsg.orig/t/issues/gh-639/fails/config.yml0000644000175000017500000000004312650351107023642 0ustar gregoagregoaengines: foo: bar: baz libdancer2-perl-0.166001+dfsg.orig/t/dsl/0000775000175000017500000000000012650351107017113 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/dsl/send_file.t0000644000175000017500000000703712650351107021235 0ustar gregoagregoause strict; use warnings; use utf8; use Encode 'encode_utf8'; use Test::More; use Plack::Test; use HTTP::Request::Common; use File::Temp; use File::Spec; { package StaticContent; use Dancer2; use Encode 'encode_utf8'; set views => 't/corpus/static'; set public_dir => 't/corpus/static'; get '/' => sub { send_file 'index.html'; }; prefix '/some' => sub { get '/image' => sub { send_file '1x1.png'; return "send_file returns; this content is ignored"; }; }; get '/stringref' => sub { my $string = encode_utf8("This is əɯosəʍɐ an test string"); send_file( \$string ); }; get '/filehandle' => sub { open my $fh, "<:raw", __FILE__; send_file( $fh, content_type => 'text/plain' ); }; get '/check_content_type' => sub { my $temp = File::Temp->new(); print $temp "hello"; close $temp; send_file($temp->filename, content_type => 'image/png', system_path => 1); }; get '/no_streaming' => sub { my $file = File::Spec->rel2abs(__FILE__); send_file( $file, system_path => 1, streaming => 0 ); }; get '/options_streaming' => sub { my $file = File::Spec->rel2abs(__FILE__); send_file( $file, system_path => 1, streaming => 1 ); }; } my $app = StaticContent->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; subtest "Text content" => sub { my $r = $cb->( GET '/' ); is( $r->code, 200, 'send_file sets the status to 200' ); my $charset = $r->headers->content_type_charset; is( $charset, 'UTF-8', 'Text content type has UTF-8 charset' ); my $test_string = encode_utf8('áéíóú'); like( $r->content, qr{$test_string}, 'Text content contains UTF-8 characters', ); }; subtest "Binary content" => sub { my $r = $cb->( GET '/some/image' ); is( $r->code, 200, 'send_file sets the status to 200 (binary content)' ); unlike( $r->content, qr/send_file returns/, "send_file returns immediately with content"); is( $r->header( 'Content-Type' ), 'image/png', 'correct content_type in response' ); }; subtest "string refs" => sub { my $r = $cb->( GET '/stringref' ); is( $r->code, 200, 'send_file set status to 200 (string ref)'); like( $r->content, qr{test string}, 'stringref content' ); }; subtest "filehandles" => sub { my $r = $cb->( GET '/filehandle' ); is( $r->code, 200, 'send_file set status to 200 (filehandle)'); like( $r->content, qr{package StaticContent}, 'filehandle content' ); }; subtest "no streaming" => sub { my $r = $cb->( GET '/no_streaming' ); is( $r->code, 200, 'send_file set status to 200 (no streaming)'); like( $r->content, qr{package StaticContent}, 'no streaming - content' ); }; subtest "options streaming" => sub { my $r = $cb->( GET '/options_streaming' ); is( $r->code, 200, 'send_file set status to 200 (options streaming)'); like( $r->content, qr{package StaticContent}, 'options streaming - content' ); }; subtest 'send_file returns correct content type' => sub { my $r = $cb->( GET '/check_content_type' ); ok($r->is_success, 'send_file returns success'); is($r->content_type, 'image/png', 'send_file returns correct content_type'); }; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/dsl/app.t0000644000175000017500000000053412650351107020060 0ustar gregoagregoause strict; use warnings; use Test::More tests => 2; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; get '/' => sub { my $app = app; ::isa_ok( $app, 'Dancer2::Core::App' ); ::is( $app->name, 'App', 'Correct app name' ); }; } Plack::Test->create( App->to_app )->request( GET '/' ); libdancer2-perl-0.166001+dfsg.orig/t/dsl/halt_with_param.t0000644000175000017500000000347612650351107022453 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; subtest 'halt with parameter within routes' => sub { { package App; use Dancer2; get '/' => sub { 'hello' }; get '/halt' => sub { header 'X-Foo' => 'foo'; halt; }; get '/shortcircuit' => sub { halt('halted'); redirect '/'; # won't get executed as halt returns immediately. }; } my $app = App->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; { my $res = $cb->( GET '/shortcircuit' ); is( $res->code, 200, '[/shortcircuit] Correct status' ); is( $res->content, 'halted', '[/shortcircuit] Correct content' ); } { my $res = $cb->( GET '/halt' ); is( $res->server, "Perl Dancer2 " . Dancer2->VERSION, '[/halt] Correct Server header', ); is( $res->headers->header('X-Foo'), 'foo', '[/halt] Correct X-Foo header', ); } }; }; subtest 'halt with parameter in before hook' => sub { { package App; use Dancer2; hook before => sub { halt('I was halted') if request->dispatch_path eq '/shortcircuit'; }; } my $app = App->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/shortcircuit' ); is( $res->code, 200, '[/shortcircuit] Correct code with before hook' ); is( $res->content, 'I was halted', '[/shortcircuit] Correct content with before hook', ); }; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/dsl/content.t0000644000175000017500000000253612650351107020756 0ustar gregoagregoause strict; use warnings; use Test::More tests => 1; use Plack::Test; use HTTP::Request::Common; my $logger; { package App::ContentFail; ## no critic use Dancer2; set show_errors => 1; set logger => 'Capture'; $logger = app->engine('logger'); get '/' => sub { content 'Foo' }; } subtest 'content keyword can only be used within delayed response' => sub { my $test = Plack::Test->create( App::ContentFail->to_app ); my $res = $test->request( GET '/' ); ok( ! $res->is_success, 'Request failed' ); is( $res->code, 500, 'Correct response code' ); like( $res->content, qr/Cannot use content keyword outside delayed response/, 'Failed to use content keyword outside delayed response', ); isa_ok( $logger, 'Dancer2::Logger::Capture' ); my $trapper = $logger->trapper; isa_ok( $trapper, 'Dancer2::Logger::Capture::Trap' ); my $error = $trapper->read; isa_ok( $error, 'ARRAY' ); is( scalar @{$error}, 1, 'Only one error' ); ok( delete $error->[0]{'formatted'}, 'Got formatted message' ); like( delete $error->[0]{'message'}, qr{^\QRoute exception: Cannot use content keyword outside delayed response\E}, 'Correct error message', ); is_deeply( $error, [ { level => 'error' } ], 'Rest of error okay', ); }; libdancer2-perl-0.166001+dfsg.orig/t/dsl/path.t0000644000175000017500000000541012650351107020232 0ustar gregoagregoause strict; use warnings; use Test::More tests => 4; use Plack::Test; use Plack::Request; use Plack::Builder; use HTTP::Request::Common; { package App; use Dancer2; get '/' => sub { my $dancer_req = request; my $env = $dancer_req->env; my $plack_req = Plack::Request->new($env); ::like( $env->{'PATH_INFO'}, qr{^/?$}, 'PATH_INFO empty or /', ); ::is( $dancer_req->path_info, $env->{'PATH_INFO'}, 'D2 path_info matches $env', ); ::is( $dancer_req->path_info, $plack_req->path_info, 'D2 path_info matches Plack path_info', ); ::is( $dancer_req->path, '/', 'D2 path is /' ); ::is( $plack_req->path, '/', 'Plack path is /' ); return $dancer_req->script_name; }; get '/endpoint' => sub { my $dancer_req = request; my $env = $dancer_req->env; my $plack_req = Plack::Request->new($env); ::is( $env->{'PATH_INFO'}, '/endpoint', 'PATH_INFO /endpoint', ); ::is( $dancer_req->path_info, $env->{'PATH_INFO'}, 'D2 path_info matches $env', ); ::is( $dancer_req->path_info, $plack_req->path_info, 'D2 path_info matches Plack path_info', ); ::is( $dancer_req->path, '/endpoint', 'D2 path is /' ); ::is( $plack_req->path, '/endpoint', 'Plack path is /' ); return $dancer_req->script_name; }; } subtest '/' => sub { my $test = Plack::Test->create( App->to_app ); my $res = $test->request( GET '/' ); ok( $res->is_success, 'Result successful' ); is( $res->content, '', 'script_name is empty' ); }; subtest '/endpoint' => sub { my $test = Plack::Test->create( App->to_app ); my $res = $test->request( GET '/endpoint' ); ok( $res->is_success, 'Result successful' ); is( $res->content, '', 'script_name is empty' ); }; subtest '/mounted/' => sub { my $app = builder { mount '/' => sub { [200,[],['OK']] }; mount '/mounted' => App->to_app; }; my $test = Plack::Test->create($app); my $res = $test->request( GET '/mounted/' ); ok( $res->is_success, 'Result successful' ); is( $res->content, '/mounted', 'script_name is /mounted' ); }; subtest '/mounted/endpoint' => sub { my $app = builder { mount '/' => sub { [200,[],['OK']] }; mount '/mounted' => App->to_app; }; my $test = Plack::Test->create($app); my $res = $test->request( GET '/mounted/endpoint' ); ok( $res->is_success, 'Result successful' ); is( $res->content, '/mounted', 'script_name is /mounted' ); }; libdancer2-perl-0.166001+dfsg.orig/t/dsl/any.t0000644000175000017500000000221012650351107020060 0ustar gregoagregoause strict; use warnings; use Test::More tests => 2; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; any [ 'get', 'post' ] => '/test' => sub { request->method }; any '/all' => sub { request->method }; } my $test = Plack::Test->create( App->to_app ); subtest 'any with params' => sub { my @success = qw; my @fails = qw; foreach my $method (@success) { my $req = HTTP::Request->new( $method => '/test' ); is( $test->request($req)->content, $method, "Method $method works", ); } foreach my $method (@fails) { my $req = HTTP::Request->new( $method => '/test' ); ok( ! $test->request($req)->is_success, "Method $method doesn't exist", ); } }; subtest 'any without params' => sub { foreach my $method ( qw ) { my $req = HTTP::Request->new( $method => '/all' ); is( $test->request($req)->content, $method, "Method $method works", ); } }; libdancer2-perl-0.166001+dfsg.orig/t/dsl/extend.t0000644000175000017500000000202312650351107020562 0ustar gregoagregoa# define a sample DSL extension that will be used in the rest of these test # This extends Dancer2::Core::DSL but provides an extra keyword # # Each test below creates a new package so it can load Dancer2 BEGIN { package Dancer2::Test::ExtendedDSL; use Moo; extends 'Dancer2::Core::DSL'; sub BUILD { my ( $self ) = @_; $self->register(foo => 1); } sub foo { return $_[1]; } } package main; use Test::More tests => 5; package test1; use Test::More; use Dancer2 dsl => 'Dancer2::Test::ExtendedDSL'; ok(defined &foo, 'use line dsl can foo'); is(foo('bar'), 'bar', 'use line Foo returns bar'); package test2; use Test::More; ok(!defined &foo, 'intermediate package has no polluted namespace'); package test3; use Test::More; use FindBin; use File::Spec; BEGIN { $ENV{DANCER_CONFDIR} = File::Spec->catdir($FindBin::Bin, 'extend_config'); } use Dancer2; ok(defined &foo, 'config specified DSL can foo'); is(foo('baz'), 'baz', 'config specified Foo returns baz'); done_testing; libdancer2-perl-0.166001+dfsg.orig/t/dsl/route_retvals.t0000644000175000017500000000063112650351107022174 0ustar gregoagregoause strict; use warnings; use Dancer2; use Test::More (); my @routes = get '/' => sub {1}; Test::More::is( scalar @routes, 2, 'Two routes available' ); foreach my $route (@routes) { Test::More::isa_ok( $route, 'Dancer2::Core::Route' ); } Test::More::is( $routes[0]->method, 'get', 'Created GET route' ); Test::More::is( $routes[1]->method, 'head', 'Created HEAD route too' ); Test::More::done_testing; libdancer2-perl-0.166001+dfsg.orig/t/dsl/pass.t0000644000175000017500000000167412650351107020254 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; subtest 'pass within routes' => sub { { package App; use Dancer2; get '/' => sub { 'hello' }; get '/**' => sub { header 'X-Pass' => 'pass'; pass; redirect '/'; # won't get executed as pass returns immediately. }; get '/pass' => sub { return "the baton"; }; } my $app = App->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; { my $res = $cb->( GET '/pass' ); is( $res->code, 200, '[/pass] Correct status' ); is( $res->content, 'the baton', '[/pass] Correct content' ); is( $res->headers->header('X-Pass'), 'pass', '[/pass] Correct X-Pass header', ); } }; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/dsl/error_template.t0000644000175000017500000000364512650351107022332 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; { package CustomError; use Dancer2; set views => 't/corpus/pretty'; set public_dir => 't/corpus/pretty_public'; get '/error' => sub { send_error "oh my", 505; }; get '/public' => sub { send_error "static", 510; }; } { package StandardError; use Dancer2; set show_errors => 1; get '/no_template' => sub { send_error "oopsie", 404; }; } my $custom_error_app = CustomError->to_app; my $standard_error_app = StandardError->to_app; is( ref $custom_error_app, 'CODE', 'Got app' ); is( ref $standard_error_app, 'CODE', 'Got app' ); my $custom_error_test = Plack::Test->create($custom_error_app); my $standard_error_test = Plack::Test->create($standard_error_app); subtest "/error" => sub { my $res = $custom_error_test->request( GET '/error' ); is $res->code, 505, 'send_error sets the status to 505'; like $res->content, qr{Template selected}, 'Error message looks good'; like $res->content, qr{message: oh my}; like $res->content, qr{status: 505}; }; subtest "/public" => sub { my $res = $custom_error_test->request( GET '/public' ); is $res->code, 510, 'send_error sets the status to 510'; like $res->content, qr{Static page}, 'Error message looks good'; }; subtest '404 with static template' => sub { my $res = $custom_error_test->request( GET '/middle/of/nowhere' ); is $res->code, 404, 'unknown route => 404'; like $res->content, qr{you're lost}i, 'Error message looks good'; }; subtest "/no_template" => sub { my $res = $standard_error_test->request( GET '/no_template' ); is $res->code, 404, 'send_error sets the status to 404'; like $res->content, qr{

Error 404 - Not Found

}, 'Error message looks good'; unlike $res->content, qr{Stack}, 'Error contains no stack trace'; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/dsl/parameters.t0000644000175000017500000002246412650351107021451 0ustar gregoagregoause strict; use warnings; use utf8; use Test::More; use Plack::Test; use HTTP::Request::Common; subtest 'Query parameters' => sub { { package App::Basic; ## no critic use Dancer2; use Encode 'encode_utf8'; get '/' => sub { my $params = query_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword', ); ::is( $params->get('foo'), 'bar', 'Got single value' ); ::is( $params->get('bar'), 'quux', 'Got single value from multi key', ); ::is_deeply( [ $params->get_all('bar') ], ['baz', 'quux'], 'Got multi value from multi key', ); ::is( $params->get('baz'), encode_utf8('הלו'), 'HMV interface returns decoded values', ); ::is( params->{'baz'}, 'הלו', 'Regular interface returns encoded values' ); }; } my $app = Plack::Test->create( App::Basic->to_app ); my $res = $app->request( GET '/?foo=bar&bar=baz&bar=quux&baz=הלו' ); ok( $res->is_success, 'Successful request' ); }; subtest 'Body parameters' => sub { { package App::Body; ## no critic use Dancer2; post '/' => sub { my $params = body_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword', ); ::is( $params->get('foo'), 'bar', 'Got single value' ); ::is( $params->get('bar'), 'quux', 'Got single value from multi key', ); my $z = [ $params->get_all('bar') ]; ::is_deeply( [ $params->get_all('bar') ], ['baz', 'quux'], 'Got multi value from multi key', ); }; } my $app = Plack::Test->create( App::Body->to_app ); my $res = $app->request( POST '/', Content => [ foo => 'bar', bar => 'baz', bar => 'quux' ] ); ok( $res->is_success, 'Successful request' ); }; subtest 'Body parameters with serialized data' => sub { { package App::Body::JSON; ## no critic use Dancer2; set serializer => 'JSON'; post '/' => sub { my $params = body_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword', ); ::is( $params->get('foo'), 'bar', 'Got single value' ); ::is( $params->get('bar'), 'quux', 'Got single value from multi key', ); my $z = [ $params->get_all('bar') ]; ::is_deeply( [ $params->get_all('bar') ], ['baz', 'quux'], 'Got multi value from multi key', ); return { ok => 1 }; }; } my $app = Plack::Test->create( App::Body::JSON->to_app ); my $res = $app->request( POST '/', Content => '{"foo":"bar","bar":["baz","quux"]}' ); ok( $res->is_success, 'Successful request' ); }; subtest 'Route parameters' => sub { { package App::Route; ## no critic use Dancer2; get '/:foo' => sub { my $params = route_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword', ); ::is( $params->get('foo'), 'bar', 'Got keyed value' ); }; get '/:name/:value' => sub { my $params = route_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword returns Hash::MultiValue object', ); ::is( $params->get('name'), 'foo', 'Got first value' ); ::is( $params->get('value'), 'bar', 'Got second value' ); }; } my $app = Plack::Test->create( App::Route->to_app ); { my $res = $app->request( GET '/bar' ); ok( $res->is_success, 'Successful request' ); } { my $res = $app->request( GET '/foo/bar' ); ok( $res->is_success, 'Successful request' ); } }; subtest 'Splat and megasplat route parameters' => sub { { package App::Route::Splat; ## no critic use Dancer2; get '/*' => sub { my $params = route_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword', ); ::is_deeply( { %{$params} }, {}, 'All route parameters are empty', ); ::is_deeply( [ splat ], [ 'foo' ], 'Got splat values', ); }; get '/*/*' => sub { my $params = route_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword returns Hash::MultiValue object', ); ::is_deeply( { %{$params} }, {}, 'All route parameters are empty', ); ::is_deeply( [ splat ], [ qw ], 'Got splat values', ); }; # /foo/bar/baz/quux/quuks get '/*/*/*/**' => sub { my $params = route_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword returns Hash::MultiValue object', ); ::is_deeply( { %{$params} }, {}, 'All route parameters are empty', ); ::is_deeply( [ splat ], [ qw, [ qw ] ], 'Got splat values', ); }; # /foo/bar/baz get '/*/:foo/**' => sub { my $params = route_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword returns Hash::MultiValue object', ); ::is( $params->get('foo'), 'bar', 'Correct route parameter' ); ::is_deeply( [ splat ], [ 'foo', ['baz'] ], 'Got splat values', ); }; } my $app = Plack::Test->create( App::Route::Splat->to_app ); { my $res = $app->request( GET '/foo' ); ok( $res->is_success, 'Successful request' ); } { my $res = $app->request( GET '/foo/bar' ); ok( $res->is_success, 'Successful request' ); } { my $res = $app->request( GET '/foo/bar/baz/quux/quuks' ); ok( $res->is_success, 'Successful request' ); } { my $res = $app->request( GET '/foo/bar/baz/' ); ok( $res->is_success, 'Successful request' ); } }; subtest 'Captured route parameters' => sub { { package App::Route::Capture; ## no critic use Dancer2; get qr{^/foo/([^/]+)$} => sub { my $params = route_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword', ); ::is_deeply( { %{$params} }, {}, 'All route parameters are empty', ); ::is_deeply( [ splat ], ['bar'], 'Correct splat values', ); ::is_deeply( captures(), +{}, 'capture values are empty', ); }; } my $app = Plack::Test->create( App::Route::Capture->to_app ); { my $res = $app->request( GET '/foo/bar' ); ok( $res->is_success, 'Successful request' ); } }; SKIP: { Test::More::skip "named captures not available until 5.10", 1 if !$^V or $^V lt v5.10; subtest 'Named captured route parameters' => sub { { package App::Route::NamedCapture; ## no critic use Dancer2; my $re = '^/bar/(?[^/]+)$'; get qr{$re} => sub { my $params = route_parameters; ::isa_ok( $params, 'Hash::MultiValue', 'parameters keyword', ); ::is_deeply( { %{$params} }, {}, 'All route parameters are empty', ); ::is_deeply( [ splat ], [], 'splat values are empty', ); ::is_deeply( captures(), { baz => 'quux' }, 'Correct capture values', ); }; } my $app = Plack::Test->create( App::Route::NamedCapture->to_app ); { my $res = $app->request( GET '/bar/quux' ); ok( $res->is_success, 'Successful request' ); }; }; }; done_testing(); libdancer2-perl-0.166001+dfsg.orig/t/dsl/to_app.t0000644000175000017500000000103612650351107020560 0ustar gregoagregoause strict; use warnings; use Plack::Test; use HTTP::Request::Common; use Test::More tests => 2; { package App1; use Dancer2; get '/' => sub {'App1'}; my $app = to_app; ::test_psgi $app, sub { my $cb = shift; ::is( $cb->( ::GET '/' )->content, 'App1', 'Got first App' ); }; } { package App2; use Dancer2; get '/' => sub {'App2'}; my $app = to_app; ::test_psgi $app, sub { my $cb = shift; ::is( $cb->( ::GET '/' )->content, 'App2', 'Got second App' ); }; } libdancer2-perl-0.166001+dfsg.orig/t/dsl/delayed.t0000644000175000017500000001006612650351107020710 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; eval { require AnyEvent; 1; } or plan skip_all => 'AnyEvent required for this test'; plan tests => 5; { package App::Content; ## no critic use Dancer2; get '/' => sub { ::is( $Dancer2::Core::Route::RESPONDER, undef, 'No responder yet' ); delayed { ::isa_ok( $Dancer2::Core::Route::RESPONDER, 'CODE', 'Got a responder in the delayed callback', ); ::is( $Dancer2::Core::Route::WRITER, undef, 'No writer yet' ); content 'OK'; ::ok( $Dancer2::Core::Route::WRITER, 'Got a writer' ); done; }; }; } { package App::Content::MultiWrite; ## no critic use Dancer2; get '/' => sub { delayed { flush; content 'Foo'; content 'Bar'; done; }; }; } { package App::NoContent; ## no critic use Dancer2; get '/' => sub { delayed {content;done;'Not OK'}; }; } { package App::MultipleContent; ## no critic use Dancer2; get '/' => sub { delayed { content 'Bar'; done; }; return 'OK'; }; } my $caught_error; { package App::ErrorHandler; ## no critic use Dancer2; require AnyEvent; set logger => 'Capture'; get '/log' => sub { delayed { flush; content "ping\n"; done; content "failure\n"; }; }; get '/cb' => sub { delayed { flush; content "ping\n"; done; content "failure\n"; } on_error => sub { $caught_error = shift; }; }; } subtest 'Testing an app with content keyword' => sub { my $test = Plack::Test->create( App::Content->to_app ); my $res = $test->request( GET '/' ); ok( $res->is_success, 'Successful request' ); is( $res->content, 'OK', 'Correct content' ); }; subtest 'Testing an app with multiple content keyword calls' => sub { my $test = Plack::Test->create( App::Content::MultiWrite->to_app ); my $res = $test->request( GET '/' ); ok( $res->is_success, 'Successful request' ); is( $res->content, 'FooBar', 'Correct content' ); }; subtest 'Testing an app without content keyword' => sub { my $test = Plack::Test->create( App::NoContent->to_app ); my $res = $test->request( GET '/' ); ok( $res->is_success, 'Successful request' ); is( $res->content, '', 'Correct content' ); }; subtest 'Delayed response ignored for non-delayed content' => sub { my $test = Plack::Test->create( App::MultipleContent->to_app ); my $res = $test->request( GET '/' ); ok( $res->is_success, 'Successful request' ); is( $res->content, 'OK', 'Correct content' ); }; subtest 'Delayed response error handling' => sub { my $test = Plack::Test->create( App::ErrorHandler->to_app ); TODO: { local $TODO = 'Does not work in development server'; my $res = $test->request( GET '/log' ); ok( $res->is_success, 'Successful request' ); is( $res->content, "ping\n", 'Correct content' ); my $logger = App::ErrorHandler::app->logger_engine; my $logs = $logger->trapper->read; isa_ok( $logs, 'ARRAY', 'Got logs' ); is( scalar @{$logs}, 1, 'Got a message' ); my $msg = shift @{$logs}; ok( $msg, 'Got message' ); isa_ok( $msg, 'HASH', 'Got message' ); is( $msg->{'level'}, 'core', 'Correct error message level', ); like( $msg->{'message'}, qr/^Error in delayed response:/, 'Got error', ); } TODO: { local $TODO = 'Does not work in development server'; my $res = $test->request( GET '/cb' ); ok( $res->is_success, 'Successful request' ); is( $res->content, "ping\n", 'Correct content' ); like( $caught_error, qr/^Error in delayed response:/, 'Got error' ); } }; libdancer2-perl-0.166001+dfsg.orig/t/dsl/halt.t0000644000175000017500000000354212650351107020232 0ustar gregoagregoause strict; use warnings; use Test::More; use Plack::Test; use HTTP::Request::Common; subtest 'halt within routes' => sub { { package App; use Dancer2; get '/' => sub { 'hello' }; get '/halt' => sub { header 'X-Foo' => 'foo'; halt; }; get '/shortcircuit' => sub { app->response->content('halted'); halt; redirect '/'; # won't get executed as halt returns immediately. }; } my $app = App->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; { my $res = $cb->( GET '/shortcircuit' ); is( $res->code, 200, '[/shortcircuit] Correct status' ); is( $res->content, 'halted', '[/shortcircuit] Correct content' ); } { my $res = $cb->( GET '/halt' ); is( $res->server, "Perl Dancer2 " . Dancer2->VERSION, '[/halt] Correct Server header', ); is( $res->headers->header('X-Foo'), 'foo', '[/halt] Correct X-Foo header', ); } }; }; subtest 'halt in before hook' => sub { { package App; use Dancer2; hook before => sub { response->content('I was halted'); halt if request->dispatch_path eq '/shortcircuit'; }; } my $app = App->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/shortcircuit' ); is( $res->code, 200, '[/shortcircuit] Correct code with before hook' ); is( $res->content, 'I was halted', '[/shortcircuit] Correct content with before hook', ); }; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/dsl/splat.t0000644000175000017500000000120512650351107020417 0ustar gregoagregoause strict; use warnings; use Test::More tests => 4; use Plack::Test; use HTTP::Request::Common; my @splat; { package App; use Dancer2; get '/*/*/*' => sub { my $params = params(); ::is_deeply( $params, { splat => [ qw ], foo => 42 }, 'Correct params', ); @splat = splat; }; } my $test = Plack::Test->create( App->to_app ); my $res = $test->request( GET '/foo/bar/baz?foo=42' ); is_deeply( [@splat], [qw(foo bar baz)], 'splat behaves as expected' ); is( $res->code, 200, 'got a 200' ); is_deeply( $res->content, 3, 'got expected response' ); libdancer2-perl-0.166001+dfsg.orig/t/dsl/extend_config/0000775000175000017500000000000012650351107021727 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/dsl/extend_config/config.yml0000644000175000017500000000005012650351107023710 0ustar gregoagregoadsl_class: 'Dancer2::Test::ExtendedDSL' libdancer2-perl-0.166001+dfsg.orig/t/dancer-test/0000775000175000017500000000000012650351107020542 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/t/dancer-test/config.yml0000644000175000017500000000002312650351107022523 0ustar gregoagregoaroute_handlers: [] libdancer2-perl-0.166001+dfsg.orig/t/template_default_tokens.t0000644000175000017500000000205612650351107023421 0ustar gregoagregoause strict; use warnings; use File::Spec; use File::Basename 'dirname'; use Test::More; use Plack::Test; use HTTP::Request::Common; eval { require Template; Template->import(); 1 } or plan skip_all => 'Template::Toolkit probably missing.'; my $views = File::Spec->rel2abs( File::Spec->catfile( dirname(__FILE__), 'views' ) ); { package Foo; use Dancer2; set session => 'Simple'; set views => $views; set template => "template_toolkit"; set foo => "in settings"; get '/view/:foo' => sub { var foo => "in var"; session foo => "in session"; template "tokens"; }; } my $version = Dancer2->VERSION; my $expected = "perl_version: $^V dancer_version: ${version} settings.foo: in settings params.foo: 42 session.foo in session vars.foo: in var"; my $app = Foo->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; like( $cb->( GET '/view/42' )->content, qr{$expected}, 'Response contains all expected tokens', ); }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/template_name.t0000644000175000017500000000070312650351107021327 0ustar gregoagregoause strict; use warnings; use File::Spec; use File::Basename 'dirname'; use Test::More; use Plack::Test; use HTTP::Request::Common; { package Foo; use Dancer2; get '/template_name' => sub { return engine('template')->name; }; } my $app = Foo->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/template_name' )->content, 'Tiny', 'template name' ); }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/context-in-before.t0000644000175000017500000000211712650351107022045 0ustar gregoagregoa#!perl use strict; use warnings; use Test::More tests => 10; use Plack::Test; use HTTP::Request::Common; my $before; { package OurApp; use Dancer2 '!pass'; use Test::More; hook before => sub { my $ctx = shift; isa_ok( $ctx, 'Dancer2::Core::App', 'Context is actually an app now', ); is( $ctx->name, 'OurApp', 'It is the correct app' ); can_ok( $ctx, 'app' ); my $app = $ctx->app; isa_ok( $app, 'Dancer2::Core::App', 'When called ->app, we get te app again', ); is( $app->name, 'OurApp', 'It is the correct app' ); is( $ctx, $app, 'Same exact application (by reference)' ); $before++; }; get '/' => sub {'OK'}; } my $app = OurApp->to_app; isa_ok( $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/' ); is( $res->code, 200, '[GET /] status OK' ); is( $res->content, 'OK', '[GET /] content OK' ); ok( $before == 1, 'before hook called' ); }; libdancer2-perl-0.166001+dfsg.orig/t/log_die_before_hook.t0000644000175000017500000000135212650351107022461 0ustar gregoagregoause Test::More; use strict; use warnings; use Plack::Test; use HTTP::Request::Common; use Capture::Tiny 'capture_stderr'; { package App; use Dancer2; set logger => 'console'; hook 'before' => sub { die 'test die inside a before hook'; print STDERR "error message not caught in the before hook\n"; }; get '/' => sub { print STDERR "error message not caught in the route handler\n"; }; } my $app = App->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $message = capture_stderr { $cb->( GET '/' ) }; like $message, qr/test die inside a before hook/, 'Got error message when a before hook dies'; }; done_testing; libdancer2-perl-0.166001+dfsg.orig/t/config_multiapp.t0000644000175000017500000000111312650351107021670 0ustar gregoagregoause strict; use warnings; use Test::More; use File::Spec; use t::app::t1::lib::App1; use t::app::t1::lib::Sub::App2; use t::app::t2::lib::App3; for my $app ( @{ Dancer2->runner->apps } ) { # Need to determine path to config; use apps' name for now.. my $path = $app->name eq 'App3' ? 't2' : 't1'; is_deeply $app->config_files, [ File::Spec->rel2abs(File::Spec->catfile( 't', 'app', $path, 'config.yml' )) ], $app->name . ": config files found"; is $app->config->{app}->{config}, 'ok', $app->name . ": config loaded properly" } done_testing; libdancer2-perl-0.166001+dfsg.orig/t/vars.t0000644000175000017500000000107012650351107017465 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Plack::Test; use HTTP::Request::Common; plan tests => 3; { use Dancer2; hook before => sub { var( "xpto" => "foo" ); vars->{zbr} = 'ugh'; }; get '/bar' => sub { var("xpto"); }; get '/baz' => sub { vars->{zbr}; }; } my $app = __PACKAGE__->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/bar' )->content, 'foo', 'foo' ); is( $cb->( GET '/baz' )->content, 'ugh', 'ugh' ); }; libdancer2-perl-0.166001+dfsg.orig/t/forward.t0000644000175000017500000000770612650351107020172 0ustar gregoagregoause strict; use warnings; use Test::More import => ['!pass']; use Plack::Test; use HTTP::Request::Common; use Dancer2; get '/' => sub { 'home:' . join( ',', params ); }; get '/bounce/' => sub { return forward '/'; }; get '/bounce/:withparams/' => sub { return forward '/'; }; get '/bounce2/adding_params/' => sub { return forward '/', { withparams => 'foo' }; }; post '/simple_post_route/' => sub { 'post:' . join( ',', params ); }; get '/go_to_post/' => sub { return forward '/simple_post_route/', { foo => 'bar' }, { method => 'post' }; }; # NOT SUPPORTED IN DANCER2 # In dancer2, vars are alive for only one request flow, a forward initiate a # new request flow, then the vars HashRef is destroyed. # # get '/b' => sub { vars->{test} = 1; forward '/a'; }; # get '/a' => sub { return "test is " . var('test'); }; my $app = __PACKAGE__->to_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; is( $cb->( GET '/' )->code, 200, '[GET /] Correct code' ); is( $cb->( GET '/' )->content, 'home:', '[GET /] Correct content' ); is( $cb->( GET '/bounce/' )->code, 200, '[GET /bounce] Correct code' ); is( $cb->( GET '/bounce/' )->content, 'home:', '[GET /bounce] Correct content', ); is( $cb->( GET '/bounce/thesethings/' )->code, 200, '[GET /bounce/thesethings/] Correct code', ); is( $cb->( GET '/bounce/thesethings/' )->content, 'home:withparams,thesethings', '[GET /bounce/thesethings/] Correct content', ); is( $cb->( GET '/bounce2/adding_params/' )->code, 200, '[GET /bounce2/adding_params/] Correct code', ); is( $cb->( GET '/bounce2/adding_params/' )->content, 'home:withparams,foo', '[GET /bounce2/adding_params/] Correct content', ); is( $cb->( GET '/go_to_post/' )->code, 200, '[GET /go_to_post/] Correct code', ); is( $cb->( GET '/go_to_post/' )->content, 'post:foo,bar', '[GET /go_to_post/] Correct content', ); # NOT SUPPORTED # response_status_is [ GET => '/b' ] => 200; # response_content_is [ GET => '/b' ] => 'test is 1'; { my $res = $cb->( GET '/bounce/' ); is( $res->headers->content_length, 5, '[GET /bounce/] Correct content length', ); is( $res->headers->content_type, 'text/html', '[GET /bounce/] Correct content type', ); is( $res->headers->content_type_charset, 'UTF-8', '[GET /bounce/] Correct content type charset', ); is( $res->headers->server, "Perl Dancer2 " . Dancer2->VERSION, '[GET /bounce/] Correct Server', ); } # checking post post '/' => sub {'post-home'}; post '/bounce/' => sub { forward('/') }; is( $cb->( POST '/' )->code, 200, '[POST /] Correct code' ); is( $cb->( POST '/' )->content, 'post-home', '[POST /] Correct content' ); is( $cb->( POST '/bounce/' )->code, 200, '[POST /bounce/] Correct code', ); is( $cb->( POST '/bounce/' )->content, 'post-home', '[POST /bounce/] Correct content', ); { my $res = $cb->( POST '/bounce/' ); is( $res->headers->content_length, 9, '[POST /bounce/] Correct content length', ); is( $res->headers->content_type, 'text/html', '[POST /bounce/] Correct content type', ); is( $res->headers->content_type_charset, 'UTF-8', '[POST /bounce/] Correct content type charset', ); is( $res->headers->server, "Perl Dancer2 " . Dancer2->VERSION, '[POST /bounce/] Correct Server', ); } }; done_testing; libdancer2-perl-0.166001+dfsg.orig/lib/0000775000175000017500000000000012650351107016634 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/lib/Dancer2.pm0000644000175000017500000002035212650351107020450 0ustar gregoagregoapackage Dancer2; # ABSTRACT: Lightweight yet powerful web application framework $Dancer2::VERSION = '0.166001'; use strict; use warnings; use List::Util 'first'; use Class::Load 'load_class'; use Import::Into; use Dancer2::Core; use Dancer2::Core::App; use Dancer2::Core::Runner; use Dancer2::FileUtils; our $AUTHORITY = 'SUKRIA'; sub VERSION { shift->SUPER::VERSION(@_) || '0.000000_000' } our $runner; sub runner {$runner} sub psgi_app { shift->runner->psgi_app(@_) } sub import { my ( $class, @args ) = @_; my ( $caller, $script ) = caller; my @final_args; my $clean_import; foreach my $arg (@args) { # ignore, no longer necessary # in the future these will warn as deprecated grep +( $arg eq $_ ), qw<:script :syntax :tests> and next; if ( $arg eq ':nopragmas' ) { $clean_import++; next; } if ( substr( $arg, 0, 1 ) eq '!' ) { push @final_args, $arg, 1; } else { push @final_args, $arg; } } $clean_import or $_->import::into($caller) for qw; scalar @final_args % 2 and die q{parameters must be key/value pairs or '!keyword'}; my %final_args = @final_args; my $appname = delete $final_args{appname}; $appname ||= $caller; # never instantiated the runner, should do it now if ( not defined $runner ) { $runner = Dancer2::Core::Runner->new(); } # Search through registered apps, creating a new app object # if we do not find one with the same name. my $app; ($app) = first { $_->name eq $appname } @{ $runner->apps }; if ( ! $app ) { # populating with the server's postponed hooks in advance $app = Dancer2::Core::App->new( name => $appname, caller => $script, environment => $runner->environment, postponed_hooks => $runner->postponed_hooks->{$appname} || {}, ); # register the app within the runner instance $runner->register_application($app); } _set_import_method_to_caller($caller); # use config dsl class, must extend Dancer2::Core::DSL my $config_dsl = $app->setting('dsl_class') || 'Dancer2::Core::DSL'; $final_args{dsl} ||= $config_dsl; # load the DSL, defaulting to Dancer2::Core::DSL load_class( $final_args{dsl} ); my $dsl = $final_args{dsl}->new( app => $app ); $dsl->export_symbols_to( $caller, \%final_args ); } sub _set_import_method_to_caller { my ($caller) = @_; my $import = sub { my ( $self, %options ) = @_; my $with = $options{with}; for my $key ( keys %$with ) { $self->dancer_app->setting( $key => $with->{$key} ); } }; { no strict 'refs'; no warnings 'redefine'; *{"${caller}::import"} = $import; } } 1; __END__ =pod =encoding UTF-8 =head1 NAME Dancer2 - Lightweight yet powerful web application framework =head1 VERSION version 0.166001 =head1 DESCRIPTION Dancer2 is the new generation of L, the lightweight web-framework for Perl. Dancer2 is a complete rewrite based on L. Dancer2 can optionally use XS modules for speed, but at its core remains fatpackable (packable by L) so you could easily deploy Dancer2 applications on hosts that do not support custom CPAN modules. Dancer2 is easy and fun: use Dancer2; get '/' => sub { "Hello World" }; dance; This is the main module for the Dancer2 distribution. It contains logic for creating a new Dancer2 application. You are welcome to join our mailing list. For subscription information, mail address and archives see L. We are also on IRC: #dancer on irc.perl.org. =head2 Documentation Index Documentation on Dancer2 is split into several manpages. Below is a complete outline on where to go for help. =over 4 =item * Dancer2 Tutorial If you are new to the Dancer approach, you should start by reading our L. =item * Dancer2 Manual L is the reference for Dancer2. Here you will find information on the concepts of Dancer2 application development and a comprehensive reference to the Dancer2 domain specific language. =item * Dancer2 Keywords The keywords for Dancer2 can be found under L. =item * Dancer2 Deployment For configuration examples of different deployment solutions involving Dancer2 and Plack, refer to L. =item * Dancer2 Cookbook Specific examples of code for real-life problems and some 'tricks' for applications in Dancer can be found in L =item * Dancer2 Config For configuration file details refer to L. It is a complete list of all configuration options. =item * Dancer2 Plugins Refer to L for a partial list of available Dancer2 plugins. Note that although we try to keep this list up to date we expect plugin authors to tell us about new modules. =item * Dancer2 Migration guide L provides the most up-to-date instruction on how to convert a Dancer (1) based application to Dancer2. =back =head1 METHODS =head2 import; If it doesn't exist already, C creates a new runner, imports strict and warnings, loads additional libraries, creates a new Dancer2 app (of type L) and exports the DSL symbols to the caller. If any additional argument processing is needed, it will be done at this point. Import gets called when you use Dancer2. You can specify import options giving you control over the keywords that will be imported into your webapp and other things: use Dancer2 '!quux'; # Don't import DSL keyword quux use Dancer2 appname => 'MyAwesomeApp'; # Add routes and hooks to MyAwesomeApp use Dancer2 ( foo => 'bar' ); # sets option foo to bar (currently not implemented) =head1 FUNCTIONS =head2 my $runner=runner(); Returns the current runner. It is of type L. =head1 AUTHORS =head2 CORE DEVELOPERS Alberto Simões Alexis Sukrieh Damien Krotkine David Golden David Precious Franck Cuny Jason A. Crome Mickey Nasriachi Russell Jenkins Sawyer X Stefan Hornburg (Racke) Steven Humphrey Yanick Champoux =head2 CONTRIBUTORS A. Sinan Unur Ahmad M. Zawawi Alex Beamish Alexander Karelas Alexandr Ciornii Andrew Beverley Andrew Grangaard Andrew Inishev Andrew Solomon Andy Jack Ashvini V B10m Bas Bloemsaat baynes Ben Hutton Blabos de Blebe Breno G. de Oliveira cdmalon Celogeek Cesare Gargano Charlie Gonzalez chenchen000 Chi Trinh Christian Walde Colin Kuskie cym0n Dale Gallagher Daniel Muey David Steinbrunner David Zurborg Davs Dinis Rebolo dtcyganov Erik Smit Fayland Lam Gabor Szabo geistteufel Gideon D'souza Graham Knop Gregor Herrmann Grzegorz Rożniecki Hobbestigrou Ivan Bessarabov Ivan Kruglov JaHIY Jakob Voss James Aitken James Raspass Javier Rojas Jean Stebens Jens Rehsack Jonathan Scott Duff Julien Fiegehenn Julio Fraire Kaitlyn Parkhurst (SYMKAT) kbeyazli Keith Broughton lbeesley Lennart Hengstmengel Ludovic Tolhurst-Cleaver Mark A. Stratman Mateu X Hunter Matt Phillips Matt S Trout Maurice Menno Blom Michał Wojciechowski Mohammad S Anwar mokko Nick Patch Nick Tonkin Nikita K Nuno Carvalho Olaf Alders Olivier Mengué Omar M. Othman pants Patrick Zimmermann Pau Amma Paul Cochrane Pedro Bruno Pedro Melo Peter Mottram Rick Yakubowski sakshee3 Sam Kington Samit Badle Shlomi Fish simbabque Slava Goltser Snigdha Tina Müller Tom Hukins Upasana Shukla Vernon Lyon Vince Willems Vincent Bachelier =head1 AUTHOR Dancer Core Developers =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2015 by Alexis Sukrieh. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut libdancer2-perl-0.166001+dfsg.orig/lib/Dancer2/0000775000175000017500000000000012650351107020112 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/lib/Dancer2/Manual/0000775000175000017500000000000012650351107021327 5ustar gregoagregoalibdancer2-perl-0.166001+dfsg.orig/lib/Dancer2/Manual/Migration.pod0000644000175000017500000003113112650351107023761 0ustar gregoagregoapackage Dancer2::Manual::Migration; # ABSTRACT: Migrating from Dancer to Dancer2 use strict; use warnings; 1; __END__ =pod =encoding UTF-8 =head1 NAME Dancer2::Manual::Migration - Migrating from Dancer to Dancer2 =head1 VERSION version 0.166001 =head1 Migration from Dancer 1 to Dancer2 This document covers some changes that users will need to be aware of while upgrading from L (version 1) to L. =head2 Launcher script The default launcher script F in L looked like this: #!/usr/bin/env perl use Dancer; use MyApp; dance; In L it is available as F and looks like this: #!/usr/bin/env perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/../lib"; use MyApp; MyApp->to_app; So you need to remove the C part, replace the C command by C<< MyApp->to_app; >> (where MyApp is the name of your application), and add the following lines: use strict; use warnings; use FindBin; use lib "$FindBin::Bin/../lib"; There is a L article L<< covering the C keyword|http://advent.perldancer.org/2014/9 >> and its usage. =head2 Configuration You specify a different location to the directory used for serving static (public) content by setting the C option. In that case, you have to set C option also. =head2 Apps 1. In L, each module is a B with its own namespace and variables. You can set the application name in each of your L application modules. Different modules can be tied into the same app by setting the application name to the same value. For example, to set the appname directive explicitly: C: package MyApp; use Dancer2; use MyApp::Admin hook before => sub { var db => 'Users'; }; get '/' => sub {...}; 1; C: package MyApp::Admin; use Dancer2 appname => 'MyApp'; # use a lexical prefix so we don't override it globally prefix '/admin' => sub { get '/' => sub {...}; }; 1; Without the appname directive, C would not have access to variable C. In fact, when accessing C, the before hook would not be executed. See L for details. 2. The following modules can be used to speed up an app in Dancer2: =over 4 =item * L =item * L =item * L =item * L =back They would need to be installed separately. This is because L does not incorporate any C code, but it can get C-code compiled as a module. Thus, these modules can be used for speed improvement provided: =over 4 =item * You have access to a C interpreter =item * You don't need to fatpack your application =back =head2 Request The request object (L) is now deferring much of its code to L to be consistent with the known interface to L requests. Currently the following attributes pass directly to L: C
, C, C, C, C, C, C, C, C, C, C, C, and C. If previous attributes returned I for no value beforehand, they will return whatever L defines now, which just might be an empty list. For example: my %data = ( referer => request->referer, user_agent => request->user_agent, ); should be replaced by: my %data = ( referer => request->referer || '', user_agent => request->user_agent || '', ); =head2 Plugins: plugin_setting C returns the configuration of the plugin. It can only be called in C or C. =head2 Routes L requires all routes defined via a string to begin with a leading slash C. For example: get '0' => sub { return "not gonna fly"; }; would return an error. The correct way to write this would be to use C =head2 Route parameters The C keyword which provides merged parameters used to allow body parameters to override route parameters. Now route parameters take precedence over query parameters and body parameters. =head2 Tests Dancer2 recommends the use of L. For example: use strict; use warnings; use Test::More tests => 2; use Plack::Test; use HTTP::Request::Common; { package App::Test; # or whatever you want to call it get '/' => sub { template 'index' }; } my $test = Plack::Test->create( App::Test->to_app ); my $res = $test->request( GET '/' ); ok( $res->is_success, '[GET /] Successful' ); like( $res->content, qr{Test2}, 'Correct title' ); Other modules that could be used for testing are: =over 4 =item * L =item * L =back =head3 Logs The C in the Logger role (L) is now C. C can no longer be used, as with L. Instead, L could be used for testing, to capture all logs to an object. For example: use strict; use warnings; use Test::More import => ['!pass']; use Plack::Test; use HTTP::Request::Common; { package App; use Dancer2; set log => 'debug'; set logger => 'capture'; get '/' => sub { debug 'this is my debug message'; return 1; }; } my $app = Dancer2->psgi_app; is( ref $app, 'CODE', 'Got app' ); test_psgi $app, sub { my $cb = shift; my $res = $cb->( GET '/' ); is $res->code, 200; my $trap = App->dancer_app->logger_engine->trapper; is_deeply $trap->read, [ { level => 'debug', message => 'this is my debug message' } ]; }; =head2 Exports: Tags The following tags are not needed in L: use Dancer2 qw(:syntax); use Dancer2 qw(:tests); use Dancer2 qw(:script); The C command should be used instead. It provides a development server and reads the configuration options in your command line utilities. =head2 Engines =over 4 =item * Engines receive a logging callback Engines now receive a logging callback named C. Engines can use it to log anything in run-time, without having to worry about what logging engine is used. This is provided as a callback because the logger might be changed in run-time and we want engines to be able to always reach the current one without having a reference back to the core application object. The logger engine doesn't have the attribute since it is the logger itself. =item * Engines handle encoding consistently All engines are now expected to handle encoding on their own. User code is expected to be in internal Perl representation. Therefore, all serializers, for example, should deserialize to the Perl representation. Templates, in turn, encode to UTF-8 if requested by the user, or by default. One side-effect of this is that C will call L's C function with decoded input. =back =head3 Serializers You no longer need to implement the C method. It is simply unnecessary. =head3 Sessions Now the L session engine is turned on by default, unless you specify a different one. =head2 Configuration =head3 warnings The C configuration option, along with the environment variable C, have been removed and have no effect whatsoever. They were added when someone requested to be able to load Dancer without the L pragma, which it adds, just like L, L, and other modules provide. If you want this to happen now (which you probably shouldn't be doing), you can always control it lexically: use Dancer2; no warnings; You can also use Dancer2 within a narrower scope: { use Dancer2 } use strict; # warnings are not turned on However, having L turned it is very recommended. =head3 server_tokens The configuration C has been introduced in the reverse (but more sensible, and Plack-compatible) form as C. C changed to C. =head3 engines If you want to use Template::Toolkit instead of the built-in simple templating engine you used to enable the following line in the config.yml file. template: "template_toolkit" That was enough to get started. The start_tag and end_tag it used were the same as in the simple template <% and %> respectively. If you wanted to further customize the Template::Toolkit you could also enable or add the following: engines: template_toolkit: encoding: 'utf8' start_tag: '[%' end_tag: '%]' In Dancer 2 you can also enable Template::Toolkit with the same configuration option: template: "template_toolkit" But the default start_tag and end_tag are now [% and %], so if you used the default in Dancer 1 now you will have to explicitly change the start_tag and end_tag values. The configuration also got an extral level of depth. Under the C key there is a C