@@ -20,7 +20,7 @@ my %module_build_args = (
"Dancer Core Developers"
],
"dist_name" => "Dancer2",
- "dist_version" => "0.151000",
+ "dist_version" => "0.153002",
"license" => "perl",
"module_name" => "Dancer2",
"recommends" => {
@@ -72,7 +72,7 @@ my %module_build_args = (
"MooX::Types::MooseLike" => "0.16",
"MooX::Types::MooseLike::Base" => 0,
"POSIX" => 0,
- "Plack" => "1.0016",
+ "Plack" => "1.0029",
"Plack::Builder" => 0,
"Pod::Simple::Search" => 0,
"Pod::Simple::SimpleTree" => 0,
@@ -112,6 +112,7 @@ my %module_build_args = (
"IO::Handle" => 0,
"IPC::Open3" => 0,
"LWP::Protocol::PSGI" => "0.06",
+ "Plack::Response" => 0,
"Plack::Test" => 0,
"Test::Fatal" => 0,
"Test::Memory::Cycle" => "1.04",
@@ -141,6 +142,7 @@ my %fallback_build_requires = (
"IPC::Open3" => 0,
"LWP::Protocol::PSGI" => "0.06",
"Module::Build" => "0.3601",
+ "Plack::Response" => 0,
"Plack::Test" => 0,
"Test::Fatal" => 0,
"Test::Memory::Cycle" => "1.04",
@@ -1,3 +1,52 @@
+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 ]
@@ -16,7 +16,6 @@ lib/Dancer2/CLI/Command/version.pm
lib/Dancer2/Config.pod
lib/Dancer2/Cookbook.pod
lib/Dancer2/Core.pm
-lib/Dancer2/Core/.Request.pm.swp
lib/Dancer2/Core/App.pm
lib/Dancer2/Core/Cookie.pm
lib/Dancer2/Core/DSL.pm
@@ -62,6 +61,7 @@ lib/Dancer2/Manual/Migration.pod
lib/Dancer2/Plugin.pm
lib/Dancer2/Plugin/Ajax.pm
lib/Dancer2/Plugins.pod
+lib/Dancer2/Policy.pod
lib/Dancer2/Serializer/Dumper.pm
lib/Dancer2/Serializer/JSON.pm
lib/Dancer2/Serializer/Mutable.pm
@@ -114,8 +114,25 @@ t/author-no-tabs.t
t/auto_page.t
t/caller.t
t/charset_server.t
+t/classes/Dancer2-Core-Factory/create.t
+t/classes/Dancer2-Core-Hook/base.t
+t/classes/Dancer2-Core-Response/new_from.t
+t/classes/Dancer2-Core-Role-Engine/base.t
+t/classes/Dancer2-Core-Role-Handler/base.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/base.t
+t/classes/Dancer2-Core-Role-Headers/with.t
+t/classes/Dancer2-Core-Role-StandardResponses/base.t
+t/classes/Dancer2-Core-Runner/base.t
+t/classes/Dancer2-Core-Runner/environment.t
+t/classes/Dancer2-Core-Runner/psgi_app.t
+t/classes/Dancer2-Core/camelize.t
+t/classes/Dancer2/import.t
t/config.yml
t/config/config.yml
t/config/environments/failure.yml
@@ -138,6 +155,7 @@ t/dancer-test/config.yml
t/deserialize.t
t/dispatcher.t
t/dsl.t
+t/dsl/content.t
t/dsl/extend.t
t/dsl/extend_config/config.yml
t/dsl/halt.t
@@ -155,6 +173,9 @@ t/handler_file.t
t/hooks.t
t/http_methods.t
t/http_status.t
+t/issues/gh-634.t
+t/issues/gh-723.t
+t/issues/gh-730.t
t/lib/App1.pm
t/lib/App2.pm
t/lib/DancerPlugin.pm
@@ -170,7 +191,6 @@ t/lib/TestPod.pm
t/log_die_before_hook.t
t/log_levels.t
t/logger.t
-t/logger/file.t
t/logger_console.t
t/lwp-protocol-psgi.t
t/memory_cycles.t
@@ -193,7 +213,6 @@ t/request.t
t/request_params.t
t/request_upload.t
t/response.t
-t/roles/headers.t
t/roles/hook.t
t/route-pod-coverage/route-pod-coverage.t
t/route.t
@@ -206,10 +225,50 @@ 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/VBzn5-yKiV0ZEaZqEtEvK_pmMT8n4QQx.yml
+t/sessions/VD8wIQAAIErosiPuPzgc7Feo60_y7s2K.yml
+t/sessions/VD8xFwAAIfVHBp2nUIRlhPrHBxZFewkg.yml
+t/sessions/VD8xPwAAIqUQa3U0CK_Q43bf7JSaXj68.yml
t/sessions/VDKr30YvCd7R3WEniUv5Re5999E6SJmQ.yml
+t/sessions/VDf4nIP4n0A4Ya5vcE7SaaDntyVZj9oB.yml
+t/sessions/VDfsgXhalKhiOdSVDEk4iwyf_j3JJ1lU.yml
+t/sessions/VDgFcPJynjsERU0GCt8fE9hhT-R3ErKV.yml
+t/sessions/VDgH-lQYfi_XUNztQLT-6ebJ_gzwGZKp.yml
+t/sessions/VDgHth9A4cXrh0fLlBodXUMnCXkcPlOO.yml
+t/sessions/VDsBvbCel9L5vqAA8X12v_IKYwpqtEIb.yml
+t/sessions/VDsC67174msADj1P2kEtWWWWqenpf_Gh.yml
+t/sessions/VDsdec7YkN_t5HYgYTY4UTO0rGbd3quL.yml
+t/sessions/VDskH-mTqVSrtI7vn3Cfjc22M3sDZ4nf.yml
+t/sessions/VDxpkwmXPxXgntfDkSbIJIW3-ZmOV6F2.yml
+t/sessions/VDxr8vlFwjuihF5Oq6qfdcX_C-sqJFst.yml
+t/sessions/VDxsUBz1JAMQos-edO9ShtnKnIqjRugy.yml
+t/sessions/VDxszUJNZJrCm2146wLcBL4Tauj5tlx3.yml
+t/sessions/VDxtWd3557qlVPhU5y4QeEnoTzopT4XL.yml
+t/sessions/VDxuf7UcBT5V58xfDyZ2akeLCE0stVRe.yml
+t/sessions/VE1LtAAAI1ug7lcj3FDxEJY_qRPhfoA1.yml
+t/sessions/VE1kdAAAROjzAe8ZtNQUKGC4lxSPjTdr.yml
+t/sessions/VE1o4wAAS5VfIRWDZD6mSTy-ytif0XA-.yml
+t/sessions/VE1tnAAAUNnRsHJYuMwKK9g-F4v26HBh.yml
+t/sessions/VE27BgAAHJqJxusuS6yVI_5EYRhjTQbw.yml
+t/sessions/VE27agAAHXnzZhVBaOsvWl1uOsOcnvfT.yml
+t/sessions/VE2OEAAAXUMpJr0fKv_R132CQL6llNO6.yml
+t/sessions/VE2VaAAAZacndokHehKRMngyv8UNxKT6.yml
+t/sessions/VE2XCwAAZ9ygkhxx0mE_K_zWzXOmEhxE.yml
+t/sessions/VE2YUAAAarbI4Jc7p_1EsANQn3BiZ7Ac.yml
+t/sessions/VE2YygAAa2BSyhqX_xSUyxT98h-go-pc.yml
+t/sessions/VE2ZKgAAbLz495eORolB6FjskBnNB9ap.yml
+t/sessions/VE2ZjwAAbbYAr6pxPtFGzvqacCdwMll6.yml
+t/sessions/VE2e9QAAc2wGVnxW-a8HhiC98g7YEx3g.yml
+t/sessions/VE2enQAAcsZVTzEKdLzR9CDcSky4ZqUI.yml
+t/sessions/VE2fRwAAdAiI1T-NFBekMmSKBrwpHDUK.yml
+t/sessions/VE2gEAAAdOWFQRoXFFphEDM1iwFguvo-.yml
+t/sessions/VE2gXgAAdircA43YYaJojXFPnqLvT9M5.yml
+t/sessions/VE2grAAAdvaf8h_9-67vWmqukDEjs7vb.yml
+t/sessions/VE4s2AAAN-mIHpV45UJy67IvQVuZVeoG.yml
+t/sessions/VEcEMgAADIiqAdXb4PP-YxIqDskws7Qd.yml
t/shared_engines.t
t/splat.t
t/template.t
@@ -258,6 +317,7 @@ 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
@@ -83,7 +83,7 @@
"MooX::Types::MooseLike" : "0.16",
"MooX::Types::MooseLike::Base" : "0",
"POSIX" : "0",
- "Plack" : "1.0016",
+ "Plack" : "1.0029",
"Plack::Builder" : "0",
"Pod::Simple::Search" : "0",
"Pod::Simple::SimpleTree" : "0",
@@ -127,6 +127,7 @@
"IO::Handle" : "0",
"IPC::Open3" : "0",
"LWP::Protocol::PSGI" : "0.06",
+ "Plack::Response" : "0",
"Plack::Test" : "0",
"Test::Fatal" : "0",
"Test::Memory::Cycle" : "1.04",
@@ -145,235 +146,235 @@
"provides" : {
"Dancer2" : {
"file" : "lib/Dancer2.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::CLI" : {
"file" : "lib/Dancer2/CLI.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::CLI::Command::gen" : {
"file" : "lib/Dancer2/CLI/Command/gen.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::CLI::Command::version" : {
"file" : "lib/Dancer2/CLI/Command/version.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core" : {
"file" : "lib/Dancer2/Core.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::App" : {
"file" : "lib/Dancer2/Core/App.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Cookie" : {
"file" : "lib/Dancer2/Core/Cookie.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::DSL" : {
"file" : "lib/Dancer2/Core/DSL.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Dispatcher" : {
"file" : "lib/Dancer2/Core/Dispatcher.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Error" : {
"file" : "lib/Dancer2/Core/Error.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Factory" : {
"file" : "lib/Dancer2/Core/Factory.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::HTTP" : {
"file" : "lib/Dancer2/Core/HTTP.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Hook" : {
"file" : "lib/Dancer2/Core/Hook.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::MIME" : {
"file" : "lib/Dancer2/Core/MIME.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Request" : {
"file" : "lib/Dancer2/Core/Request.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Request::Upload" : {
"file" : "lib/Dancer2/Core/Request/Upload.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Response" : {
"file" : "lib/Dancer2/Core/Response.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::ConfigReader" : {
"file" : "lib/Dancer2/Core/Role/ConfigReader.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::DSL" : {
"file" : "lib/Dancer2/Core/Role/DSL.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::Engine" : {
"file" : "lib/Dancer2/Core/Role/Engine.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::Handler" : {
"file" : "lib/Dancer2/Core/Role/Handler.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::HasLocation" : {
"file" : "lib/Dancer2/Core/Role/HasLocation.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::Headers" : {
"file" : "lib/Dancer2/Core/Role/Headers.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::Hookable" : {
"file" : "lib/Dancer2/Core/Role/Hookable.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::Logger" : {
"file" : "lib/Dancer2/Core/Role/Logger.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::Serializer" : {
"file" : "lib/Dancer2/Core/Role/Serializer.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::SessionFactory" : {
"file" : "lib/Dancer2/Core/Role/SessionFactory.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::SessionFactory::File" : {
"file" : "lib/Dancer2/Core/Role/SessionFactory/File.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::StandardResponses" : {
"file" : "lib/Dancer2/Core/Role/StandardResponses.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Role::Template" : {
"file" : "lib/Dancer2/Core/Role/Template.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Route" : {
"file" : "lib/Dancer2/Core/Route.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Runner" : {
"file" : "lib/Dancer2/Core/Runner.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Session" : {
"file" : "lib/Dancer2/Core/Session.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Time" : {
"file" : "lib/Dancer2/Core/Time.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Core::Types" : {
"file" : "lib/Dancer2/Core/Types.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::FileUtils" : {
"file" : "lib/Dancer2/FileUtils.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Handler::AutoPage" : {
"file" : "lib/Dancer2/Handler/AutoPage.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Handler::File" : {
"file" : "lib/Dancer2/Handler/File.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Logger::Capture" : {
"file" : "lib/Dancer2/Logger/Capture.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Logger::Capture::Trap" : {
"file" : "lib/Dancer2/Logger/Capture/Trap.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Logger::Console" : {
"file" : "lib/Dancer2/Logger/Console.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Logger::Diag" : {
"file" : "lib/Dancer2/Logger/Diag.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Logger::File" : {
"file" : "lib/Dancer2/Logger/File.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Logger::Note" : {
"file" : "lib/Dancer2/Logger/Note.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Logger::Null" : {
"file" : "lib/Dancer2/Logger/Null.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Plugin" : {
"file" : "lib/Dancer2/Plugin.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Plugin::Ajax" : {
"file" : "lib/Dancer2/Plugin/Ajax.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Serializer::Dumper" : {
"file" : "lib/Dancer2/Serializer/Dumper.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Serializer::JSON" : {
"file" : "lib/Dancer2/Serializer/JSON.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Serializer::Mutable" : {
"file" : "lib/Dancer2/Serializer/Mutable.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Serializer::YAML" : {
"file" : "lib/Dancer2/Serializer/YAML.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Session::Simple" : {
"file" : "lib/Dancer2/Session/Simple.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Session::YAML" : {
"file" : "lib/Dancer2/Session/YAML.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Template::Implementation::ForkedTiny" : {
"file" : "lib/Dancer2/Template/Implementation/ForkedTiny.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Template::Simple" : {
"file" : "lib/Dancer2/Template/Simple.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Template::TemplateToolkit" : {
"file" : "lib/Dancer2/Template/TemplateToolkit.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Template::Tiny" : {
"file" : "lib/Dancer2/Template/Tiny.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
},
"Dancer2::Test" : {
"file" : "lib/Dancer2/Test.pm",
- "version" : "0.151000"
+ "version" : "0.153002"
}
},
"release_status" : "stable",
@@ -390,6 +391,6 @@
"x_IRC" : "irc://irc.perl.org/#dancer",
"x_WebIRC" : "https://chat.mibbit.com/#dancer@irc.perl.org"
},
- "version" : "0.151000"
+ "version" : "0.153002"
}
@@ -15,6 +15,7 @@ build_requires:
IPC::Open3: 0
LWP::Protocol::PSGI: 0.06
Module::Build: 0.3601
+ Plack::Response: 0
Plack::Test: 0
Test::Fatal: 0
Test::Memory::Cycle: 1.04
@@ -41,178 +42,178 @@ name: Dancer2
provides:
Dancer2:
file: lib/Dancer2.pm
- version: 0.151000
+ version: 0.153002
Dancer2::CLI:
file: lib/Dancer2/CLI.pm
- version: 0.151000
+ version: 0.153002
Dancer2::CLI::Command::gen:
file: lib/Dancer2/CLI/Command/gen.pm
- version: 0.151000
+ version: 0.153002
Dancer2::CLI::Command::version:
file: lib/Dancer2/CLI/Command/version.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core:
file: lib/Dancer2/Core.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::App:
file: lib/Dancer2/Core/App.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Cookie:
file: lib/Dancer2/Core/Cookie.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::DSL:
file: lib/Dancer2/Core/DSL.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Dispatcher:
file: lib/Dancer2/Core/Dispatcher.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Error:
file: lib/Dancer2/Core/Error.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Factory:
file: lib/Dancer2/Core/Factory.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::HTTP:
file: lib/Dancer2/Core/HTTP.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Hook:
file: lib/Dancer2/Core/Hook.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::MIME:
file: lib/Dancer2/Core/MIME.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Request:
file: lib/Dancer2/Core/Request.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Request::Upload:
file: lib/Dancer2/Core/Request/Upload.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Response:
file: lib/Dancer2/Core/Response.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::ConfigReader:
file: lib/Dancer2/Core/Role/ConfigReader.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::DSL:
file: lib/Dancer2/Core/Role/DSL.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::Engine:
file: lib/Dancer2/Core/Role/Engine.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::Handler:
file: lib/Dancer2/Core/Role/Handler.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::HasLocation:
file: lib/Dancer2/Core/Role/HasLocation.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::Headers:
file: lib/Dancer2/Core/Role/Headers.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::Hookable:
file: lib/Dancer2/Core/Role/Hookable.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::Logger:
file: lib/Dancer2/Core/Role/Logger.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::Serializer:
file: lib/Dancer2/Core/Role/Serializer.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::SessionFactory:
file: lib/Dancer2/Core/Role/SessionFactory.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::SessionFactory::File:
file: lib/Dancer2/Core/Role/SessionFactory/File.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::StandardResponses:
file: lib/Dancer2/Core/Role/StandardResponses.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Role::Template:
file: lib/Dancer2/Core/Role/Template.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Route:
file: lib/Dancer2/Core/Route.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Runner:
file: lib/Dancer2/Core/Runner.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Session:
file: lib/Dancer2/Core/Session.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Time:
file: lib/Dancer2/Core/Time.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Core::Types:
file: lib/Dancer2/Core/Types.pm
- version: 0.151000
+ version: 0.153002
Dancer2::FileUtils:
file: lib/Dancer2/FileUtils.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Handler::AutoPage:
file: lib/Dancer2/Handler/AutoPage.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Handler::File:
file: lib/Dancer2/Handler/File.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Logger::Capture:
file: lib/Dancer2/Logger/Capture.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Logger::Capture::Trap:
file: lib/Dancer2/Logger/Capture/Trap.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Logger::Console:
file: lib/Dancer2/Logger/Console.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Logger::Diag:
file: lib/Dancer2/Logger/Diag.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Logger::File:
file: lib/Dancer2/Logger/File.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Logger::Note:
file: lib/Dancer2/Logger/Note.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Logger::Null:
file: lib/Dancer2/Logger/Null.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Plugin:
file: lib/Dancer2/Plugin.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Plugin::Ajax:
file: lib/Dancer2/Plugin/Ajax.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Serializer::Dumper:
file: lib/Dancer2/Serializer/Dumper.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Serializer::JSON:
file: lib/Dancer2/Serializer/JSON.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Serializer::Mutable:
file: lib/Dancer2/Serializer/Mutable.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Serializer::YAML:
file: lib/Dancer2/Serializer/YAML.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Session::Simple:
file: lib/Dancer2/Session/Simple.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Session::YAML:
file: lib/Dancer2/Session/YAML.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Template::Implementation::ForkedTiny:
file: lib/Dancer2/Template/Implementation/ForkedTiny.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Template::Simple:
file: lib/Dancer2/Template/Simple.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Template::TemplateToolkit:
file: lib/Dancer2/Template/TemplateToolkit.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Template::Tiny:
file: lib/Dancer2/Template/Tiny.pm
- version: 0.151000
+ version: 0.153002
Dancer2::Test:
file: lib/Dancer2/Test.pm
- version: 0.151000
+ version: 0.153002
recommends:
CGI::Deurl::XS: 0
Crypt::URandom: 0
@@ -260,7 +261,7 @@ requires:
MooX::Types::MooseLike: 0.16
MooX::Types::MooseLike::Base: 0
POSIX: 0
- Plack: 1.0016
+ Plack: 1.0029
Plack::Builder: 0
Pod::Simple::Search: 0
Pod::Simple::SimpleTree: 0
@@ -287,4 +288,4 @@ resources:
bugtracker: https://github.com/PerlDancer/Dancer2/issues
homepage: http://perldancer.org/
repository: https://github.com/PerlDancer/Dancer2
-version: 0.151000
+version: 0.153002
@@ -66,7 +66,7 @@ my %WriteMakefileArgs = (
"MooX::Types::MooseLike" => "0.16",
"MooX::Types::MooseLike::Base" => 0,
"POSIX" => 0,
- "Plack" => "1.0016",
+ "Plack" => "1.0029",
"Plack::Builder" => 0,
"Pod::Simple::Search" => 0,
"Pod::Simple::SimpleTree" => 0,
@@ -99,6 +99,7 @@ my %WriteMakefileArgs = (
"IO::Handle" => 0,
"IPC::Open3" => 0,
"LWP::Protocol::PSGI" => "0.06",
+ "Plack::Response" => 0,
"Plack::Test" => 0,
"Test::Fatal" => 0,
"Test::Memory::Cycle" => "1.04",
@@ -111,9 +112,9 @@ my %WriteMakefileArgs = (
"utf8" => 0,
"vars" => 0
},
- "VERSION" => "0.151000",
+ "VERSION" => "0.153002",
"test" => {
- "TESTS" => "t/*.t t/dsl/*.t t/logger/*.t t/roles/*.t t/route-pod-coverage/*.t t/template_tiny/*.t"
+ "TESTS" => "t/*.t t/classes/Dancer2-Core-Factory/*.t t/classes/Dancer2-Core-Hook/*.t t/classes/Dancer2-Core-Response/*.t t/classes/Dancer2-Core-Role-Engine/*.t t/classes/Dancer2-Core-Role-Handler/*.t t/classes/Dancer2-Core-Role-HasLocation/*.t t/classes/Dancer2-Core-Role-Headers/*.t t/classes/Dancer2-Core-Role-StandardResponses/*.t t/classes/Dancer2-Core-Runner/*.t t/classes/Dancer2-Core/*.t t/classes/Dancer2/*.t t/dsl/*.t t/issues/*.t t/roles/*.t t/route-pod-coverage/*.t t/template_tiny/*.t"
}
);
@@ -163,8 +164,9 @@ my %FallbackPrereqs = (
"MooX::Types::MooseLike" => "0.16",
"MooX::Types::MooseLike::Base" => 0,
"POSIX" => 0,
- "Plack" => "1.0016",
+ "Plack" => "1.0029",
"Plack::Builder" => 0,
+ "Plack::Response" => 0,
"Plack::Test" => 0,
"Pod::Simple::Search" => 0,
"Pod::Simple::SimpleTree" => 0,
@@ -1,6 +1,6 @@
# ABSTRACT: create new Dancer2 application
package Dancer2::CLI::Command::gen;
-$Dancer2::CLI::Command::gen::VERSION = '0.151000';
+$Dancer2::CLI::Command::gen::VERSION = '0.153002';
use strict;
use warnings;
@@ -279,7 +279,7 @@ Dancer2::CLI::Command::gen - create new Dancer2 application
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::CLI::Command::version;
# ABSTRACT: display version
-$Dancer2::CLI::Command::version::VERSION = '0.151000';
+$Dancer2::CLI::Command::version::VERSION = '0.153002';
use App::Cmd::Setup -command;
sub description { 'Display version of Dancer2' }
@@ -29,7 +29,7 @@ Dancer2::CLI::Command::version - display version
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::CLI;
# ABSTRACT: Dancer2 cli application
-$Dancer2::CLI::VERSION = '0.151000';
+$Dancer2::CLI::VERSION = '0.153002';
use App::Cmd::Setup -app;
1;
@@ -17,7 +17,7 @@ Dancer2::CLI - Dancer2 cli application
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::Config;
# ABSTRACT: Configure Dancer2 to suit your needs
-$Dancer2::Config::VERSION = '0.151000';
+$Dancer2::Config::VERSION = '0.153002';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Config - Configure Dancer2 to suit your needs
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Cookbook;
# ABSTRACT: Example-driven quick-start to the Dancer2 web framework
-$Dancer2::Cookbook::VERSION = '0.151000';
+$Dancer2::Cookbook::VERSION = '0.153002';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Cookbook - Example-driven quick-start to the Dancer2 web framework
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
diff --git a/var/tmp/source/XSAWYERX/Dancer2-0.151000/Dancer2-0.151000/lib/Dancer2/Core/.Request.pm.swp b/var/tmp/source/XSAWYERX/Dancer2-0.151000/Dancer2-0.151000/lib/Dancer2/Core/.Request.pm.swp
deleted file mode 100644
index 39b007e9..00000000
Binary files a/var/tmp/source/XSAWYERX/Dancer2-0.151000/Dancer2-0.151000/lib/Dancer2/Core/.Request.pm.swp and /dev/null differ
@@ -1,6 +1,6 @@
# ABSTRACT: encapsulation of Dancer2 packages
package Dancer2::Core::App;
-$Dancer2::Core::App::VERSION = '0.151000';
+$Dancer2::Core::App::VERSION = '0.153002';
use Moo;
use Carp 'croak';
use Scalar::Util 'blessed';
@@ -13,11 +13,12 @@ use Plack::Builder;
use Dancer2::FileUtils 'path';
use Dancer2::Core;
use Dancer2::Core::Cookie;
+use Dancer2::Core::Error;
use Dancer2::Core::Types;
use Dancer2::Core::Route;
use Dancer2::Core::Hook;
use Dancer2::Core::Request;
-
+use Dancer2::Core::Factory;
# we have hooks here
with 'Dancer2::Core::Role::Hookable';
@@ -25,6 +26,13 @@ with 'Dancer2::Core::Role::ConfigReader';
sub supported_engines { [ qw<logger serializer session template> ] }
+has _factory => (
+ is => 'ro',
+ isa => Object['Dancer2::Core::Factory'],
+ lazy => 1,
+ default => sub { Dancer2::Core::Factory->new },
+);
+
has logger_engine => (
is => 'ro',
isa => Maybe[ConsumerOf['Dancer2::Core::Role::Logger']],
@@ -57,6 +65,16 @@ has serializer_engine => (
writer => 'set_serializer_engine',
);
+sub defined_engines {
+ my $self = shift;
+ return map {
+ my $type = "${_}_engine";
+ my $engine = $self->$type;
+
+ defined $engine ? $engine : ()
+ } @{ $self->supported_engines };
+}
+
has '+local_triggers' => (
default => sub {
my $self = shift;
@@ -126,9 +144,11 @@ sub _build_logger_engine {
my $engine_options =
$self->_get_config_for_engine( logger => $value, $config );
- my $logger = Dancer2::Core::Factory->create(
+ my $logger = $self->_factory->create(
logger => $value,
%{$engine_options},
+ location => $self->config_location,
+ environment => $self->environment,
app_name => $self->name,
postponed_hooks => $self->get_postponed_hooks
);
@@ -154,7 +174,7 @@ sub _build_session_engine {
my $engine_options =
$self->_get_config_for_engine( session => $value, $config );
- return Dancer2::Core::Factory->create(
+ return $self->_factory->create(
session => $value,
%{$engine_options},
postponed_hooks => $self->get_postponed_hooks,
@@ -183,7 +203,7 @@ sub _build_template_engine {
$engine_attrs->{views} ||= $config->{views}
|| path( $self->location, 'views' );
- return Dancer2::Core::Factory->create(
+ return $self->_factory->create(
template => $value,
%{$engine_attrs},
postponed_hooks => $self->get_postponed_hooks,
@@ -204,7 +224,7 @@ sub _build_serializer_engine {
my $engine_options =
$self->_get_config_for_engine( serializer => $value, $config );
- return Dancer2::Core::Factory->create(
+ return $self->_factory->create(
serializer => $value,
config => $engine_options,
postponed_hooks => $self->get_postponed_hooks,
@@ -357,9 +377,11 @@ sub destroy_session {
$session->expires(-86400); # yesterday
$engine->destroy( id => $session->id );
- # Clear session and invalidate session cookie in request
+ # Invalidate session cookie in request
+ # and clear session in app and engines
$self->set_destroyed_session($session);
$self->clear_session;
+ $_->clear_session for $self->defined_engines;
return;
}
@@ -367,10 +389,7 @@ sub destroy_session {
sub setup_session {
my $self = shift;
- for my $type ( @{ $self->supported_engines } ) {
- my $attr = "${type}_engine";
- my $engine = $self->$attr or next;
-
+ for my $engine ( $self->defined_engines ) {
$self->has_session ?
$engine->set_session( $self->session ) :
$engine->clear_session;
@@ -518,10 +537,23 @@ sub _init_hooks {
# session, first flush the session so cookie-based sessions can
# update the session ID if needed, then set the session cookie
# in the response
+ #
+ # if there is NO session object but the request has a cookie with
+ # a session key, create a dummy session with the same ID (without
+ # actually retrieving and flushing immediately) and generate the
+ # cookie header from the dummy session. Lazy Sessions FTW!
if ( $app->has_session ) {
- my $session = $app->session;
- $session->is_dirty and $engine->flush( session => $session );
+ my $session;
+ if ( $app->_has_session ) { # Session object exists
+ $session = $app->session;
+ $session->is_dirty and $engine->flush( session => $session );
+ }
+ else { # Cookie header exists. Create a dummy session object
+ my $cookie = $app->cookie( $engine->cookie_name );
+ my $session_id = $cookie->value;
+ $session = Dancer2::Core::Session->new( id => $session_id );
+ }
$engine->set_cookie_header(
response => $response,
session => $session
@@ -575,6 +607,11 @@ sub cleanup {
$self->clear_response;
$self->clear_session;
$self->clear_destroyed_session;
+ # Clear engine attributes
+ for my $engine ( $self->defined_engines ) {
+ $engine->clear_session;
+ $engine->clear_request;
+ }
}
sub engine {
@@ -595,18 +632,13 @@ sub template {
$template->set_settings( $self->config );
# return content
- return $template->process( $self->request, @_ );
+ return $template->process( @_ );
}
sub hook_candidates {
my $self = shift;
- my @engines;
- for my $e ( @{ $self->supported_engines } ) {
- my $attr = "${e}_engine";
- my $engine = $self->$attr or next;
- push @engines, $engine;
- }
+ my @engines = $self->defined_engines;
my @route_handlers;
for my $handler ( @{ $self->route_handlers } ) {
@@ -653,6 +685,23 @@ sub log {
$logger->$level(@_);
}
+sub send_error {
+ my $self = shift;
+ my ( $message, $status ) = @_;
+
+ my $serializer = $self->engine('serializer');
+ my $err = Dancer2::Core::Error->new(
+ message => $message,
+ app => $self,
+ ( status => $status )x!! $status,
+ ( serializer => $serializer )x!! $serializer,
+ )->throw;
+
+ # Immediately return to dispatch if with_return coderef exists
+ $self->has_with_return && $self->with_return->($err);
+ return $err;
+}
+
sub send_file {
my $self = shift;
my $path = shift;
@@ -675,7 +724,7 @@ sub send_file {
# pretending it's a file (on-the-fly file sending)
ref $path eq 'SCALAR' and return $$path;
- my $file_handler = Dancer2::Core::Factory->create(
+ my $file_handler = $self->_factory->create(
Handler => 'File',
app => $self,
postponed_hooks => $self->postponed_hooks,
@@ -718,7 +767,7 @@ sub init_route_handlers {
my ($handler_name, $config) = @{$handler_data};
$config = {} if !ref($config);
- my $handler = Dancer2::Core::Factory->create(
+ my $handler = $self->_factory->create(
Handler => $handler_name,
app => $self,
%$config,
@@ -1008,7 +1057,9 @@ DISPATCH:
$request->_set_route_params($match);
+ # Add request to app and engines
$self->set_request($request);
+ $_->set_request( $request ) for $self->defined_engines;
# Add session to app *if* we have a session and the request
# has the appropriate cookie header for _this_ app.
@@ -1072,6 +1123,10 @@ DISPATCH:
and delete $request->{_params}{splat};
$response->has_passed(0); # clear for the next round
+
+ # clear the content because if you pass it,
+ # the next route is in charge of catching it
+ $response->clear_content;
next ROUTE;
}
@@ -1091,7 +1146,13 @@ DISPATCH:
# make sure Core::Dispatcher recognizes this failure
# so it can try the next Core::App
- Dancer2->runner->{'internal_404'} = 1;
+ # and set the created request so we don't create it again
+ # (this is important so we don't ignore the previous body)
+ if ( Dancer2->runner->{'internal_dispatch'} ) {
+ Dancer2->runner->{'internal_404'} = 1;
+ Dancer2->runner->{'internal_request'} = $request;
+ }
+
return $self->response_not_found($request);
}
@@ -1102,19 +1163,10 @@ sub build_request {
my $engine = $self->serializer_engine;
my $request = Dancer2::Core::Request->new(
env => $env,
- is_behind_proxy => Dancer2->runner->config->{'behind_proxy'} || 0,
+ is_behind_proxy => $self->settings->{'behind_proxy'} || 0,
( serializer => $engine )x!! $engine,
);
- # if it's a mutable serializer, we add more headers
- # so it can be set properly
- # I don't like doing this... -- Sawyer
- if ( $engine->$_isa('Dancer2::Serializer::Mutable') ) {
- $engine->{'extra_headers'} = {
- map +( $_ => $request->$_ ), qw<content_type accept accept_type>
- }
- }
-
# Log deserialization errors
if ($engine) {
$engine->has_error and $self->log(
@@ -1130,9 +1182,6 @@ sub build_request {
sub _dispatch_route {
my ( $self, $route ) = @_;
- # FIXME: check for memory leak here
- # perhaps we need to weaken $self, perhaps not
- # would it matter if we do? could it be a problem?
$self->execute_hook( 'core.app.before_request', $self );
my $response = $self->response;
@@ -1142,22 +1191,19 @@ sub _dispatch_route {
$content = $response->content;
}
else {
- # FIXME: check for memory leak here
- # perhaps we need to weaken $self, perhaps not
- # would it matter if we do? could it be a problem?
$content = eval { $route->execute($self) };
my $error = $@;
if ($error) {
$self->log( error => "Route exception: $error" );
- # FIXME: check for memory leak here
- # perhaps we need to weaken $self, perhaps not
- # would it matter if we do? could it be a problem?
$self->execute_hook( 'core.app.route_exception', $self, $error );
return $self->response_internal_error($error);
}
}
+ $response->has_content
+ and $content = $response->content;
+
if ( ref $content eq 'Dancer2::Core::Response' ) {
$response = $self->set_response($content);
}
@@ -1219,7 +1265,7 @@ Dancer2::Core::App - encapsulation of Dancer2 packages
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Cookie;
# ABSTRACT: A cookie representing class
-$Dancer2::Core::Cookie::VERSION = '0.151000';
+$Dancer2::Core::Cookie::VERSION = '0.153002';
use Moo;
use URI::Escape;
use Dancer2::Core::Types;
@@ -106,7 +106,7 @@ Dancer2::Core::Cookie - A cookie representing class
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,12 +1,11 @@
# ABSTRACT: Dancer2's Domain Specific Language (DSL)
package Dancer2::Core::DSL;
-$Dancer2::Core::DSL::VERSION = '0.151000';
+$Dancer2::Core::DSL::VERSION = '0.153002';
use Moo;
use Carp;
use Class::Load 'load_class';
use Dancer2::Core::Hook;
-use Dancer2::Core::Error;
use Dancer2::FileUtils;
with 'Dancer2::Core::Role::DSL';
@@ -20,6 +19,7 @@ sub dsl_keywords {
app => { is_global => 1 },
captures => { is_global => 0 },
config => { is_global => 1 },
+ content => { is_global => 0 },
content_type => { is_global => 0 },
context => { is_global => 0 },
cookie => { is_global => 0 },
@@ -142,6 +142,8 @@ sub session {
}
}
+sub send_error { shift->app->send_error(@_) }
+
sub send_file { shift->app->send_file(@_) }
#
@@ -291,6 +293,7 @@ sub status { shift->response->status(@_) }
sub push_header { shift->response->push_header(@_) }
sub header { shift->response->header(@_) }
sub headers { shift->response->header(@_) }
+sub content { shift->response->content(@_) }
sub content_type { shift->response->content_type(@_) }
sub pass { shift->app->pass }
@@ -341,24 +344,6 @@ sub mime {
}
}
-sub send_error {
- my ( $self, $message, $status ) = @_;
-
- my $serializer = $self->app->engine('serializer');
- my $x = Dancer2::Core::Error->new(
- message => $message,
- app => $self->app,
- ( status => $status )x!! $status,
- ( serializer => $serializer )x!! $serializer,
- )->throw;
-
- # return if there is a with_return coderef
- $self->app->with_return->($x)
- if $self->app->has_with_return;
-
- return $x;
-}
-
#
# engines
#
@@ -415,7 +400,7 @@ Dancer2::Core::DSL - Dancer2's Domain Specific Language (DSL)
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 FUNCTIONS
@@ -1,6 +1,6 @@
package Dancer2::Core::Dispatcher;
# ABSTRACT: Class for dispatching request to the appropriate route handler
-$Dancer2::Core::Dispatcher::VERSION = '0.151000';
+$Dancer2::Core::Dispatcher::VERSION = '0.153002';
use Moo;
use Dancer2::Core::Types;
@@ -46,6 +46,7 @@ sub dispatch {
}
# don't run anymore
+ delete Dancer2->runner->{'internal_request'};
last;
} # while
@@ -69,7 +70,7 @@ Dancer2::Core::Dispatcher - Class for dispatching request to the appropriate rou
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Core::Error;
# ABSTRACT: Class representing fatal errors
-$Dancer2::Core::Error::VERSION = '0.151000';
+$Dancer2::Core::Error::VERSION = '0.153002';
use Moo;
use Carp;
use Dancer2::Core::Types;
@@ -488,7 +488,7 @@ Dancer2::Core::Error - Class representing fatal errors
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,9 +1,7 @@
package Dancer2::Core::Factory;
# ABSTRACT: Instantiate components by type and name
-$Dancer2::Core::Factory::VERSION = '0.151000';
-use strict;
-use warnings;
-
+$Dancer2::Core::Factory::VERSION = '0.153002';
+use Moo;
use Dancer2::Core;
use Class::Load 'try_load_class';
use Carp 'croak';
@@ -35,7 +33,7 @@ Dancer2::Core::Factory - Instantiate components by type and name
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 AUTHOR
@@ -1,7 +1,7 @@
# ABSTRACT: helper for rendering HTTP status codes for Dancer2
package Dancer2::Core::HTTP;
-$Dancer2::Core::HTTP::VERSION = '0.151000';
+$Dancer2::Core::HTTP::VERSION = '0.153002';
use strict;
use warnings;
@@ -134,7 +134,7 @@ Dancer2::Core::HTTP - helper for rendering HTTP status codes for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 FUNCTIONS
@@ -1,6 +1,6 @@
package Dancer2::Core::Hook;
# ABSTRACT: Manipulate hooks with Dancer2
-$Dancer2::Core::Hook::VERSION = '0.151000';
+$Dancer2::Core::Hook::VERSION = '0.153002';
use Moo;
use Dancer2::Core::Types;
use Carp;
@@ -51,7 +51,7 @@ Dancer2::Core::Hook - Manipulate hooks with Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,7 +1,7 @@
# ABSTRACT: Class to ease manipulation of MIME types
package Dancer2::Core::MIME;
-$Dancer2::Core::MIME::VERSION = '0.151000';
+$Dancer2::Core::MIME::VERSION = '0.153002';
use Moo;
use MIME::Types;
@@ -90,7 +90,7 @@ Dancer2::Core::MIME - Class to ease manipulation of MIME types
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Core::Request::Upload;
# ABSTRACT: Class representing file upload requests
-$Dancer2::Core::Request::Upload::VERSION = '0.151000';
+$Dancer2::Core::Request::Upload::VERSION = '0.153002';
use Moo;
use Carp;
@@ -91,7 +91,7 @@ Dancer2::Core::Request::Upload - Class representing file upload requests
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,5 +1,5 @@
package Dancer2::Core::Request;
-$Dancer2::Core::Request::VERSION = '0.151000';
+$Dancer2::Core::Request::VERSION = '0.153002';
# ABSTRACT: Interface for accessing incoming requests
use Moo;
@@ -714,7 +714,7 @@ Dancer2::Core::Request - Interface for accessing incoming requests
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,7 +1,7 @@
# ABSTRACT: Response object for Dancer2
package Dancer2::Core::Response;
-$Dancer2::Core::Response::VERSION = '0.151000';
+$Dancer2::Core::Response::VERSION = '0.153002';
use Moo;
use Encode;
@@ -69,7 +69,6 @@ has status => (
has content => (
is => 'rw',
isa => Str,
- default => sub {''},
coerce => sub {
my $value = shift;
return "$value";
@@ -82,6 +81,9 @@ has content => (
$self->has_passed or $self->header( 'Content-Length' => length($value) );
return $value;
},
+
+ predicate => 'has_content',
+ clearer => 'clear_content',
);
before content => sub {
@@ -118,6 +120,26 @@ sub encode_content {
return $content;
}
+sub new_from_plack {
+ my ($self, $psgi_res) = @_;
+
+ return Dancer2::Core::Response->new(
+ status => $psgi_res->status,
+ headers => $psgi_res->headers,
+ content => $psgi_res->body,
+ );
+}
+
+sub new_from_array {
+ my ($self, $arrayref) = @_;
+
+ return Dancer2::Core::Response->new(
+ status => $arrayref->[0],
+ headers => $arrayref->[1],
+ content => $arrayref->[2][0],
+ );
+}
+
sub to_psgi {
my ($self) = @_;
# It is possible to have no content and/or no content type set
@@ -201,7 +223,7 @@ Dancer2::Core::Response - Response object for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 ATTRIBUTES
@@ -254,6 +276,14 @@ Interally, it uses the L<is_encoded> flag to make sure that content is not encod
If it encodes the content, then it will return the encoded content. In all other
cases it returns C<false>.
+=head2 new_from_plack
+
+Creates a new response object from a L<Plack::Response> object.
+
+=head2 new_from_array
+
+Creates a new response object from a PSGI arrayref.
+
=head2 to_psgi
Converts the response object to a PSGI array.
@@ -1,6 +1,6 @@
# ABSTRACT: Config role for Dancer2 core objects
package Dancer2::Core::Role::ConfigReader;
-$Dancer2::Core::Role::ConfigReader::VERSION = '0.151000';
+$Dancer2::Core::Role::ConfigReader::VERSION = '0.153002';
use Moo::Role;
use File::Spec;
@@ -274,7 +274,7 @@ Dancer2::Core::Role::ConfigReader - Config role for Dancer2 core objects
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::DSL;
# ABSTRACT: Role for DSL
-$Dancer2::Core::Role::DSL::VERSION = '0.151000';
+$Dancer2::Core::Role::DSL::VERSION = '0.153002';
use Moo::Role;
use Dancer2::Core::Types;
use Carp 'croak';
@@ -106,7 +106,7 @@ Dancer2::Core::Role::DSL - Role for DSL
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Engine;
# ABSTRACT: Role for engines
-$Dancer2::Core::Role::Engine::VERSION = '0.151000';
+$Dancer2::Core::Role::Engine::VERSION = '0.153002';
use Moo::Role;
use Dancer2::Core::Types;
@@ -15,11 +15,19 @@ has session => (
);
has config => (
- is => 'rw',
+ is => 'ro',
isa => HashRef,
default => sub { {} },
);
+has request => (
+ is => 'ro',
+ isa => InstanceOf['Dancer2::Core::Request'],
+ writer => 'set_request',
+ clearer => 'clear_request',
+ predicate => 'has_request',
+);
+
1;
__END__
@@ -34,7 +42,7 @@ Dancer2::Core::Role::Engine - Role for engines
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Handler;
# ABSTRACT: Role for Handlers
-$Dancer2::Core::Role::Handler::VERSION = '0.151000';
+$Dancer2::Core::Role::Handler::VERSION = '0.153002';
use Moo::Role;
use Dancer2::Core::Types;
@@ -26,7 +26,7 @@ Dancer2::Core::Role::Handler - Role for Handlers
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 ATTRIBUTES
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::HasLocation;
# ABSTRACT: Role for application location "guessing"
-$Dancer2::Core::Role::HasLocation::VERSION = '0.151000';
+$Dancer2::Core::Role::HasLocation::VERSION = '0.153002';
use Moo::Role;
use Dancer2::Core::Types;
use Dancer2::FileUtils;
@@ -84,7 +84,7 @@ Dancer2::Core::Role::HasLocation - Role for application location "guessing"
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 AUTHOR
@@ -1,7 +1,7 @@
# ABSTRACT: Role for handling headers
package Dancer2::Core::Role::Headers;
-$Dancer2::Core::Role::Headers::VERSION = '0.151000';
+$Dancer2::Core::Role::Headers::VERSION = '0.153002';
use Moo::Role;
use Dancer2::Core::Types;
use HTTP::Headers;
@@ -77,7 +77,7 @@ Dancer2::Core::Role::Headers - Role for handling headers
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Hookable;
# ABSTRACT: Role for hookable objects
-$Dancer2::Core::Role::Hookable::VERSION = '0.151000';
+$Dancer2::Core::Role::Hookable::VERSION = '0.153002';
use Moo::Role;
use Dancer2::Core;
use Dancer2::Core::Types;
@@ -156,7 +156,7 @@ Dancer2::Core::Role::Hookable - Role for hookable objects
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Logger;
# ABSTRACT: Role for logger engines
-$Dancer2::Core::Role::Logger::VERSION = '0.151000';
+$Dancer2::Core::Role::Logger::VERSION = '0.153002';
use Dancer2::Core::Types;
use Moo::Role;
@@ -177,7 +177,7 @@ Dancer2::Core::Role::Logger - Role for logger engines
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -302,7 +302,7 @@ You can change it either in your config.yml file:
logger: "console"
The log format can also be configured,
-please see L<Dancer2::Core::Role::Logger/"logger_format"> for details.
+please see L<Dancer2::Core::Role::Logger/"log_format"> for details.
=head1 METHODS
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::Serializer;
# ABSTRACT: Role for Serializer engines
-$Dancer2::Core::Role::Serializer::VERSION = '0.151000';
+$Dancer2::Core::Role::Serializer::VERSION = '0.153002';
use Dancer2::Core::Types;
use Moo::Role;
@@ -78,7 +78,7 @@ Dancer2::Core::Role::Serializer - Role for Serializer engines
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::SessionFactory::File;
#ABSTRACT: Role for file-based session factories
-$Dancer2::Core::Role::SessionFactory::File::VERSION = '0.151000';
+$Dancer2::Core::Role::SessionFactory::File::VERSION = '0.153002';
use strict;
use warnings;
use Carp 'croak';
@@ -113,7 +113,7 @@ Dancer2::Core::Role::SessionFactory::File - Role for file-based session factorie
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::SessionFactory;
#ABSTRACT: Role for session factories
-$Dancer2::Core::Role::SessionFactory::VERSION = '0.151000';
+$Dancer2::Core::Role::SessionFactory::VERSION = '0.153002';
use strict;
use warnings;
use Carp 'croak';
@@ -254,7 +254,7 @@ Dancer2::Core::Role::SessionFactory - Role for session factories
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Role::StandardResponses;
# ABSTRACT: Role to provide commonly used responses
-$Dancer2::Core::Role::StandardResponses::VERSION = '0.151000';
+$Dancer2::Core::Role::StandardResponses::VERSION = '0.153002';
use Moo::Role;
sub response {
@@ -39,7 +39,7 @@ Dancer2::Core::Role::StandardResponses - Role to provide commonly used responses
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 METHODS
@@ -1,7 +1,7 @@
# ABSTRACT: Role for template engines
package Dancer2::Core::Role::Template;
-$Dancer2::Core::Role::Template::VERSION = '0.151000';
+$Dancer2::Core::Role::Template::VERSION = '0.153002';
use Dancer2::Core::Types;
use Dancer2::FileUtils qw'path';
use Carp 'croak';
@@ -101,9 +101,9 @@ sub render_layout {
}
sub apply_renderer {
- my ( $self, $request, $view, $tokens ) = @_;
+ my ( $self, $view, $tokens ) = @_;
$view = $self->view_pathname($view) if !ref $view;
- $tokens = $self->_prepare_tokens_options($request,$tokens);
+ $tokens = $self->_prepare_tokens_options( $tokens );
$self->execute_hook( 'engine.template.before_render', $tokens );
@@ -116,9 +116,9 @@ sub apply_renderer {
}
sub apply_layout {
- my ( $self, $request, $content, $tokens, $options ) = @_;
+ my ( $self, $content, $tokens, $options ) = @_;
- $tokens = $self->_prepare_tokens_options( $request, $tokens );
+ $tokens = $self->_prepare_tokens_options( $tokens );
# If 'layout' was given in the options hashref, use it if it's a true value,
# or don't use a layout if it was false (0, or undef); if layout wasn't
@@ -150,7 +150,7 @@ sub apply_layout {
}
sub _prepare_tokens_options {
- my ( $self, $request, $tokens ) = @_;
+ my ( $self, $tokens ) = @_;
# these are the default tokens provided for template processing
$tokens ||= {};
@@ -158,9 +158,9 @@ sub _prepare_tokens_options {
$tokens->{dancer_version} = Dancer2->VERSION;
$tokens->{settings} = $self->settings;
- $tokens->{request} = $request;
- $tokens->{params} = $request->params;
- $tokens->{vars} = $request->vars;
+ $tokens->{request} = $self->request;
+ $tokens->{params} = $self->request->params;
+ $tokens->{vars} = $self->request->vars;
$tokens->{session} = $self->session->data
if $self->has_session;
@@ -169,7 +169,7 @@ sub _prepare_tokens_options {
}
sub process {
- my ( $self, $request, $view, $tokens, $options ) = @_;
+ my ( $self, $view, $tokens, $options ) = @_;
my ( $content, $full_content );
# it's important that $tokens is not undef, so that things added to it via
@@ -181,11 +181,11 @@ sub process {
$content =
$view
- ? $self->apply_renderer( $request, $view, $tokens )
+ ? $self->apply_renderer( $view, $tokens )
: delete $options->{content};
defined $content
- and $full_content = $self->apply_layout( $request, $content, $tokens, $options );
+ and $full_content = $self->apply_layout( $content, $tokens, $options );
defined $full_content
and return $full_content;
@@ -207,7 +207,7 @@ Dancer2::Core::Role::Template - Role for template engines
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,7 +1,7 @@
# ABSTRACT: Dancer2's route handler
package Dancer2::Core::Route;
-$Dancer2::Core::Route::VERSION = '0.151000';
+$Dancer2::Core::Route::VERSION = '0.153002';
use strict;
use warnings;
@@ -228,7 +228,7 @@ Dancer2::Core::Route - Dancer2's route handler
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 ATTRIBUTES
@@ -1,6 +1,6 @@
package Dancer2::Core::Runner;
# ABSTRACT: Top-layer class to start a dancer app
-$Dancer2::Core::Runner::VERSION = '0.151000';
+$Dancer2::Core::Runner::VERSION = '0.153002';
use Moo;
use Carp 'croak';
use Dancer2::Core::MIME;
@@ -260,7 +260,7 @@ Dancer2::Core::Runner - Top-layer class to start a dancer app
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 AUTHOR
@@ -1,5 +1,5 @@
package Dancer2::Core::Session;
-$Dancer2::Core::Session::VERSION = '0.151000';
+$Dancer2::Core::Session::VERSION = '0.153002';
#ABSTRACT: class to represent any session object
use strict;
@@ -71,7 +71,7 @@ Dancer2::Core::Session - class to represent any session object
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core::Time;
#ABSTRACT: class to handle common helpers for time manipulations
-$Dancer2::Core::Time::VERSION = '0.151000';
+$Dancer2::Core::Time::VERSION = '0.153002';
use Moo;
has seconds => (
@@ -134,7 +134,7 @@ Dancer2::Core::Time - class to handle common helpers for time manipulations
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Core::Types;
# ABSTRACT: Moo types for Dancer2 core.
-$Dancer2::Core::Types::VERSION = '0.151000';
+$Dancer2::Core::Types::VERSION = '0.153002';
use strict;
use warnings;
use Scalar::Util 'blessed', 'looks_like_number';
@@ -148,7 +148,7 @@ Dancer2::Core::Types - Moo types for Dancer2 core.
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Core;
# ABSTRACT: Core libraries for Dancer2 2.0
-$Dancer2::Core::VERSION = '0.151000';
+$Dancer2::Core::VERSION = '0.153002';
use strict;
use warnings;
@@ -29,7 +29,7 @@ Dancer2::Core - Core libraries for Dancer2 2.0
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 FUNCTIONS
@@ -1,6 +1,6 @@
package Dancer2::FileUtils;
# ABSTRACT: File utility helpers
-$Dancer2::FileUtils::VERSION = '0.151000';
+$Dancer2::FileUtils::VERSION = '0.153002';
use strict;
use warnings;
@@ -101,7 +101,7 @@ Dancer2::FileUtils - File utility helpers
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Handler::AutoPage;
# ABSTRACT: Class for handling the AutoPage feature
-$Dancer2::Handler::AutoPage::VERSION = '0.151000';
+$Dancer2::Handler::AutoPage::VERSION = '0.153002';
use Moo;
use Carp 'croak';
use Dancer2::Core::Types;
@@ -40,7 +40,7 @@ sub code {
return;
}
- my $ct = $template->process( $app->request, $page );
+ my $ct = $template->process( $page );
$app->response->header( 'Content-Length', length($ct) );
return ( $app->request->method eq 'GET' ) ? $ct : '';
};
@@ -64,7 +64,7 @@ Dancer2::Handler::AutoPage - Class for handling the AutoPage feature
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Handler::File;
# ABSTRACT: class for handling file content rendering
-$Dancer2::Handler::File::VERSION = '0.151000';
+$Dancer2::Handler::File::VERSION = '0.153002';
use Carp 'croak';
use Moo;
use HTTP::Date;
@@ -147,7 +147,7 @@ Dancer2::Handler::File - class for handling file content rendering
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 AUTHOR
@@ -1,6 +1,6 @@
package Dancer2::Logger::Capture::Trap;
# ABSTRACT: a place to store captured Dancer2 logs
-$Dancer2::Logger::Capture::Trap::VERSION = '0.151000';
+$Dancer2::Logger::Capture::Trap::VERSION = '0.153002';
use Moo;
use Dancer2::Core::Types;
@@ -37,7 +37,7 @@ Dancer2::Logger::Capture::Trap - a place to store captured Dancer2 logs
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Logger::Capture;
# ABSTRACT: Capture dancer logs
-$Dancer2::Logger::Capture::VERSION = '0.151000';
+$Dancer2::Logger::Capture::VERSION = '0.153002';
use Moo;
use Dancer2::Logger::Capture::Trap;
@@ -35,7 +35,7 @@ Dancer2::Logger::Capture - Capture dancer logs
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Logger::Console;
# ABSTRACT: Console logger
-$Dancer2::Logger::Console::VERSION = '0.151000';
+$Dancer2::Logger::Console::VERSION = '0.153002';
use Moo;
with 'Dancer2::Core::Role::Logger';
@@ -24,7 +24,7 @@ Dancer2::Logger::Console - Console logger
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Logger::Diag;
# ABSTRACT: Test::More diag() logging engine for Dancer2
-$Dancer2::Logger::Diag::VERSION = '0.151000';
+$Dancer2::Logger::Diag::VERSION = '0.153002';
use Moo;
use Test::More;
@@ -26,7 +26,7 @@ Dancer2::Logger::Diag - Test::More diag() logging engine for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Logger::File;
# ABSTRACT: file-based logging engine for Dancer2
-$Dancer2::Logger::File::VERSION = '0.151000';
+$Dancer2::Logger::File::VERSION = '0.153002';
use Carp 'carp';
use Moo;
use Dancer2::Core::Types;
@@ -12,33 +12,30 @@ use Fcntl qw(:flock SEEK_END);
use Dancer2::FileUtils qw(open_file);
use IO::File;
-# FIXME: this is not a good way to do this
has environment => (
- is => 'ro',
- lazy => 1,
- default => sub { $_[0]->app->environment },
+ is => 'ro',
+ required => 1,
);
-# FIXME: this is not a good way to do this
has location => (
- is => 'ro',
- lazy => 1,
- default => sub { $_[0]->app->config_location },
+ is => 'ro',
+ required => 1,
);
has log_dir => (
is => 'rw',
- isa => Str,
- lazy => 1,
- builder => '_build_log_dir',
- trigger => sub {
- my ( $self, $dir ) = @_;
+ isa => sub {
+ my $dir = shift;
+
if ( !-d $dir && !mkdir $dir ) {
- return carp
- "Log directory \"$dir\" does not exist and unable to create it.";
+ die "log directory \"$dir\" does not exist and unable to create it.";
+ }
+ if ( !-w $dir ) {
+ die "log directory \"$dir\" is not writable."
}
- return carp "Log directory \"$dir\" is not writable." if !-w $dir;
},
+ lazy => 1,
+ builder => '_build_log_dir',
);
has file_name => (
@@ -61,7 +58,7 @@ has fh => (
builder => '_build_fh',
);
-sub _build_log_dir {File::Spec->catdir( $_[0]->location, 'logs' )}
+sub _build_log_dir { File::Spec->catdir( $_[0]->location, 'logs' ) }
sub _build_file_name {$_[0]->environment . ".log"}
@@ -114,7 +111,7 @@ Dancer2::Logger::File - file-based logging engine for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Logger::Note;
# ABSTRACT: Test::More note() logging engine for Dancer2
-$Dancer2::Logger::Note::VERSION = '0.151000';
+$Dancer2::Logger::Note::VERSION = '0.153002';
use Moo;
use Test::More;
@@ -26,7 +26,7 @@ Dancer2::Logger::Note - Test::More note() logging engine for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Logger::Null;
# ABSTRACT: Blackhole-like silent logging engine for Dancer2
-$Dancer2::Logger::Null::VERSION = '0.151000';
+$Dancer2::Logger::Null::VERSION = '0.153002';
use Moo;
with 'Dancer2::Core::Role::Logger';
@@ -20,7 +20,7 @@ Dancer2::Logger::Null - Blackhole-like silent logging engine for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Manual::Migration;
# ABSTRACT: Migrating from Dancer to Dancer2
-$Dancer2::Manual::Migration::VERSION = '0.151000';
+$Dancer2::Manual::Migration::VERSION = '0.153002';
use strict;
use warnings;
@@ -18,7 +18,7 @@ Dancer2::Manual::Migration - Migrating from Dancer to Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head2 Migration from Dancer1 to Dancer2
@@ -151,6 +151,9 @@ Other modules that could be used for testing are:
=head4 Logs
+The C<logger_format> in the Logger role (L<Dancer2::Core::Role::Logger>)
+is now C<log_format>.
+
C<read_logs> can no longer be used, as with L<Dancer2::Test>. Instead,
L<Dancer2::Logger::Capture> could be used for testing, to capture all
logs to an object.
@@ -1,6 +1,6 @@
# ABSTRACT: A gentle introduction to Dancer2
package Dancer2::Manual;
-$Dancer2::Manual::VERSION = '0.151000';
+$Dancer2::Manual::VERSION = '0.153002';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Manual - A gentle introduction to Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -885,6 +885,23 @@ Accesses the configuration of the application:
return "This is " . config->{appname};
};
+=head2 content
+
+Sets the content for the response.
+
+ get '/' => sub {
+ content 'Hello, world!';
+
+ # the return value of the route is ignored
+ return 'Ignored String';
+ };
+
+Once you set the content using the keyword, your return value (which
+is usually the content) is ignored.
+
+B<WARNING> : If you are using the C<pass> keyword, the last route will be
+in charge of setting the content.
+
=head2 content_type
Sets the B<content-type> rendered, for the current route handler:
@@ -1181,6 +1198,10 @@ route. So it's not necessary anymore to use C<return> with pass.
}
};
+B<WARNING> : You cannot set the content before passing and have it remain,
+even if you use the C<content> keyword or set it directly in the response
+object.
+
=head2 patch
Defines a route for HTTP B<PATCH> requests to the given URL:
@@ -1,7 +1,7 @@
# ABSTRACT: a plugin for adding Ajax route handlers
package Dancer2::Plugin::Ajax;
-$Dancer2::Plugin::Ajax::VERSION = '0.151000';
+$Dancer2::Plugin::Ajax::VERSION = '0.153002';
use strict;
use warnings;
@@ -63,7 +63,7 @@ Dancer2::Plugin::Ajax - a plugin for adding Ajax route handlers
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Plugin;
# ABSTRACT: Extending Dancer2's DSL with plugins
-$Dancer2::Plugin::VERSION = '0.151000';
+$Dancer2::Plugin::VERSION = '0.153002';
use Moo::Role;
use Carp 'croak', 'carp';
use Dancer2::Core::DSL;
@@ -251,7 +251,7 @@ Dancer2::Plugin - Extending Dancer2's DSL with plugins
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Plugins;
# ABSTRACT: Recommended Dancer2 plugins
-$Dancer2::Plugins::VERSION = '0.151000';
+$Dancer2::Plugins::VERSION = '0.153002';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Plugins - Recommended Dancer2 plugins
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -0,0 +1,119 @@
+package Dancer2::Policy;
+# ABSTRACT: Dancer core and community policy and standards of conduct
+$Dancer2::Policy::VERSION = '0.153002';
+use strict;
+use warnings;
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Dancer2::Policy - Dancer core and community policy and standards of conduct
+
+=head1 VERSION
+
+version 0.153002
+
+=head1 DESCRIPTION
+
+This document describes various policies (most notably, the standards
+of conduct) for the Dancer core developers and broad community.
+
+This is what we expect from our community and ourselves and these are
+the standards of behavior we set forth in order to make sure the community
+remains a safe space for all of its members, without exception.
+
+=head1 STANDARDS OF CONDUCT
+
+These standards apply anywhere the community comes together as a group.
+This includes, but is not limited to, the Dancer IRC channel, the Dancer
+mailing list, Dancer hackathons, and Dancer conferences.
+
+=over 4
+
+=item *
+
+Always be civil.
+
+=item *
+
+Heed the moderators.
+
+=item *
+
+Abuse is not tolerated.
+
+=back
+
+Civility is simple: stick to the facts while avoiding demeaning remarks and
+sarcasm. It is not enough to be factual. You must also be civil. Responding
+in kind to incivility is not acceptable.
+
+If the list moderators tell you that you are not being civil, carefully
+consider how your words have appeared before responding in any way. You may
+protest, but repeated protest in the face of a repeatedly reaffirmed decision
+is not acceptable.
+
+Unacceptable behavior will result in a public and clearly identified warning.
+Repeated unacceptable behavior will result in removal from the mailing list and
+revocation of any commit bit. The first removal is for one month. Subsequent
+removals will double in length. After six months with no warning, a user's ban
+length is reset. Removals, like warnings, are public.
+
+The list of moderators consists of all active core developers. This includes,
+in alphabetical order, Alberto Simões, David Precious, Mickey Nasriachi,
+Russell Jenkins, Sawyer X, Stefan Hornburg (Racke), Steven Humphrey, and Yanick
+Champoux.
+
+This list might additionally grow to active members of the community who have
+stepped up to help handle abusive behavior. If this should happen, this
+document would be updated to include their names.
+
+Additionally, it's important to understand the self-regulating nature we
+foster at the Dancer community. This means anyone and everyone in the
+community - in the channel, on the list, at an event - has the ability to
+call out unacceptable behavior and incivility to others in the community.
+
+Moderators are responsible for issuing warnings and take disciplinary actions,
+but anyone may - and is encouraged - to publicly make note of unacceptable
+treatment of others.
+
+As a core principle, abuse is never tolerated. One cannot berate, insult,
+debase, deride, put down, or vilify anyone, or act towards anyone in a way
+intending to hurt them.
+
+The community specifically considers as abuse any attempts to otherize anyone,
+whether by their technical skill, knowledge, gender, sexual orientation,
+or any other characteristic.
+
+The community aims to maintain a safe space for everyone, in any forum it
+has. If you ever feel this core principle has been compromised, you are strongly
+urged to contact a moderator. We are always here.
+
+Remember, this is B<your> community, as much as it is anyone else's.
+
+=head1 CREDITS
+
+This policy has been adopted and adapted from the policy available for
+the Perl language development, provided by B<p5p> (the Perl 5 Porters).
+
+The original inspiration policy document can be read at L<perlpolicy>.
+
+=head1 AUTHOR
+
+Dancer Core Developers
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2014 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
@@ -1,7 +1,7 @@
# ABSTRACT: Serializer for handling Dumper data
package Dancer2::Serializer::Dumper;
-$Dancer2::Serializer::Dumper::VERSION = '0.151000';
+$Dancer2::Serializer::Dumper::VERSION = '0.153002';
use Moo;
use Carp 'croak';
use Data::Dumper;
@@ -55,7 +55,7 @@ Dancer2::Serializer::Dumper - Serializer for handling Dumper data
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Serializer::JSON;
# ABSTRACT: Serializer for handling JSON data
-$Dancer2::Serializer::JSON::VERSION = '0.151000';
+$Dancer2::Serializer::JSON::VERSION = '0.153002';
use Moo;
use JSON ();
@@ -57,7 +57,7 @@ Dancer2::Serializer::JSON - Serializer for handling JSON data
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Serializer::Mutable;
# ABSTRACT: Serialize and deserialize content based on HTTP header
-$Dancer2::Serializer::Mutable::VERSION = '0.151000';
+$Dancer2::Serializer::Mutable::VERSION = '0.153002';
use Moo;
use Carp 'croak';
use Encode;
@@ -77,13 +77,12 @@ sub deserialize {
sub _get_content_type {
my $self = shift;
- my $headers = $self->{'extra_headers'}
- or return;
+ $self->has_request or return;
# Search for the first HTTP header variable which
# specifies supported content.
foreach my $method ( qw<content_type accept accept_type> ) {
- if ( my $value = $headers->{$method} ) {
+ if ( my $value = $self->request->header($method) ) {
if ( exists $formats->{$value} ) {
$self->set_content_type($value);
return $formats->{$value};
@@ -109,7 +108,7 @@ Dancer2::Serializer::Mutable - Serialize and deserialize content based on HTTP h
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Serializer::YAML;
# ABSTRACT: Serializer for handling YAML data
-$Dancer2::Serializer::YAML::VERSION = '0.151000';
+$Dancer2::Serializer::YAML::VERSION = '0.153002';
use Moo;
use Carp 'croak';
use Encode;
@@ -51,7 +51,7 @@ Dancer2::Serializer::YAML - Serializer for handling YAML data
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,6 +1,6 @@
package Dancer2::Session::Simple;
# ABSTRACT: in-memory session backend for Dancer2
-$Dancer2::Session::Simple::VERSION = '0.151000';
+$Dancer2::Session::Simple::VERSION = '0.153002';
use Moo;
use Dancer2::Core::Types;
use Carp;
@@ -49,7 +49,7 @@ Dancer2::Session::Simple - in-memory session backend for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,5 +1,5 @@
package Dancer2::Session::YAML;
-$Dancer2::Session::YAML::VERSION = '0.151000';
+$Dancer2::Session::YAML::VERSION = '0.153002';
# ABSTRACT: YAML-file-based session backend for Dancer2
use Moo;
@@ -39,7 +39,7 @@ Dancer2::Session::YAML - YAML-file-based session backend for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -1,5 +1,5 @@
package Dancer2::Template::Implementation::ForkedTiny;
-$Dancer2::Template::Implementation::ForkedTiny::VERSION = '0.151000';
+$Dancer2::Template::Implementation::ForkedTiny::VERSION = '0.153002';
# ABSTRACT: Dancer2 own implementation of Template::Tiny
use 5.00503;
@@ -229,7 +229,7 @@ Dancer2::Template::Implementation::ForkedTiny - Dancer2 own implementation of Te
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Template::Simple;
# ABSTRACT: Pure Perl 5 template engine for Dancer2
-$Dancer2::Template::Simple::VERSION = '0.151000';
+$Dancer2::Template::Simple::VERSION = '0.153002';
use strict;
use warnings;
use Moo;
@@ -156,7 +156,7 @@ Dancer2::Template::Simple - Pure Perl 5 template engine for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,7 +1,7 @@
# ABSTRACT: Template toolkit engine for Dancer2
package Dancer2::Template::TemplateToolkit;
-$Dancer2::Template::TemplateToolkit::VERSION = '0.151000';
+$Dancer2::Template::TemplateToolkit::VERSION = '0.153002';
use strict;
use warnings;
use Carp qw/croak/;
@@ -63,7 +63,7 @@ Dancer2::Template::TemplateToolkit - Template toolkit engine for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Template::Tiny;
# ABSTRACT: Template::Tiny engine for Dancer2
-$Dancer2::Template::Tiny::VERSION = '0.151000';
+$Dancer2::Template::Tiny::VERSION = '0.153002';
use Moo;
use Carp qw/croak/;
use Dancer2::Core::Types;
@@ -50,7 +50,7 @@ Dancer2::Template::Tiny - Template::Tiny engine for Dancer2
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -1,6 +1,6 @@
package Dancer2::Test;
# ABSTRACT: Useful routines for testing Dancer2 apps
-$Dancer2::Test::VERSION = '0.151000';
+$Dancer2::Test::VERSION = '0.153002';
use strict;
use warnings;
@@ -621,11 +621,28 @@ Dancer2::Test - Useful routines for testing Dancer2 apps
=head1 VERSION
-version 0.151000
+version 0.153002
+
+=head1 SYNOPSIS
+
+ use Test::More;
+ use Plack::Test;
+ use HTTP::Request::Common; # install separately
+
+ use YourDancerApp;
+
+ my $app = YourDancerApp->to_app;
+ my $test = Plack::Test->create($app);
+
+ my $res = $test->request( GET '/' );
+ is( $res->code, 200, '[GET /] Request successful' );
+ like( $res->content, qr/hello, world/, '[GET /] Correct content';
+
+ done_testing;
=head1 DESCRIPTION
-DEPRECATED - Please use L<Plack::Test> instead.
+B<DEPRECATED>. Please use L<Plack::Test> instead as shown in the SYNOPSIS!
This module will warn for a while until we actually remove it. This is to
provide enough time to fully remove it from your system.
@@ -1,6 +1,6 @@
package Dancer2::Tutorial;
# ABSTRACT: An example to get you dancing
-$Dancer2::Tutorial::VERSION = '0.151000';
+$Dancer2::Tutorial::VERSION = '0.153002';
__END__
=pod
@@ -13,7 +13,7 @@ Dancer2::Tutorial - An example to get you dancing
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 What is Dancer2?
@@ -1,6 +1,6 @@
package Dancer2;
# ABSTRACT: Lightweight yet powerful web application framework
-$Dancer2::VERSION = '0.151000';
+$Dancer2::VERSION = '0.153002';
use strict;
use warnings;
use List::Util 'first';
@@ -15,7 +15,7 @@ our $AUTHORITY = 'SUKRIA';
# set version in dist.ini now
# but we still need a basic version for
# the tests
-$Dancer2::VERSION ||= '0.150000'; # 2.14.3
+$Dancer2::VERSION ||= '0.153002'; # 2.153.2
our $runner;
@@ -32,7 +32,7 @@ sub import {
my @final_args;
foreach my $arg (@args) {
- grep +( $arg eq $_ ), qw<:script :syntax>
+ grep +( $arg eq $_ ), qw<:script :syntax :tests>
and next;
if ( substr( $arg, 0, 1 ) eq '!' ) {
@@ -43,7 +43,7 @@ sub import {
}
scalar @final_args % 2
- and die q{parameters must be key/value pairs, ':script' or '!keyword'};
+ and die q{parameters must be key/value pairs or '!keyword'};
my %final_args = @final_args;
@@ -118,7 +118,7 @@ Dancer2 - Lightweight yet powerful web application framework
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 DESCRIPTION
@@ -33,7 +33,7 @@ dancer2 - Dancer2 command line interface
=head1 VERSION
-version 0.151000
+version 0.153002
=head1 SYNOPSIS
@@ -68,7 +68,7 @@ do { my $x = {
'MooX::Types::MooseLike' => '0.16',
'MooX::Types::MooseLike::Base' => '0',
'POSIX' => '0',
- 'Plack' => '1.0016',
+ 'Plack' => '1.0029',
'Plack::Builder' => '0',
'Pod::Simple::Search' => '0',
'Pod::Simple::SimpleTree' => '0',
@@ -112,6 +112,7 @@ do { my $x = {
'IO::Handle' => '0',
'IPC::Open3' => '0',
'LWP::Protocol::PSGI' => '0.06',
+ 'Plack::Response' => '0',
'Plack::Test' => '0',
'Test::Fatal' => '0',
'Test::Memory::Cycle' => '1.04',
@@ -67,6 +67,7 @@ my @files = (
'lib/Dancer2/Plugin.pm',
'lib/Dancer2/Plugin/Ajax.pm',
'lib/Dancer2/Plugins.pod',
+ 'lib/Dancer2/Policy.pod',
'lib/Dancer2/Serializer/Dumper.pm',
'lib/Dancer2/Serializer/JSON.pm',
'lib/Dancer2/Serializer/Mutable.pm',
@@ -97,8 +98,25 @@ my @files = (
't/auto_page.t',
't/caller.t',
't/charset_server.t',
+ 't/classes/Dancer2-Core-Factory/create.t',
+ 't/classes/Dancer2-Core-Hook/base.t',
+ 't/classes/Dancer2-Core-Response/new_from.t',
+ 't/classes/Dancer2-Core-Role-Engine/base.t',
+ 't/classes/Dancer2-Core-Role-Handler/base.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/base.t',
+ 't/classes/Dancer2-Core-Role-Headers/with.t',
+ 't/classes/Dancer2-Core-Role-StandardResponses/base.t',
+ 't/classes/Dancer2-Core-Runner/base.t',
+ 't/classes/Dancer2-Core-Runner/environment.t',
+ 't/classes/Dancer2-Core-Runner/psgi_app.t',
+ 't/classes/Dancer2-Core/camelize.t',
+ 't/classes/Dancer2/import.t',
't/config.yml',
't/config/config.yml',
't/config/environments/failure.yml',
@@ -121,6 +139,7 @@ my @files = (
't/deserialize.t',
't/dispatcher.t',
't/dsl.t',
+ 't/dsl/content.t',
't/dsl/extend.t',
't/dsl/extend_config/config.yml',
't/dsl/halt.t',
@@ -138,6 +157,9 @@ my @files = (
't/hooks.t',
't/http_methods.t',
't/http_status.t',
+ 't/issues/gh-634.t',
+ 't/issues/gh-723.t',
+ 't/issues/gh-730.t',
't/lib/App1.pm',
't/lib/App2.pm',
't/lib/DancerPlugin.pm',
@@ -153,7 +175,6 @@ my @files = (
't/log_die_before_hook.t',
't/log_levels.t',
't/logger.t',
- 't/logger/file.t',
't/logger_console.t',
't/lwp-protocol-psgi.t',
't/memory_cycles.t',
@@ -174,7 +195,6 @@ my @files = (
't/request_params.t',
't/request_upload.t',
't/response.t',
- 't/roles/headers.t',
't/roles/hook.t',
't/route-pod-coverage/route-pod-coverage.t',
't/route.t',
@@ -187,10 +207,50 @@ my @files = (
'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/VBzn5-yKiV0ZEaZqEtEvK_pmMT8n4QQx.yml',
+ 't/sessions/VD8wIQAAIErosiPuPzgc7Feo60_y7s2K.yml',
+ 't/sessions/VD8xFwAAIfVHBp2nUIRlhPrHBxZFewkg.yml',
+ 't/sessions/VD8xPwAAIqUQa3U0CK_Q43bf7JSaXj68.yml',
't/sessions/VDKr30YvCd7R3WEniUv5Re5999E6SJmQ.yml',
+ 't/sessions/VDf4nIP4n0A4Ya5vcE7SaaDntyVZj9oB.yml',
+ 't/sessions/VDfsgXhalKhiOdSVDEk4iwyf_j3JJ1lU.yml',
+ 't/sessions/VDgFcPJynjsERU0GCt8fE9hhT-R3ErKV.yml',
+ 't/sessions/VDgH-lQYfi_XUNztQLT-6ebJ_gzwGZKp.yml',
+ 't/sessions/VDgHth9A4cXrh0fLlBodXUMnCXkcPlOO.yml',
+ 't/sessions/VDsBvbCel9L5vqAA8X12v_IKYwpqtEIb.yml',
+ 't/sessions/VDsC67174msADj1P2kEtWWWWqenpf_Gh.yml',
+ 't/sessions/VDsdec7YkN_t5HYgYTY4UTO0rGbd3quL.yml',
+ 't/sessions/VDskH-mTqVSrtI7vn3Cfjc22M3sDZ4nf.yml',
+ 't/sessions/VDxpkwmXPxXgntfDkSbIJIW3-ZmOV6F2.yml',
+ 't/sessions/VDxr8vlFwjuihF5Oq6qfdcX_C-sqJFst.yml',
+ 't/sessions/VDxsUBz1JAMQos-edO9ShtnKnIqjRugy.yml',
+ 't/sessions/VDxszUJNZJrCm2146wLcBL4Tauj5tlx3.yml',
+ 't/sessions/VDxtWd3557qlVPhU5y4QeEnoTzopT4XL.yml',
+ 't/sessions/VDxuf7UcBT5V58xfDyZ2akeLCE0stVRe.yml',
+ 't/sessions/VE1LtAAAI1ug7lcj3FDxEJY_qRPhfoA1.yml',
+ 't/sessions/VE1kdAAAROjzAe8ZtNQUKGC4lxSPjTdr.yml',
+ 't/sessions/VE1o4wAAS5VfIRWDZD6mSTy-ytif0XA-.yml',
+ 't/sessions/VE1tnAAAUNnRsHJYuMwKK9g-F4v26HBh.yml',
+ 't/sessions/VE27BgAAHJqJxusuS6yVI_5EYRhjTQbw.yml',
+ 't/sessions/VE27agAAHXnzZhVBaOsvWl1uOsOcnvfT.yml',
+ 't/sessions/VE2OEAAAXUMpJr0fKv_R132CQL6llNO6.yml',
+ 't/sessions/VE2VaAAAZacndokHehKRMngyv8UNxKT6.yml',
+ 't/sessions/VE2XCwAAZ9ygkhxx0mE_K_zWzXOmEhxE.yml',
+ 't/sessions/VE2YUAAAarbI4Jc7p_1EsANQn3BiZ7Ac.yml',
+ 't/sessions/VE2YygAAa2BSyhqX_xSUyxT98h-go-pc.yml',
+ 't/sessions/VE2ZKgAAbLz495eORolB6FjskBnNB9ap.yml',
+ 't/sessions/VE2ZjwAAbbYAr6pxPtFGzvqacCdwMll6.yml',
+ 't/sessions/VE2e9QAAc2wGVnxW-a8HhiC98g7YEx3g.yml',
+ 't/sessions/VE2enQAAcsZVTzEKdLzR9CDcSky4ZqUI.yml',
+ 't/sessions/VE2fRwAAdAiI1T-NFBekMmSKBrwpHDUK.yml',
+ 't/sessions/VE2gEAAAdOWFQRoXFFphEDM1iwFguvo-.yml',
+ 't/sessions/VE2gXgAAdircA43YYaJojXFPnqLvT9M5.yml',
+ 't/sessions/VE2grAAAdvaf8h_9-67vWmqukDEjs7vb.yml',
+ 't/sessions/VE4s2AAAN-mIHpV45UJy67IvQVuZVeoG.yml',
+ 't/sessions/VEcEMgAADIiqAdXb4PP-YxIqDskws7Qd.yml',
't/shared_engines.t',
't/splat.t',
't/template.t',
@@ -239,6 +299,7 @@ my @files = (
'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'
);
@@ -0,0 +1,265 @@
+#!perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 32;
+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<three items requested>) },
+ 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<get post> );
+}
+
+{
+ 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},
+ '==',
+ 11,
+ '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::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 NoStrictNoWarningsNoUTF8;
+ 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;';
+}
+
+{
+ 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;';
+}
+
@@ -0,0 +1,24 @@
+#!/usr/bin/perl
+use 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",
+ );
+}
+
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::More tests => 4;
+use 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' );
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::More tests => 11;
+use Test::Fatal;
+use 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<name code> );
+
+ 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',
+ );
+}
@@ -0,0 +1,80 @@
+#!perl
+
+use 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<new_from_array new_from_plack> );
+
+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,
+ {
+ 'Server' => "Perl Dancer2 $Dancer2::VERSION",
+ %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,
+ {
+ 'Server' => "Perl Dancer2 $Dancer2::VERSION",
+ %default_headers,
+ },
+ 'All headers correct',
+ );
+};
+
@@ -0,0 +1,22 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::More tests => 4;
+
+{
+ package App;
+ use Moo;
+ with 'Dancer2::Core::Role::Engine';
+ sub supported_hooks {}
+}
+
+my $app = App->new;
+isa_ok( $app, 'App' );
+can_ok( $app, qw<session config> ); # attributes
+can_ok( $app, qw<set_session clear_session has_session> ); # methods
+ok(
+ $app->DOES('Dancer2::Core::Role::Hookable'),
+ 'App consumes Dancer2::Core::Role::Hookable',
+);
+
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+use 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<app> ); # attributes
+ok(
+ $handler->DOES('Dancer2::Core::Role::Handler'),
+ 'Handler consumes Dancer2::Core::Role::Handler',
+);
+
diff --git a/var/tmp/source/XSAWYERX/Dancer2-0.153002/Dancer2-0.153002/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/bin/.exists b/var/tmp/source/XSAWYERX/Dancer2-0.153002/Dancer2-0.153002/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/bin/.exists
new file mode 100644
index 00000000..e69de29b
diff --git a/var/tmp/source/XSAWYERX/Dancer2-0.153002/Dancer2-0.153002/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/inner/dir/.exists b/var/tmp/source/XSAWYERX/Dancer2-0.153002/Dancer2-0.153002/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerDir/lib/fake/inner/dir/.exists
new file mode 100644
index 00000000..e69de29b
diff --git a/var/tmp/source/XSAWYERX/Dancer2-0.153002/Dancer2-0.153002/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/.dancer b/var/tmp/source/XSAWYERX/Dancer2-0.153002/Dancer2-0.153002/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/.dancer
new file mode 100644
index 00000000..e69de29b
diff --git a/var/tmp/source/XSAWYERX/Dancer2-0.153002/Dancer2-0.153002/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/fakescript.pl b/var/tmp/source/XSAWYERX/Dancer2-0.153002/Dancer2-0.153002/t/classes/Dancer2-Core-Role-HasLocation/FakeDancerFile/fakescript.pl
new file mode 100644
index 00000000..e69de29b
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+use 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<caller location> ); # attributes
+ can_ok( $app, '_build_location' ); # methods
+
+ ok(
+ $app->DOES('Dancer2::Core::Role::HasLocation'),
+ 'App consumes Dancer2::Core::Role::HasLocation',
+ );
+
+ like(
+ $app->caller,
+ qr{^t[\\/]classes[\\/]Dancer2-Core-Role-HasLocation[\\/]base\.t$},
+ 'Default caller',
+ );
+}
+
+my $basedir = dirname( File::Spec->rel2abs(__FILE__) );
+
+note 'With lib/ and bin/:'; {
+ my $app = App->new(
+ caller => File::Spec->catfile(
+ $basedir, qw<FakeDancerDir fake inner dir fakescript.pl>
+ )
+ );
+
+ isa_ok( $app, 'App' );
+
+ my $location = $app->location;
+ $location =~ s/\Q$basedir\E//;
+
+ like(
+ $location,
+ qr{^[\\/]FakeDancerDir[\\/]$},
+ 'Got correct location with lib/ and bin/',
+ );
+}
+
+note 'With .dancer file:'; {
+ my $app = App->new(
+ caller => File::Spec->catfile(
+ $basedir, qw<FakeDancerFile script.pl>
+ )
+ );
+
+ isa_ok( $app, 'App' );
+
+ my $location = $app->location;
+ $location =~ s/\Q$basedir\E//;
+
+ like(
+ $location,
+ qr{^[\\/]FakeDancerFile$},
+ 'Got correct location with .dancer file',
+ );
+}
+
+note 'blib/ ignored:'; {
+ my $app = App->new(
+ caller => File::Spec->catfile(
+ $basedir, qw<FakeDancerDir blib lib fakescript.pl>
+ )
+ );
+
+ isa_ok( $app, 'App' );
+
+ my $location = $app->location;
+ $location =~ s/\Q$basedir\E//;
+
+ like(
+ $location,
+ qr{^[\\/]FakeDancerDir[\\/]$},
+ 'blib/ dir is ignored',
+ );
+}
@@ -0,0 +1,98 @@
+#!perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 6;
+
+{
+ package Object;
+ use Moo;
+ with 'Dancer2::Core::Role::Headers';
+}
+
+subtest 'Default' => sub {
+ plan tests => 4;
+
+ my $object = Object->new();
+ isa_ok( $object, 'Object' );
+ can_ok( $object, qw<headers header push_header headers_to_array> );
+ ok( $object->DOES('Dancer2::Core::Role::Headers'), 'Does role' );
+ isa_ok( $object->headers, 'HTTP::Headers' );
+};
+
+subtest 'Set headers with object' => sub {
+ plan tests => 4;
+
+ my $headers = HTTP::Headers->new();
+ isa_ok( $headers, 'HTTP::Headers' );
+
+ $headers->header( 'Host' => 'Foo' );
+
+ my $object = Object->new( headers => $headers );
+ isa_ok( $object, 'Object' );
+ isa_ok( $object->headers, 'HTTP::Headers', 'headers' );
+ is( $object->header('Host'), 'Foo', 'Set headers correctly' );
+};
+
+subtest 'Set headers with array' => sub {
+ plan tests => 2;
+
+ my $object = Object->new(
+ headers => [ 'Host' => 'Foo' ]
+ );
+
+ isa_ok( $object->headers, 'HTTP::Headers', 'headers' );
+ is( $object->header('Host'), 'Foo', 'Set headers correctly' );
+};
+
+subtest 'Change headers' => sub {
+ plan tests => 4;
+
+ my $object = Object->new();
+ $object->header( 'Host' => 'Foo' );
+ is( $object->header('Host'), 'Foo', 'Add header correctly' );
+ is( $object->headers->header('Host'), 'Foo', 'Add header correctly' );
+
+ $object->header( 'Host' => 'Bar' );
+ is( $object->header('Host'), 'Bar', 'Change header correctly' );
+ is( $object->headers->header('Host'), 'Bar', 'Changeheader correctly' );
+};
+
+subtest 'Add multiple headers' => sub {
+ plan tests => 1;
+
+ my $object = Object->new();
+ $object->push_header( 'X-Foo' => 'Bar' );
+ $object->push_header( 'X-Foo' => 'Baz' );
+
+ my @values = $object->header('X-Foo');
+ is_deeply( \@values, [ 'Bar', 'Baz' ], 'Successfully adding many headers' );
+};
+
+subtest 'headers_to_array' => sub {
+ plan tests => 1;
+
+ my $object = Object->new(
+ headers => [
+ 'Host' => 'Foo',
+ 'Content-Type' => 'text/plain',
+ 'X-Multi' => 'Bar',
+ ]
+ );
+
+ $object->push_header( 'X-Multi' => 'Baz' );
+
+ my $headers = $object->headers_to_array;
+ is_deeply(
+ $headers,
+ [
+ 'Host' => 'Foo',
+ 'Content-Type' => 'text/plain',
+ 'X-Multi' => 'Bar',
+ 'X-Multi' => 'Baz',
+ ],
+ 'Correctly created an array from headers',
+ );
+};
+
@@ -0,0 +1,171 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::More tests => 36;
+
+{
+ 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;
+ 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<bar baz>;
+ },
+ );
+
+ isa_ok( $response, 'Response' );
+
+ is_deeply(
+ [ $response->status('calling status') ],
+ [ 'foo' ],
+ 'status() works',
+ );
+
+ is_deeply(
+ [ $response->header('calling header') ],
+ [ qw<bar baz> ],
+ 'header() works',
+ );
+}
+
+my $handler = Handler->new;
+isa_ok( $handler, 'Handler' );
+can_ok( $handler, qw<response response_400 response_403 response_404> );
+
+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 '->response_400'; {
+ # 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_400($app),
+ 'Bad Request',
+ 'Correct response 400 created',
+ );
+}
+
+note '->response_403'; {
+ # set up status and header
+ my $app = App->new(
+ response => Response->new(
+ status => sub {
+ my ( $self, $code ) = @_;
+ ::isa_ok( $self, 'Response' );
+ ::is( $code, '403', '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_403($app),
+ 'Unauthorized',
+ 'Correct response 403 created',
+ );
+}
+
+note '->response_404'; {
+ # set up status and header
+ my $app = App->new(
+ response => Response->new(
+ status => sub {
+ my ( $self, $code ) = @_;
+ ::isa_ok( $self, 'Response' );
+ ::is( $code, '404', '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_404($app),
+ 'Not Found',
+ 'Correct response 404 created',
+ );
+}
@@ -0,0 +1,246 @@
+use strict;
+use warnings;
+use Test::More tests => 40;
+use 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<server _build_server run> );
+
+ my $server = $runner->server;
+ isa_ok( $server, 'HTTP::Server::PSGI' );
+ can_ok( $server, 'run' );
+ foreach my $attr ( qw<host port timeout> ) {
+ 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->{'server_tokens'},
+ 1,
+ 'Default server_tokens',
+ );
+}
+
+{
+ local $ENV{DANCER_SERVER_TOKENS} = 0;
+ my $runner = Dancer2::Core::Runner->new();
+ is(
+ $runner->config->{'server_tokens'},
+ 0,
+ 'Successfully set server_tokens using DANCER_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',
+ );
+}
+
+note 'Warnings';
+{
+ my $runner = Dancer2::Core::Runner->new();
+ is(
+ $runner->config->{'warnings'},
+ 0,
+ 'Default warnings',
+ );
+}
+
+{
+ local $ENV{DANCER_WARNINGS} = 1;
+ my $runner = Dancer2::Core::Runner->new();
+ is(
+ $runner->config->{'warnings'},
+ 1,
+ 'Successfully set warnings using DANCER_WARNINGS',
+ );
+}
+
+{
+ {
+ 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<register_application add_postponed_hooks> );
+
+ 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<start start_server> );
+
+ $runner->config->{'apphandler'} = 'PSGI';
+ 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' );
+}
+
@@ -0,0 +1,38 @@
+use 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',
+ );
+}
+
@@ -0,0 +1,92 @@
+#!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 );
+ };
+}
+
@@ -0,0 +1,77 @@
+#!perl
+
+use strict;
+use warnings;
+use Test::More tests => 9;
+use Plack::Test;
+use HTTP::Request::Common;
+
+{
+ package App::SetContent;
+ use Dancer2;
+ get '/' => sub {
+ content 'OK';
+
+ 'Not OK';
+ };
+}
+
+{
+ package App::PassSuccess;
+ use Dancer2;
+
+ get '/' => sub {
+ content 'Missing';
+ pass;
+ };
+
+ get '/' => sub {
+ 'There';
+ };
+}
+
+{
+ package App::PassFail;
+ use Dancer2;
+
+ get '/' => sub {
+ content 'Missing';
+ pass;
+ };
+
+ get '/' => sub {};
+}
+
+{
+ my $app = App::SetContent->to_app;
+ isa_ok( $app, 'CODE' );
+
+ my $test = Plack::Test->create($app);
+ my $res = $test->request( GET '/' );
+
+ is( $res->code, 200, 'Reached route' );
+ is( $res->content, 'OK', 'Correct content' );
+}
+
+{
+ my $app = App::PassSuccess->to_app;
+ isa_ok( $app, 'CODE' );
+
+ my $test = Plack::Test->create($app);
+ my $res = $test->request( GET '/' );
+
+ is( $res->code, 200, 'Reached route' );
+ is( $res->content, 'There', 'Correct content' );
+}
+
+{
+ my $app = App::PassFail->to_app;
+ isa_ok( $app, 'CODE' );
+
+ my $test = Plack::Test->create($app);
+ my $res = $test->request( GET '/' );
+
+ is( $res->code, 200, 'Reached route' );
+ is( $res->content, '', 'Correct content' );
+}
+
@@ -0,0 +1,120 @@
+use 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',
+ );
+};
+
@@ -0,0 +1,57 @@
+#!perl
+
+use 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' );
+};
+
@@ -0,0 +1,72 @@
+#!perl
+
+use 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' );
+};
+
@@ -1,10 +0,0 @@
-#!#!/usr/bin/perl
-use strict;
-use warnings;
-
-use Test::More tests => 2;
-use Dancer2::Logger::File;
-
-my $logger = Dancer2::Logger::File->new();
-isa_ok( $logger, 'Dancer2::Logger::File' );
-can_ok( $logger, qw<environment location log_dir file_name log_file fh> );
@@ -1,26 +0,0 @@
-
-use strict;
-use warnings;
-use Test::More;
-
-{
-
- package Foo;
- use Moo;
- with 'Dancer2::Core::Role::Headers';
-}
-
-my $f = Foo->new( headers => [ 'X-Foo' => 42, 'X-Bar' => 43 ] );
-is $f->header('x-foo'), 42, "header can be read with lowercase";
-is $f->header('X-Foo'), 42, "header can be read with original name";
-
-$f->header( 'x-baz' => 44 );
-is $f->header('x-baz'), 44, "new header is created";
-
-$f->header( 'X-Foo' => 777 );
-is $f->header('X-Foo'), 777, "existing header is replaced";
-
-$f->push_header( 'X-Foo' => 888 );
-is $f->header('X-Foo'), '777, 888', "push_header appends a value";
-
-done_testing;
@@ -87,7 +87,7 @@ sub get_app_for_engine {
hook 'engine.session.after_retrieve' => sub {
my ($response) = @_;
is ref($response), 'Dancer2::Core::Session',
- 'Correct response type returned in before_retrieve';
+ 'Correct response type returned in after_retrieve';
};
#this returns dancer app. We'll register it with LWP::Protocol::PSGI
dance;
@@ -120,6 +120,16 @@ foreach my $engine (@engines) {
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 $r = $ua->get("http://localhost:3000/file.txt");
+
+ # 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";
+ };
+
$r = $ua->get("http://localhost:3000/get_session");
is $r->content, "ok", "get_session ran ok";
@@ -0,0 +1,79 @@
+use strict;
+use warnings;
+use Test::More;
+
+use YAML;
+use Test::TCP 1.13;
+use File::Temp 0.22;
+use LWP::UserAgent;
+use HTTP::Date qw/str2time/;
+use File::Spec;
+
+my $tempdir = File::Temp::tempdir( CLEANUP => 1, TMPDIR => 1 );
+
+Test::TCP::test_tcp(
+ client => sub {
+ my $port = shift;
+
+ my $ua = LWP::UserAgent->new;
+ $ua->cookie_jar( { file => "$tempdir/.cookies.txt" } );
+
+ my $res = $ua->get("http://127.0.0.1:$port/");
+ ok $res->is_success;
+ is $res->content, "session.name \n";
+
+ $res = $ua->get("http://127.0.0.1:$port/set_session/test_name");
+ ok $res->is_success;
+ is $res->content, "session.name test_name\n";
+
+ $res = $ua->get("http://127.0.0.1:$port/destroy_session");
+ ok $res->is_success;
+ is $res->content, "session.name \n";
+
+ File::Temp::cleanup();
+ },
+ server => sub {
+ my $port = shift;
+
+ 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 appdir => $tempdir;
+ setting(
+ engines => {
+ session => { 'Simple' => { session_dir => 't/sessions' } }
+ }
+ );
+ setting( session => 'Simple' );
+
+ set(show_errors => 1,
+ startup_info => 0,
+ environment => 'production',
+ port => $port
+ );
+
+ # we're overiding a RO attribute only for this test!
+ Dancer2->runner->{'port'} = $port;
+ start;
+ },
+);
+done_testing;
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1,2 @@
+---
+name: damian
@@ -0,0 +1 @@
+session.name [% session.name %]