├── clients
├── go
│ ├── .gitignore
│ ├── Procfile
│ ├── manifest.yml
│ └── main.go
├── ruby
│ ├── ruby-rails
│ │ ├── log
│ │ │ └── .keep
│ │ ├── tmp
│ │ │ └── .keep
│ │ ├── lib
│ │ │ └── tasks
│ │ │ │ └── .keep
│ │ ├── test
│ │ │ ├── fixtures
│ │ │ │ ├── .keep
│ │ │ │ └── files
│ │ │ │ │ └── .keep
│ │ │ ├── mailers
│ │ │ │ └── .keep
│ │ │ ├── models
│ │ │ │ └── .keep
│ │ │ ├── controllers
│ │ │ │ └── .keep
│ │ │ ├── integration
│ │ │ │ └── .keep
│ │ │ └── test_helper.rb
│ │ ├── app
│ │ │ ├── models
│ │ │ │ ├── concerns
│ │ │ │ │ └── .keep
│ │ │ │ └── application_record.rb
│ │ │ ├── controllers
│ │ │ │ ├── concerns
│ │ │ │ │ └── .keep
│ │ │ │ ├── application_controller.rb
│ │ │ │ └── feedback_controller.rb
│ │ │ ├── views
│ │ │ │ └── layouts
│ │ │ │ │ ├── mailer.text.erb
│ │ │ │ │ └── mailer.html.erb
│ │ │ ├── jobs
│ │ │ │ └── application_job.rb
│ │ │ ├── channels
│ │ │ │ └── application_cable
│ │ │ │ │ ├── channel.rb
│ │ │ │ │ └── connection.rb
│ │ │ └── mailers
│ │ │ │ └── application_mailer.rb
│ │ ├── config
│ │ │ ├── boot.rb
│ │ │ ├── spring.rb
│ │ │ ├── environment.rb
│ │ │ ├── cable.yml
│ │ │ ├── initializers
│ │ │ │ ├── mime_types.rb
│ │ │ │ ├── application_controller_renderer.rb
│ │ │ │ ├── filter_parameter_logging.rb
│ │ │ │ ├── backtrace_silencers.rb
│ │ │ │ ├── wrap_parameters.rb
│ │ │ │ ├── cors.rb
│ │ │ │ ├── inflections.rb
│ │ │ │ └── new_framework_defaults.rb
│ │ │ ├── routes.rb
│ │ │ ├── database.yml
│ │ │ ├── locales
│ │ │ │ └── en.yml
│ │ │ ├── secrets.yml
│ │ │ ├── application.rb
│ │ │ └── environments
│ │ │ │ ├── development.rb
│ │ │ │ └── test.rb
│ │ ├── config.ru
│ │ ├── public
│ │ │ └── robots.txt
│ │ ├── Rakefile
│ │ ├── README.md
│ │ ├── db
│ │ │ └── seeds.rb
│ │ ├── .gitignore
│ │ └── Gemfile
│ └── sinatra
│ │ ├── Rakefile
│ │ ├── README.md
│ │ ├── lib
│ │ └── extreme-carpaccio.rb
│ │ └── tests
│ │ └── test_exterme-carpaccio.rb
├── racket
│ ├── .gitignore
│ ├── carpaccio.rkt
│ └── README.md
├── java
│ ├── java-spark
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── src
│ │ │ └── main
│ │ │ │ └── java
│ │ │ │ └── extremecarpaccio
│ │ │ │ ├── JsonResponseTransformer.java
│ │ │ │ └── Strings.java
│ │ └── pom.xml
│ ├── java-fluent-http
│ │ ├── .gitignore
│ │ ├── src
│ │ │ ├── main
│ │ │ │ └── java
│ │ │ │ │ └── xcarpaccio
│ │ │ │ │ ├── Answer.java
│ │ │ │ │ ├── Logger.java
│ │ │ │ │ ├── MyFluentHttpServer.java
│ │ │ │ │ ├── Message.java
│ │ │ │ │ ├── Order.java
│ │ │ │ │ └── WebConfiguration.java
│ │ │ └── test
│ │ │ │ └── java
│ │ │ │ └── xcarpaccio
│ │ │ │ └── MyFluentHttpServerTest.java
│ │ ├── README.md
│ │ └── pom.xml
│ ├── java-springboot
│ │ └── src
│ │ │ ├── main
│ │ │ ├── resources
│ │ │ │ └── application.properties
│ │ │ └── java
│ │ │ │ └── xcarpaccio
│ │ │ │ ├── Amount.java
│ │ │ │ ├── CarpaccioApplication.java
│ │ │ │ ├── FeedbackMessage.java
│ │ │ │ ├── Order.java
│ │ │ │ └── WebController.java
│ │ │ └── test
│ │ │ └── java
│ │ │ └── xcarpaccio
│ │ │ ├── WebControllerBusinessTest.java
│ │ │ ├── WebControllerMockedServerTest.java
│ │ │ └── WebControllerServerTest.java
│ └── java-httpserver
│ │ ├── manifest.yml
│ │ ├── src
│ │ ├── main
│ │ │ └── java
│ │ │ │ └── xcarpaccio
│ │ │ │ ├── Result.java
│ │ │ │ ├── StringUtils.java
│ │ │ │ ├── Logger.java
│ │ │ │ ├── Order.java
│ │ │ │ └── FeedbackMessage.java
│ │ └── test
│ │ │ └── java
│ │ │ └── xcarpaccio
│ │ │ ├── AbstractHttpServerTest.java
│ │ │ └── MyHttpServerTest.java
│ │ ├── README.md
│ │ └── .gitignore
├── javascript
│ ├── node-plain
│ │ ├── .gitignore
│ │ ├── conf.js
│ │ ├── main.js
│ │ ├── README.md
│ │ ├── lib
│ │ │ └── logic.js
│ │ ├── package.json
│ │ └── specs
│ │ │ └── server_spec.js
│ └── express
│ │ ├── lib
│ │ ├── process.js
│ │ └── routes.js
│ │ ├── test
│ │ ├── 200-process-order.js
│ │ └── 000-server-start.js
│ │ ├── README.md
│ │ ├── package.json
│ │ └── server.js
├── php
│ ├── silex
│ │ ├── .gitignore
│ │ ├── web
│ │ │ └── app.php
│ │ ├── src
│ │ │ └── ExtremeCarpaccio
│ │ │ │ └── Model
│ │ │ │ └── Order.php
│ │ ├── tests
│ │ │ ├── units
│ │ │ │ ├── Test.php
│ │ │ │ └── src
│ │ │ │ │ └── ExtremeCarpaccio
│ │ │ │ │ └── Model
│ │ │ │ │ ├── OrderProduct.php
│ │ │ │ │ └── Order.php
│ │ │ └── functionals
│ │ │ │ └── features
│ │ │ │ ├── Ping.feature
│ │ │ │ ├── bootstrap
│ │ │ │ └── ExtremeCarpaccio
│ │ │ │ │ ├── FeatureContext.php
│ │ │ │ │ ├── ApiContext.php
│ │ │ │ │ └── ApiContext
│ │ │ │ │ └── PingContext.php
│ │ │ │ └── Order.feature
│ │ ├── README.md
│ │ ├── docker
│ │ │ ├── php
│ │ │ │ └── Dockerfile
│ │ │ └── nginx
│ │ │ │ └── site.conf
│ │ ├── docker-compose.yml
│ │ ├── .bootstrap.atoum.php
│ │ ├── behat.yml
│ │ ├── composer.json
│ │ └── Makefile
│ ├── native
│ │ ├── .gitignore
│ │ ├── tests
│ │ │ ├── functionals
│ │ │ │ └── casperjs
│ │ │ │ │ ├── 01-index.js
│ │ │ │ │ ├── 02-ping.js
│ │ │ │ │ ├── 04-feedback.js
│ │ │ │ │ └── 03-order.js
│ │ │ └── units
│ │ │ │ ├── Test.php
│ │ │ │ └── src
│ │ │ │ └── ExtremeCarpaccio
│ │ │ │ └── Model
│ │ │ │ ├── OrderProduct.php
│ │ │ │ └── Order.php
│ │ ├── src
│ │ │ └── ExtremeCarpaccio
│ │ │ │ └── Model
│ │ │ │ └── Order.php
│ │ ├── docker
│ │ │ ├── php
│ │ │ │ └── Dockerfile
│ │ │ └── nginx
│ │ │ │ └── site.conf
│ │ ├── web
│ │ │ └── app.php
│ │ ├── docker-compose.yml
│ │ ├── composer.json
│ │ ├── README.md
│ │ ├── .bootstrap.atoum.php
│ │ └── Makefile
│ └── socket
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── src
│ │ ├── OutputInterface.php
│ │ ├── ResponseInterface.php
│ │ ├── FeedbackMapperInterface.php
│ │ ├── Console.php
│ │ ├── Result.php
│ │ ├── Order.php
│ │ ├── ReaderInterface.php
│ │ ├── FeedbackMessage.php
│ │ ├── JsonFeedbackMapper.php
│ │ ├── Starter.php
│ │ ├── Response.php
│ │ ├── Server.php
│ │ └── Reader.php
│ │ ├── composer.json
│ │ └── tests
│ │ ├── TestOrder.php
│ │ └── TestJsonFeedbackMapper.php
├── scala
│ ├── .gitignore
│ ├── project
│ │ ├── build.properties
│ │ └── Dependencies.scala
│ ├── README.md
│ ├── build.sbt
│ └── src
│ │ └── main
│ │ └── scala
│ │ └── main
│ │ └── Server.scala
├── clojure
│ ├── .gitignore
│ ├── src
│ │ ├── user.clj
│ │ └── extremecarpaccio
│ │ │ └── core.clj
│ ├── test
│ │ └── extremecarpaccio
│ │ │ └── core_test.clj
│ ├── project.clj
│ └── README.md
├── c#
│ ├── dnx-csharp
│ │ ├── watch-web.sh
│ │ ├── watch-tests.sh
│ │ ├── global.json
│ │ ├── NuGet.config
│ │ ├── src
│ │ │ └── xcarpaccio
│ │ │ │ ├── models.cs
│ │ │ │ ├── startup.cs
│ │ │ │ ├── app.cs
│ │ │ │ ├── project.json
│ │ │ │ └── modules.cs
│ │ ├── test
│ │ │ └── xcarpaccio.tests
│ │ │ │ ├── tests.cs
│ │ │ │ └── project.json
│ │ ├── build.sh
│ │ └── .vscode
│ │ │ ├── tasks.json
│ │ │ └── launch.json
│ ├── coreWebApi
│ │ ├── src
│ │ │ └── xcarpaccio
│ │ │ │ ├── Models
│ │ │ │ ├── Order.cs
│ │ │ │ └── Feedback.cs
│ │ │ │ ├── appsettings.json
│ │ │ │ ├── Controllers
│ │ │ │ ├── Home.cs
│ │ │ │ ├── OrderController.cs
│ │ │ │ └── FeedbackController.cs
│ │ │ │ ├── web.config
│ │ │ │ ├── Program.cs
│ │ │ │ ├── RequestLoggerMiddleware.cs
│ │ │ │ ├── project.json
│ │ │ │ └── Startup.cs
│ │ ├── global.json
│ │ ├── readme.md
│ │ ├── Dockerfile
│ │ ├── NuGet.config
│ │ ├── test
│ │ │ └── xcarpaccio.tests
│ │ │ │ ├── feedbackTest.cs
│ │ │ │ └── project.json
│ │ └── .vscode
│ │ │ ├── tasks.json
│ │ │ └── launch.json
│ └── nancy
│ │ ├── NancyApplication1
│ │ ├── Content
│ │ │ └── nancy-logo.png
│ │ ├── packages.config
│ │ ├── IndexModule.cs
│ │ ├── Bootstrapper.cs
│ │ ├── Views
│ │ │ └── index.sshtml
│ │ ├── Program.cs
│ │ └── Properties
│ │ │ └── AssemblyInfo.cs
│ │ ├── extreme-carpaccio.client
│ │ ├── Bill.cs
│ │ ├── Feedback.cs
│ │ ├── packages.config
│ │ ├── Order.cs
│ │ ├── Bootstrapper.cs
│ │ ├── Program.cs
│ │ ├── Properties
│ │ │ └── AssemblyInfo.cs
│ │ └── IndexModule.cs
│ │ ├── README.md
│ │ └── extreme-carpaccio.client.sln
├── kotlin
│ ├── settings.gradle
│ ├── src
│ │ ├── main
│ │ │ ├── resources
│ │ │ │ └── simplelogger.properties
│ │ │ └── kotlin
│ │ │ │ └── xcarpaccio
│ │ │ │ ├── Result.kt
│ │ │ │ ├── Order.kt
│ │ │ │ └── Logger.kt
│ │ └── test
│ │ │ └── resources
│ │ │ └── mockito-extensions
│ │ │ └── org.mockito.plugins.MockMaker
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── README.md
│ ├── build.gradle
│ └── .gitignore
├── haskell
│ ├── .gitignore
│ ├── tdd.sh
│ ├── test
│ │ └── Spec.hs
│ ├── src
│ │ ├── Model.hs
│ │ └── Main.hs
│ ├── README.md
│ └── carpaccio.cabal
├── erlang
│ ├── .gitignore
│ ├── rebar
│ ├── src
│ │ ├── xcarpaccio.erl
│ │ ├── xcarpaccio.app.src
│ │ └── xcarpaccio_app.erl
│ ├── rebar.config
│ ├── test
│ │ └── jsx_usage_test.erl
│ └── README.md
├── python
│ ├── flask-server
│ │ ├── __main__.py
│ │ ├── README.md
│ │ └── client
│ │ │ └── __init__.py
│ ├── simple-server
│ │ ├── __main__.py
│ │ └── README.md
│ └── simple-server-python3
│ │ ├── __main__.py
│ │ ├── client
│ │ └── __init__.pyc
│ │ └── README.md
├── f#
│ ├── carpaccio-client
│ │ ├── paket.references
│ │ ├── App.config
│ │ ├── carpaccio-model.fs
│ │ └── carpaccio-client.fs
│ ├── .gitignore
│ ├── .paket
│ │ └── paket.bootstrapper.exe
│ ├── paket.dependencies
│ ├── paket.lock
│ ├── build.cmd
│ ├── README.md
│ ├── build.sh
│ ├── build.fsx
│ └── extreme-carpaccio.sln
├── groovy
│ └── groovy-ratpack
│ │ ├── .gitignore
│ │ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ │ ├── README.md
│ │ ├── src
│ │ ├── ratpack
│ │ │ └── Ratpack.groovy
│ │ └── test
│ │ │ └── groovy
│ │ │ └── ExtremeCarpaccioSpec.groovy
│ │ └── build.gradle
├── typescript
│ ├── src
│ │ ├── calc.ts
│ │ ├── calc.spec.ts
│ │ └── server.ts
│ ├── tsconfig.json
│ └── package.json
├── d
│ ├── source
│ │ ├── models
│ │ │ ├── feedback.d
│ │ │ └── order.d
│ │ ├── utils.d
│ │ └── app.d
│ ├── dub.json
│ ├── .gitignore
│ └── README.md
└── rust
│ ├── Cargo.toml
│ └── src
│ └── main.rs
├── server
├── .bowerrc
├── manifest.yml
├── public
│ └── stylesheets
│ │ └── style.css
├── javascripts
│ ├── services
│ │ ├── index.js
│ │ ├── reduction.js
│ │ └── order.js
│ ├── utils.js
│ ├── routes.js
│ └── config.js
├── configuration.json
├── bower.json
├── .eslintrc
├── specs
│ ├── investigating_spec.js
│ ├── config_spec.js
│ └── utils_spec.js
├── package.json
├── app.js
└── bin
│ └── www
├── .travis.yml
├── .github
├── dependabot.yml
└── workflows
│ ├── on-all-prs.yml
│ └── on-prs-made-against-the-server.yml
├── .gitignore
├── LICENSE
└── README.md
/clients/go/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 |
--------------------------------------------------------------------------------
/clients/go/Procfile:
--------------------------------------------------------------------------------
1 | web: go
2 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/log/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/tmp/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/racket/.gitignore:
--------------------------------------------------------------------------------
1 | compiled
2 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/lib/tasks/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/test/fixtures/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/test/mailers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/test/models/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/java/java-spark/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/test/controllers/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/test/integration/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/app/models/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/test/fixtures/files/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/javascript/node-plain/.gitignore:
--------------------------------------------------------------------------------
1 | npm-debug.log
2 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/clients/php/silex/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 |
3 | composer.lock
4 |
--------------------------------------------------------------------------------
/clients/scala/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | target
3 | project/target
--------------------------------------------------------------------------------
/clients/scala/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version = 0.13.15
--------------------------------------------------------------------------------
/server/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "public/components"
3 | }
--------------------------------------------------------------------------------
/clients/clojure/.gitignore:
--------------------------------------------------------------------------------
1 | .lein-failures
2 | .nrepl-port
3 | target/
--------------------------------------------------------------------------------
/clients/php/native/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 |
3 | composer.lock
4 |
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | .idea
3 | *.iml
4 |
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/watch-web.sh:
--------------------------------------------------------------------------------
1 | cd test/xcarpaccio
2 | dnx-watch web
3 |
--------------------------------------------------------------------------------
/clients/kotlin/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'extreme-carpaccio'
2 |
3 |
--------------------------------------------------------------------------------
/clients/php/native/tests/functionals/casperjs/01-index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/app/views/layouts/mailer.text.erb:
--------------------------------------------------------------------------------
1 | <%= yield %>
2 |
--------------------------------------------------------------------------------
/clients/haskell/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | .cabal-sandbox
3 | cabal.sandbox.config
4 |
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/watch-tests.sh:
--------------------------------------------------------------------------------
1 | cd test/xcarpaccio.tests
2 | dnx-watch test
3 |
--------------------------------------------------------------------------------
/clients/erlang/.gitignore:
--------------------------------------------------------------------------------
1 | .eunit
2 | .rebar/
3 | deps/
4 | ebin/
5 | erl_crash.dump
6 |
--------------------------------------------------------------------------------
/clients/java/java-springboot/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8090
--------------------------------------------------------------------------------
/clients/php/socket/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | .idea/
3 | .DS_Store
4 | composer.lock
5 |
--------------------------------------------------------------------------------
/clients/python/flask-server/__main__.py:
--------------------------------------------------------------------------------
1 | import client
2 |
3 | client.start_server()
4 |
--------------------------------------------------------------------------------
/clients/python/simple-server/__main__.py:
--------------------------------------------------------------------------------
1 | import client
2 |
3 | client.start_server()
--------------------------------------------------------------------------------
/clients/f#/carpaccio-client/paket.references:
--------------------------------------------------------------------------------
1 | Suave
2 | Newtonsoft.Json
3 | FSharp.Core
4 |
--------------------------------------------------------------------------------
/clients/python/simple-server-python3/__main__.py:
--------------------------------------------------------------------------------
1 | import client
2 |
3 | client.start_server()
--------------------------------------------------------------------------------
/clients/erlang/rebar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dlresende/extreme-carpaccio/HEAD/clients/erlang/rebar
--------------------------------------------------------------------------------
/clients/kotlin/src/main/resources/simplelogger.properties:
--------------------------------------------------------------------------------
1 | org.slf4j.simpleLogger.defaultLogLevel=error
--------------------------------------------------------------------------------
/clients/kotlin/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker:
--------------------------------------------------------------------------------
1 | mock-maker-inline
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/app/jobs/application_job.rb:
--------------------------------------------------------------------------------
1 | class ApplicationJob < ActiveJob::Base
2 | end
3 |
--------------------------------------------------------------------------------
/clients/javascript/node-plain/conf.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | port: 1337,
3 | host: "127.0.0.1"
4 | }
5 |
--------------------------------------------------------------------------------
/clients/f#/.gitignore:
--------------------------------------------------------------------------------
1 | .fake/
2 | build/
3 | deploy/
4 | packages/
5 | bin/
6 | obj/
7 | .paket/paket.exe
8 |
9 |
--------------------------------------------------------------------------------
/clients/groovy/groovy-ratpack/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 | build
3 | .gradle
4 | .project
5 | .settings
6 | .classpath
7 |
--------------------------------------------------------------------------------
/clients/php/socket/README.md:
--------------------------------------------------------------------------------
1 | Use composer to get dependencies
2 |
3 | $ composer install
4 |
5 | Run Starter.php
--------------------------------------------------------------------------------
/clients/javascript/express/lib/process.js:
--------------------------------------------------------------------------------
1 | exports.order = function order(input, onResult) {
2 | onResult(null, {});
3 | }
4 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::API
2 | end
3 |
--------------------------------------------------------------------------------
/clients/typescript/src/calc.ts:
--------------------------------------------------------------------------------
1 | // more of your code here
2 |
3 | export function sayHello() {
4 | return "Hello World";
5 | }
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/src/xcarpaccio/Models/Order.cs:
--------------------------------------------------------------------------------
1 | namespace XCarpaccio.Models
2 | {
3 | public class Order
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/clients/d/source/models/feedback.d:
--------------------------------------------------------------------------------
1 | module models.feedback;
2 |
3 | struct Feedback
4 | {
5 | string type;
6 | string content;
7 | }
--------------------------------------------------------------------------------
/clients/f#/.paket/paket.bootstrapper.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dlresende/extreme-carpaccio/HEAD/clients/f#/.paket/paket.bootstrapper.exe
--------------------------------------------------------------------------------
/clients/php/socket/src/OutputInterface.php:
--------------------------------------------------------------------------------
1 | (default port is 5000)
6 |
7 | dotnet test .\test\xcarpaccio.tests to run tests
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "projects": [
3 | "src",
4 | "test"
5 | ],
6 | "sdk": {
7 | "version": "1.0.0-preview2-1-003177"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/clients/c#/nancy/extreme-carpaccio.client/Bill.cs:
--------------------------------------------------------------------------------
1 | namespace xCarpaccio.client
2 | {
3 | class Bill
4 | {
5 | public decimal total { get; set; }
6 |
7 | }
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/clients/javascript/node-plain/main.js:
--------------------------------------------------------------------------------
1 | var conf = require('./conf'),
2 | server = require('./lib/server'),
3 | applyLogic = require('./lib/logic');
4 |
5 | server.start(conf, applyLogic);
6 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/cable.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: async
3 |
4 | test:
5 | adapter: async
6 |
7 | production:
8 | adapter: redis
9 | url: redis://localhost:6379/1
10 |
--------------------------------------------------------------------------------
/clients/php/socket/src/Console.php:
--------------------------------------------------------------------------------
1 | true]);
8 |
9 |
10 | $app->run();
11 |
--------------------------------------------------------------------------------
/clients/clojure/src/user.clj:
--------------------------------------------------------------------------------
1 | (ns user
2 | (:require [ring.adapter.jetty :refer [run-jetty]]
3 | [extremecarpaccio.core :refer :all]))
4 |
5 | (defonce server (run-jetty #'my-app {:port 4000 :join? false}))
6 |
--------------------------------------------------------------------------------
/clients/f#/paket.lock:
--------------------------------------------------------------------------------
1 | NUGET
2 | remote: https://www.nuget.org/api/v2
3 | specs:
4 | FAKE (4.28)
5 | FSharp.Core (4.0.0.1)
6 | Newtonsoft.Json (8.0.3)
7 | Suave (1.1.2)
8 | FSharp.Core (>= 3.1.2.5)
9 |
--------------------------------------------------------------------------------
/clients/c#/nancy/extreme-carpaccio.client/Feedback.cs:
--------------------------------------------------------------------------------
1 | namespace xCarpaccio.client
2 | {
3 | class Feedback
4 | {
5 | public string type { get; set; }
6 | public string content { get; set; }
7 |
8 | }
9 | }
--------------------------------------------------------------------------------
/clients/php/socket/src/Result.php:
--------------------------------------------------------------------------------
1 | total = $result;
10 | }
11 |
12 |
13 |
14 | }
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 |
--------------------------------------------------------------------------------
/clients/f#/carpaccio-client/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/clients/haskell/tdd.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | while true; do
4 |
5 | cabal test --test-option=--color
6 | echo ""
7 |
8 | inotifywait -qr -e modify -e create -e move -e delete src test --exclude "\.\#.*"
9 | done
10 |
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/src/main/java/xcarpaccio/Answer.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | public class Answer {
4 | public Double total;
5 |
6 | public Answer(double total) {
7 | this.total = total;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
3 | post :feedback, controller: :feedback
4 | end
5 |
--------------------------------------------------------------------------------
/clients/c#/nancy/README.md:
--------------------------------------------------------------------------------
1 | WELCOME TO NANCY :-),
2 |
3 | IF YOU DON'T HAVE NANCY YET, INSTALL THE NANCY PROJECT TEMPLATES FROM EXTENSIONS AND UPDATES - TOOLS
4 |
5 | BUILD TO RUN ANYWHERE,
6 | THIS IS A SELFHOSTING NANCY APPLICATION, JUST RUN IT
--------------------------------------------------------------------------------
/clients/php/silex/src/ExtremeCarpaccio/Model/Order.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/clients/kotlin/src/main/kotlin/xcarpaccio/Order.kt:
--------------------------------------------------------------------------------
1 | package xcarpaccio
2 |
3 | import kotlinx.serialization.Serializable
4 |
5 | @Serializable
6 | data class Order(val prices: List, val quantities: List, val country: String, val reduction: String) {
7 |
8 | }
--------------------------------------------------------------------------------
/clients/php/socket/src/Order.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require_relative 'config/application'
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure sensitive parameters which will be filtered from the log file.
4 | Rails.application.config.filter_parameters += [:password]
5 |
--------------------------------------------------------------------------------
/clients/php/socket/src/ReaderInterface.php:
--------------------------------------------------------------------------------
1 | mockGenerator->allIsInterface();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/clients/java/java-httpserver/manifest.yml:
--------------------------------------------------------------------------------
1 | ---
2 | applications:
3 | - name: extreme-carpaccio-java-http-server
4 | memory: 1G
5 | instances: 1
6 | path: target/extreme-carpaccio-java-httpserver-1.0-SNAPSHOT-jar-with-dependencies.jar
7 | buildpack: https://github.com/cloudfoundry/java-buildpack.git
8 |
--------------------------------------------------------------------------------
/clients/php/native/tests/units/Test.php:
--------------------------------------------------------------------------------
1 | mockGenerator->allIsInterface();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/clients/d/dub.json:
--------------------------------------------------------------------------------
1 | {
2 | "authors": [
3 | "Diego Lemos", "rgeorges"
4 | ],
5 | "copyright": " ",
6 | "dependencies": {
7 | "vibe-d": "~>0.8.6-rc.1"
8 | },
9 | "description": "extreme-carpaccio D language client.",
10 | "license": "public",
11 | "name": "extreme-carpaccio-server"
12 | }
--------------------------------------------------------------------------------
/clients/java/java-springboot/src/main/java/xcarpaccio/Amount.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | public class Amount {
4 |
5 | public Double total;
6 |
7 | public Amount(Double total) {
8 | this.total = total;
9 | }
10 |
11 | public Amount() {} //for test only
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/clients/javascript/express/lib/routes.js:
--------------------------------------------------------------------------------
1 | exports.order = function order(req, res, next) {
2 | // TODO implement from here
3 | res.json({});
4 | }
5 |
6 | exports.feedback = function feedback(req, res, next) {
7 | console.info("FEEDBACK:", req.body.type, req.body.content);
8 | next();
9 | }
10 |
--------------------------------------------------------------------------------
/clients/kotlin/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Jan 19 15:05:17 CET 2020
2 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip
3 | distributionBase=GRADLE_USER_HOME
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/clients/typescript/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es2017",
5 | "noImplicitAny": true,
6 | "outDir": "./dist",
7 | "sourceMap": true
8 | },
9 | "include": [
10 | "./src/**/*"
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/clients/erlang/src/xcarpaccio.erl:
--------------------------------------------------------------------------------
1 | -module(xcarpaccio).
2 |
3 | -export([start/0]).
4 |
5 | start() ->
6 | ok = application:start(crypto),
7 | ok = application:start(ranch),
8 | ok = application:start(cowlib),
9 | ok = application:start(cowboy),
10 | ok = application:start(xcarpaccio).
11 |
--------------------------------------------------------------------------------
/clients/java/java-httpserver/src/main/java/xcarpaccio/Result.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | public class Result {
4 | public Double total;
5 |
6 | public Result() { // Empty constructor required by Jackson
7 | }
8 |
9 | public Result(Double total) {
10 | this.total = total;
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/clients/groovy/groovy-ratpack/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Mar 13 14:31:38 CET 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-bin.zip
7 |
--------------------------------------------------------------------------------
/clients/racket/carpaccio.rkt:
--------------------------------------------------------------------------------
1 | #lang racket
2 |
3 | (provide carpaccio/total)
4 |
5 | (define (carpaccio/total details country reduction)
6 | 0.0)
7 |
8 |
9 | (module+ test
10 |
11 | (require rackunit rackunit/text-ui)
12 |
13 | (check-equal? 0.0 (carpaccio/total '() "" ""))
14 |
15 | "all test run")
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/src/main/java/xcarpaccio/Logger.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | public class Logger {
4 |
5 | public void log(String message) {
6 | System.out.println(message);
7 | }
8 |
9 | public void error(String message) {
10 | System.err.println(message);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/clients/typescript/src/calc.spec.ts:
--------------------------------------------------------------------------------
1 | import { sayHello } from "./calc";
2 |
3 |
4 | describe("Test calc", () => {
5 |
6 | test("Example unit test", () => {
7 | expect(true).toBe(true);
8 | });
9 |
10 | it("say hello", () => {
11 | expect(sayHello()).toBe("Hello World");
12 | })
13 |
14 | })
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
--------------------------------------------------------------------------------
/clients/scala/project/Dependencies.scala:
--------------------------------------------------------------------------------
1 | import sbt._
2 |
3 | object Dependencies {
4 | lazy val `akka-http`: ModuleID = "com.typesafe.akka" %% "akka-http" % "10.0.9"
5 | lazy val `akka-http-circe`: ModuleID = "de.heikoseeberger" %% "akka-http-circe" % "1.16.1"
6 | lazy val `circe-generic`: ModuleID = "io.circe" %% "circe-generic" % "0.8.0"
7 | }
8 |
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/src/xcarpaccio/models.cs:
--------------------------------------------------------------------------------
1 | namespace XCarpaccio
2 | {
3 | public class Feedback
4 | {
5 | public string Type { get; set; }
6 | public string Content { get; set; }
7 |
8 | public override string ToString()
9 | {
10 | return $"[{Type}] {Content}";
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/clients/kotlin/src/main/kotlin/xcarpaccio/Logger.kt:
--------------------------------------------------------------------------------
1 | package xcarpaccio
2 |
3 | class Logger {
4 | fun log(message: String) {
5 | println(message)
6 | }
7 |
8 | fun log(ex: Exception) {
9 | ex.printStackTrace()
10 | }
11 |
12 | fun error(message: String) {
13 | System.err.println(message)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/clients/php/silex/tests/functionals/features/Ping.feature:
--------------------------------------------------------------------------------
1 | Feature: Registration validation
2 | In order to play
3 | As a user
4 | I must confirm my registration
5 |
6 | Scenario: Registration confirmation
7 | Given I am a pre-registered user
8 | When I receive the registration validation
9 | Then I must validate my registration
10 |
--------------------------------------------------------------------------------
/clients/erlang/src/xcarpaccio.app.src:
--------------------------------------------------------------------------------
1 | {application, xcarpaccio,
2 | [
3 | {description, ""},
4 | {vsn, "1"},
5 | {registered, []},
6 | {applications, [
7 | kernel,
8 | stdlib,
9 | cowboy
10 | ]},
11 | {mod, { xcarpaccio_app, []}},
12 | {env, [{http_port, 1337}]}
13 | ]}.
14 |
--------------------------------------------------------------------------------
/clients/php/silex/README.md:
--------------------------------------------------------------------------------
1 | Configure your /etc/hosts file with your docker IP address. The project hostname is "project.loc"
2 |
3 | Start docker environment :
4 |
5 | $ make start
6 |
7 | Stop docker environment :
8 |
9 | $ make stop
10 |
11 | Start provisioning :
12 |
13 | $ make up
14 |
15 | Run tests :
16 |
17 | $ make tests
18 |
--------------------------------------------------------------------------------
/clients/c#/nancy/NancyApplication1/IndexModule.cs:
--------------------------------------------------------------------------------
1 | namespace NancyApplication1
2 | {
3 | using Nancy;
4 |
5 | public class IndexModule : NancyModule
6 | {
7 | public IndexModule()
8 | {
9 | Get["/"] = parameters =>
10 | {
11 | return View["index"];
12 | };
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/clients/php/socket/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "extremeCarpaccioPhpClient",
3 | "minimum-stability": "stable",
4 | "license": "open source",
5 | "require": {
6 | "phpunit/phpunit": "6.5.14",
7 | "ext-sockets": "*",
8 | "ext-json": "*"
9 | },
10 | "autoload": {
11 | "psr-0": {
12 | "" : "src"
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/src/xcarpaccio/Models/Feedback.cs:
--------------------------------------------------------------------------------
1 | namespace XCarpaccio.Models
2 | {
3 | public class Feedback
4 | {
5 | public string Type { get; set; }
6 | public string Content { get; set; }
7 |
8 | public override string ToString()
9 | {
10 | return $"[{Type}] {Content}";
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/clients/c#/nancy/extreme-carpaccio.client/Order.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace xCarpaccio.client
4 | {
5 | class Order
6 | {
7 | public decimal[] prices { get; set; }
8 | public int [] quantities { get; set; }
9 | public string country { get; set; }
10 | public string reduction { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/clients/rust/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "extreme"
3 | version = "0.1.0"
4 | authors = ["Jean-Eudes"]
5 |
6 | [dependencies]
7 | rustc-serialize = "0.3"
8 |
9 | [dependencies.nickel]
10 | version = "*"
11 | # If you are using the 'nightly' rust channel you can uncomment
12 | # the line below to activate unstable features
13 | # features = ["unstable"]
14 |
15 |
--------------------------------------------------------------------------------
/clients/d/.gitignore:
--------------------------------------------------------------------------------
1 | .dub
2 | docs.json
3 | __dummy.html
4 | docs/
5 | /extreme-carpaccio-server
6 | extreme-carpaccio-server.so
7 | extreme-carpaccio-server.dylib
8 | extreme-carpaccio-server.dll
9 | extreme-carpaccio-server.a
10 | extreme-carpaccio-server.lib
11 | extreme-carpaccio-server-test-*
12 | *.exe
13 | *.o
14 | *.obj
15 | *.lst
16 | *.dll
17 | dub.selections.json
18 |
--------------------------------------------------------------------------------
/clients/javascript/node-plain/README.md:
--------------------------------------------------------------------------------
1 | # Run
2 |
3 | ```
4 | npm start
5 | ```
6 |
7 | # Test
8 |
9 | ```
10 | npm test
11 | ```
12 |
13 | # Resources
14 |
15 | * [Simplified HTTP request client](https://github.com/request/request)
16 | * [Using Jasmine-Node to Test Your Node Server](http://randomjavascript.blogspot.fr/2012/12/using-jasmine-node-to-test-your-node.html)
17 |
--------------------------------------------------------------------------------
/clients/php/silex/tests/functionals/features/bootstrap/ExtremeCarpaccio/FeatureContext.php:
--------------------------------------------------------------------------------
1 | 2000) return price * 1.18; else return price * 1.18; }"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/server"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 | versioning-strategy: increase-if-necessary
9 | ignore:
10 | - dependency-name: chalk
11 | - dependency-name: eslint-plugin-promise
12 | versions:
13 | - 4.3.0
14 | commit-message:
15 | prefix: "chore"
16 |
--------------------------------------------------------------------------------
/clients/erlang/rebar.config:
--------------------------------------------------------------------------------
1 | %% -*- erlang -*-
2 | {erl_opts, [debug_info]}.
3 | {deps, [
4 | {cowboy, "1.0.1", {git, "https://github.com/ninenines/cowboy.git", {tag, "1.0.1"}}},
5 | {jsx, "2.4.0", {git, "https://github.com/talentdeficit/jsx.git", {tag, "v2.4.0"}}}
6 | ]}.
7 | {cover_enabled, true}.
8 | {eunit_opts, [
9 | verbose, {report,{eunit_surefire,[{dir,"."}]}}
10 | ]}.
11 |
--------------------------------------------------------------------------------
/clients/php/native/docker/php/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:fpm
2 |
3 | WORKDIR /home/project
4 |
5 | RUN apt-get update && apt-get upgrade -y && apt-get install -y git libssl-dev wget && \
6 | docker-php-ext-install zip mbstring && \
7 | pecl install xdebug-beta && docker-php-ext-enable xdebug
8 |
9 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
10 |
--------------------------------------------------------------------------------
/clients/php/silex/docker/php/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:fpm
2 |
3 | WORKDIR /home/project
4 |
5 | RUN apt-get update && apt-get upgrade -y && apt-get install -y git libssl-dev wget && \
6 | docker-php-ext-install zip mbstring && \
7 | pecl install xdebug-beta && docker-php-ext-enable xdebug
8 |
9 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
10 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/README.md:
--------------------------------------------------------------------------------
1 | ## Dependencies
2 | - Ruby v2.0+
3 | - Ruby gem
4 |
5 | ## Install
6 | ```
7 | gem install bundler
8 | bundle install
9 | ```
10 |
11 | ## Start
12 | ```
13 | bundle exec rails s -p8888 -b0.0.0.0
14 | # -b0.0.0.0 Is to allow access from LAN or else only localhost can access
15 | ```
16 |
17 | The server listens on port 8888: [http://localhost:8888](http://localhot:8888)
18 |
--------------------------------------------------------------------------------
/clients/haskell/test/Spec.hs:
--------------------------------------------------------------------------------
1 | module Main where
2 |
3 | import Test.Hspec
4 | import Model
5 |
6 | main :: IO ()
7 | main = hspec $ do
8 |
9 | describe "computeTotal" $ do
10 |
11 | -- Replace this test with a relevant ones
12 | it "should give the dummy value of 1000" $ do
13 | let order = Order [3.14] [42] "WHATEVER" "WHATEVER"
14 | in computeTotal order `shouldBe` Quantity 1000.0
15 |
--------------------------------------------------------------------------------
/clients/java/java-httpserver/src/main/java/xcarpaccio/Logger.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | public class Logger {
4 | public void log(String message) {
5 | System.out.println(message);
6 | }
7 |
8 | public void log(Exception ex) {
9 | ex.printStackTrace();
10 | }
11 |
12 | public void error(String message) {
13 | System.err.println(message);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | *.iml
3 |
4 | lib-cov
5 | *.seed
6 | *.log
7 | *.csv
8 | *.dat
9 | *.out
10 | *.pid
11 | *.gz
12 | *.orig
13 |
14 | [Dd]ebug/
15 | [Oo]bj/
16 | [Bb]in
17 | [Rr]elease
18 | *.suo
19 | **/packages/*
20 | pids
21 | logs
22 | results
23 |
24 | npm-debug.log
25 | node_modules
26 |
27 | server/public/components
28 | *.sublime-project
29 | *.sublime-workspace
30 | .DS_Store
31 | *.tmp
32 | *.swp
33 |
--------------------------------------------------------------------------------
/clients/php/socket/tests/TestOrder.php:
--------------------------------------------------------------------------------
1 | assertEquals($expected, $actual);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/db/seeds.rb:
--------------------------------------------------------------------------------
1 | # This file should contain all the record creation needed to seed the database with its default values.
2 | # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
3 | #
4 | # Examples:
5 | #
6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
7 | # Character.create(name: 'Luke', movie: movies.first)
8 |
--------------------------------------------------------------------------------
/clients/javascript/node-plain/lib/logic.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Where all the logic should be executed (http entry point)
3 | *
4 | * @param {Object} reqBody - http request body payload
5 | * @return {Object} response that will be returned as json
6 | * @api public
7 | */
8 | var applyLogic = function(reqBody) {
9 |
10 | // TODO implement from here
11 | return {total: 0.0};
12 | };
13 |
14 | module.exports = applyLogic;
15 |
--------------------------------------------------------------------------------
/clients/python/simple-server/README.md:
--------------------------------------------------------------------------------
1 | # Python Client server
2 |
3 | The server is developed with python 3.4
4 |
5 | ## How to run the server
6 |
7 | ### Console
8 | You can run it with python console
9 |
10 | ```
11 | import client
12 | client.start_server()
13 | ```
14 |
15 | ### Python call
16 | Calling python . in the project directory
17 |
18 | ```
19 | python .
20 | ```
21 |
22 | Or use your favorite IDE
23 |
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/test/xcarpaccio.tests/tests.cs:
--------------------------------------------------------------------------------
1 | namespace XCarpaccio.Tests
2 | {
3 | using Xunit;
4 |
5 | public class WalkingSkeleton
6 | {
7 | [Fact]
8 | public void feedback_model_prints_nicely()
9 | {
10 | var feedback = new Feedback() { Type = "Error", Content = "Hello" };
11 | Assert.Equal("[Error] Hello", feedback.ToString());
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/clients/php/native/tests/functionals/casperjs/02-ping.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | casper.test.begin('Check http://project.loc/ping', 2, function(test) {
4 | casper.start('http://project.loc/ping', function() {
5 | test.assertHttpStatus(200);
6 | }).then(function() {
7 | test.assertEquals(this.getPageContent(), 'pong', "Pong found");
8 | }).run(function() {
9 | test.done();
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/clients/php/silex/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '2'
2 |
3 | services:
4 | web:
5 | image: nginx:latest
6 | ports:
7 | - "80:80"
8 | volumes:
9 | - .:/home/project
10 | - ./docker/nginx/site.conf:/etc/nginx/conf.d/site.conf
11 |
12 | php:
13 | build: ./docker/php
14 | volumes:
15 | - .:/home/project
16 | working_dir: /home/project
17 | links:
18 | - "web:project.loc"
19 |
--------------------------------------------------------------------------------
/clients/python/simple-server-python3/README.md:
--------------------------------------------------------------------------------
1 | # Python Client server
2 |
3 | The server is developed with python 3.4
4 |
5 | ## How to run the server
6 |
7 | ### Console
8 | You can run it with python console
9 |
10 | ```
11 | import client
12 | client.start_server()
13 | ```
14 |
15 | ### Python call
16 | Calling python . in the project directory
17 |
18 | ```
19 | python .
20 | ```
21 |
22 | Or use your favorite IDE
23 |
--------------------------------------------------------------------------------
/clients/c#/nancy/NancyApplication1/Bootstrapper.cs:
--------------------------------------------------------------------------------
1 | namespace NancyApplication1
2 | {
3 | using Nancy;
4 |
5 | public class Bootstrapper : DefaultNancyBootstrapper
6 | {
7 | // The bootstrapper enables you to reconfigure the composition of the framework,
8 | // by overriding the various methods and properties.
9 | // For more information https://github.com/NancyFx/Nancy/wiki/Bootstrapper
10 | }
11 | }
--------------------------------------------------------------------------------
/clients/f#/carpaccio-client/carpaccio-model.fs:
--------------------------------------------------------------------------------
1 | module CarpaccioModel
2 | open System
3 |
4 | []
5 | type Result = {total: double}
6 |
7 | []
8 | type Feedback =
9 | { Type: string
10 | Content: string }
11 |
12 | []
13 | type Order =
14 | { prices : double[]
15 | quantities: double[]
16 | country: string
17 | reduction: string
18 | }
19 |
--------------------------------------------------------------------------------
/clients/java/java-springboot/src/main/java/xcarpaccio/CarpaccioApplication.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class CarpaccioApplication {
8 | public static void main(String[] args) {
9 | SpringApplication.run(CarpaccioApplication.class, args);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/clients/javascript/express/test/200-process-order.js:
--------------------------------------------------------------------------------
1 | var expect = require('chai').expect;
2 | var process = require('../lib/process');
3 |
4 | describe('process.order(payload, callback)', function () {
5 | it('calls back with an empty object', function (done) {
6 | process.order({}, function (err, result) {
7 | if (err) return done(err);
8 | expect(result).to.deep.equal({});
9 | done();
10 | })
11 | })
12 | })
13 |
--------------------------------------------------------------------------------
/clients/javascript/node-plain/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "extreme-carpaccio-client-node-plain",
3 | "version": "0.1.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "node main.js",
7 | "test": "./node_modules/jasmine-node/bin/jasmine-node ."
8 | },
9 | "dependencies": {
10 | "request": "2.53.*",
11 | "chalk": "^1.1.3"
12 | },
13 | "devDependencies": {
14 | "jasmine-node": "^1.14.5"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/clients/php/native/web/app.php:
--------------------------------------------------------------------------------
1 | function () {
9 | header('HTTP/1.1 204 No Content');
10 | header('Content-Type: text/plain; charset=utf8');
11 | },
12 | ];
13 |
14 | $route = in_array($_SERVER['REQUEST_URI'], ['/', '/ping', ]) ? $_SERVER['REQUEST_URI'] : '/';
15 |
16 | $actions[$route]();
17 |
--------------------------------------------------------------------------------
/clients/c#/nancy/extreme-carpaccio.client/Bootstrapper.cs:
--------------------------------------------------------------------------------
1 | namespace xCarpaccio.client
2 | {
3 | using Nancy;
4 |
5 | public class Bootstrapper : DefaultNancyBootstrapper
6 | {
7 | // The bootstrapper enables you to reconfigure the composition of the framework,
8 | // by overriding the various methods and properties.
9 | // For more information https://github.com/NancyFx/Nancy/wiki/Bootstrapper
10 | }
11 | }
--------------------------------------------------------------------------------
/.github/workflows/on-all-prs.yml:
--------------------------------------------------------------------------------
1 | on: pull_request
2 |
3 | permissions:
4 | contents: write
5 | pull-requests: write
6 |
7 | jobs:
8 | automerge-when-author-is-dependabot:
9 | runs-on: ubuntu-latest
10 | if: github.actor == 'dependabot[bot]'
11 | steps:
12 | - run: gh pr merge --auto --merge "$PR_URL"
13 | env:
14 | PR_URL: ${{github.event.pull_request.html_url}}
15 | GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
16 |
17 |
--------------------------------------------------------------------------------
/clients/haskell/src/Model.hs:
--------------------------------------------------------------------------------
1 | module Model
2 | where
3 |
4 | data Order = Order
5 | { prices :: [Double]
6 | , quantities :: [Integer]
7 | , country :: String
8 | , reduction :: String
9 | } deriving (Show)
10 |
11 | data Quantity = Quantity
12 | { _total :: Double } deriving (Show,Eq)
13 |
14 | computeTotal :: Order -> Quantity
15 | computeTotal _ =
16 | -- You should replace this dummy value with your algorithm
17 | Quantity 1000.0
18 |
--------------------------------------------------------------------------------
/clients/ruby/sinatra/README.md:
--------------------------------------------------------------------------------
1 | A ruby client based on [http://www.sinatrarb.com/](Sinatra)
2 |
3 | ## Dependencies
4 | - Ruby v2.0+
5 | - Ruby gem
6 |
7 | ## Install
8 | ```
9 | gem install sinatra sinatra-reloader json rack-test
10 | ```
11 |
12 | ## Start
13 | ```
14 | ruby lib/extreme-carpaccio.rb
15 | ```
16 |
17 | The server listens on port 9000: (http://localhost:4567/ping)[http://localhot:4567]
18 |
19 | ## Test
20 |
21 | ```
22 | rake test
23 | ```
24 |
--------------------------------------------------------------------------------
/clients/c#/nancy/NancyApplication1/Views/index.sshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NancyApplication1
6 |
7 |
14 |
15 |
16 |
17 | 
18 | This view was rendered using the SuperSimpleViewEngine
19 |
20 |
21 |
--------------------------------------------------------------------------------
/clients/java/java-springboot/src/main/java/xcarpaccio/FeedbackMessage.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | public class FeedbackMessage {
4 | public String type;
5 | public String content;
6 |
7 | @Override
8 | public String toString() {
9 | return "FeedbackMessage{" +
10 | "type='" + type + '\'' +
11 | ", content='" + content + '\'' +
12 | '}';
13 | }
14 |
15 | public FeedbackMessage() {
16 | }
17 | }
--------------------------------------------------------------------------------
/clients/php/native/docker-compose.yml:
--------------------------------------------------------------------------------
1 | php:
2 | build: docker/php
3 | volumes:
4 | - .:/home/project
5 | working_dir: /home/project
6 |
7 | web:
8 | image: nginx:latest
9 | ports:
10 | - "80:80"
11 | volumes:
12 | - .:/home/project
13 | - ./docker/nginx/site.conf:/etc/nginx/conf.d/site.conf
14 | links:
15 | - php
16 |
17 | testing:
18 | image: vitr/casperjs
19 | volumes:
20 | - .:/home/project
21 | links:
22 | - "web:project.loc"
23 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/clients/php/native/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "extreme-carpaccio/clients-php-native",
3 | "autoload": {
4 | "psr-4": {
5 | "ExtremeCarpaccio\\": "src/ExtremeCarpaccio"
6 | }
7 | },
8 | "require-dev": {
9 | "atoum/atoum": "~3.0",
10 | "atoum/stubs": "~2.5"
11 | },
12 | "autoload-dev": {
13 | "psr-4": {
14 | "Tests\\Units\\": "tests/units",
15 | "Tests\\Units\\ExtremeCarpaccio\\": "tests/units/src/ExtremeCarpaccio"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/src/xcarpaccio/Controllers/OrderController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using XCarpaccio.Models;
3 |
4 | namespace XCarpaccio.Controllers
5 | {
6 | [Route("[controller]")]
7 | public class OrderController : Controller
8 | {
9 | public OrderController(){
10 | }
11 |
12 | [HttpPost]
13 | public IActionResult Post([FromBody]Order order)
14 | {
15 | return this.NotFound();
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/test/xcarpaccio.tests/feedbackTest.cs:
--------------------------------------------------------------------------------
1 | using System.Net;
2 | using Xunit;
3 | using XCarpaccio.Models;
4 |
5 | namespace XCarpaccio.Tests
6 | {
7 |
8 | public class WalkingSkeleton
9 | {
10 | [Fact]
11 | public void feedback_model_prints_nicely()
12 | {
13 | var feedback = new Feedback() { Type = "Error", Content = "Hello" };
14 | Assert.Equal("[Error] Hello", feedback.ToString());
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/clients/php/silex/tests/functionals/features/Order.feature:
--------------------------------------------------------------------------------
1 | Feature: Order management
2 | In order to calculate the bill
3 | I must compute the amount of the received orders
4 |
5 | Scenario: Order without reduction
6 | Given I have the following order
7 | | price | quantity |
8 | | 15.99 | 1 |
9 | And the country is "ES"
10 | And the reduction is "STANDARD"
11 | When I validate
12 | Then The total must be 19.03 €
13 |
--------------------------------------------------------------------------------
/clients/javascript/express/README.md:
--------------------------------------------------------------------------------
1 | Express Client
2 | ==============
3 |
4 | Install
5 | -------
6 |
7 | npm install
8 |
9 | Start
10 | -----
11 |
12 | PORT=1234 npm start
13 |
14 | default port is 3000
15 |
16 | Start with ` nodemon `
17 | _(Alternatively, you can use nodemon instead of node.)_
18 | -----
19 |
20 | npm run nodemon
21 | > about nodemon: http://nodemon.io/
22 |
23 | Test
24 | ----
25 |
26 | npm test
27 |
28 | Implement
29 | ----
30 | See TODO in `routes.js`
31 |
--------------------------------------------------------------------------------
/server/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bower.json",
3 | "version": "0.0.0",
4 | "authors": [
5 | "dotnetstation "
6 | ],
7 | "description": "bower packages",
8 | "dependencies": {
9 | "react": "~0.12.2",
10 | "bootstrap": "~3.3.2",
11 | "react-bootstrap": "~0.15.1",
12 | "respond": "~1.4.2",
13 | "html5shiv": "~3.7.2",
14 | "jquery": "~2.1.3",
15 | "react-intl": "~1.1.0",
16 | "chartjs": "~1.0.1",
17 | "lodash": "~3.4.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/clients/php/native/README.md:
--------------------------------------------------------------------------------
1 | Configure your /etc/hosts file with your docker IP address. The project hostname is "project.loc"
2 |
3 | Start docker environment :
4 |
5 | $ make start
6 |
7 | Stop docker environment :
8 |
9 | $ make stop
10 |
11 | Start provisioning :
12 |
13 | $ make up
14 |
15 | Run functional tests :
16 |
17 | $ make functional-tests
18 |
19 | Run unit tests :
20 |
21 | $ make unit-tests
22 |
23 | Run all tests :
24 |
25 | $ make tests
26 |
27 |
--------------------------------------------------------------------------------
/clients/php/socket/src/FeedbackMessage.php:
--------------------------------------------------------------------------------
1 | _type = $type;
11 | $this->_content = $content;
12 | }
13 |
14 | public function GetMessage(): string
15 | {
16 | return $this->_content;
17 | }
18 |
19 | public function GetType()
20 | {
21 | return $this->_type;
22 | }
23 | }
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/src/main/java/xcarpaccio/MyFluentHttpServer.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import net.codestory.http.WebServer;
4 |
5 | public class MyFluentHttpServer {
6 |
7 | public MyFluentHttpServer() {
8 | this(9000);
9 | }
10 |
11 | public MyFluentHttpServer(int port) {
12 | new WebServer().configure(new WebConfiguration()).start(port);
13 | }
14 |
15 | public static void main( String[] args ) {
16 | new MyFluentHttpServer();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/clients/php/silex/tests/functionals/features/bootstrap/ExtremeCarpaccio/ApiContext.php:
--------------------------------------------------------------------------------
1 | baseUrl = $baseUrl;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/clients/java/java-spark/src/main/java/extremecarpaccio/JsonResponseTransformer.java:
--------------------------------------------------------------------------------
1 | package extremecarpaccio;
2 |
3 | import com.google.gson.Gson;
4 | import spark.ResponseTransformer;
5 |
6 | public class JsonResponseTransformer implements ResponseTransformer {
7 | private final Gson gson;
8 |
9 | public JsonResponseTransformer(Gson gson) {
10 | this.gson = gson;
11 | }
12 |
13 | @Override
14 | public String render(Object o) throws Exception {
15 | return gson.toJson(o);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/clients/php/socket/src/JsonFeedbackMapper.php:
--------------------------------------------------------------------------------
1 |
12 | {
13 | WriteLine($"[{ctx.Request.Method}] {ctx.Request.Path}");
14 | return next();
15 | });
16 | app.UseOwin(x => x.UseNancy());
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/server/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "node": true
6 | },
7 | "extends": [
8 | "standard"
9 | ],
10 | "globals": {
11 | "Atomics": "readonly",
12 | "SharedArrayBuffer": "readonly"
13 | },
14 | "parserOptions": {
15 | "ecmaFeatures": {
16 | "jsx": true
17 | },
18 | "ecmaVersion": 2018,
19 | "sourceType": "module"
20 | },
21 | "plugins": [
22 | "react"
23 | ],
24 | "rules": {
25 | }
26 | }
--------------------------------------------------------------------------------
/server/specs/investigating_spec.js:
--------------------------------------------------------------------------------
1 |
2 | describe('Configuration', function(){
3 | it('should evaluate function from string', function() {
4 | var customEval = function(s) { return new Function("return " + s)(); },
5 | str1 = "function (price) { return price - 50; }",
6 | fun1 = customEval(str1),
7 | str2 = "function (price) { return price / 2; }",
8 | fun2 = customEval(str2);
9 |
10 | expect(fun1.apply(null, [124])).toEqual(74);
11 | expect(fun2.apply(null, [124])).toEqual(62);
12 | })
13 | });
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/build.sh:
--------------------------------------------------------------------------------
1 | @echo off
2 | echo ===============================
3 | echo - Xtrem Carpaccio! -
4 | echo ===============================
5 |
6 | echo ======== RESTORE DEPENDENCIES =============
7 | dnu commands install Microsoft.Dnx.Watcher
8 | dnu restore
9 |
10 | echo ======== BUILD SOURCES =============
11 | cd src/xcarpaccio/
12 | dnu build
13 | cd ../..
14 | echo ======== BUILD TESTS =============
15 | cd test/xcarpaccio.tests/
16 | dnu build
17 | echo ======== RUN TESTS =============
18 | dnx test
19 | cd ../../
20 |
--------------------------------------------------------------------------------
/.github/workflows/on-prs-made-against-the-server.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | pull_request:
5 | paths:
6 | - server/**
7 |
8 | jobs:
9 | run-tests-on-windows:
10 | name: on windows
11 | runs-on: windows-latest
12 | steps:
13 | - uses: actions/checkout@v3
14 | - run: npm install && npm test
15 | working-directory: server
16 | run-tests-on-linux:
17 | name: on linux
18 | runs-on: ubuntu-latest
19 | steps:
20 | - uses: actions/checkout@v3
21 | - run: npm install && npm test
22 | working-directory: server
23 |
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/src/xcarpaccio/app.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using Microsoft.AspNetCore.Builder;
3 | using Microsoft.AspNetCore.Hosting;
4 |
5 | namespace XCarpaccio
6 | {
7 |
8 | public class Program
9 | {
10 | public static void Main(params string[] args)
11 | {
12 | var host = new WebHostBuilder()
13 | .UseContentRoot(Directory.GetCurrentDirectory())
14 | .UseKestrel()
15 | .UseStartup()
16 | .Build();
17 |
18 | host.Run();
19 | }
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/clients/f#/README.md:
--------------------------------------------------------------------------------
1 | Suave is a simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition.
2 |
3 | This project has been created with Fsharp yeoman [generator](https://github.com/fsprojects/generator-fsharp).
4 | It uses [Fake](http://fsharp.github.io/FAKE/) and [Paket](https://fsprojects.github.io/Paket/).
5 |
6 |
7 | It can now run without Visual studio as well and on other platform using Mono.
8 |
9 | You just need to run build.sh or build.cmd depending on your platform.
10 |
11 | Good luck !
--------------------------------------------------------------------------------
/clients/clojure/test/extremecarpaccio/core_test.clj:
--------------------------------------------------------------------------------
1 | (ns extremecarpaccio.core-test
2 | (:require [midje.sweet :refer :all]
3 | [ring.mock.request :as mock]
4 | [extremecarpaccio.core :refer :all]))
5 |
6 | (facts "about routes"
7 | (fact "ping route should respond pong"
8 | (let [response (my-app (mock/request :get "/ping"))]
9 | (:status response) => 200
10 | (:body response) => "pong"))
11 |
12 | (fact "not-found route should respond 404"
13 | (let [response (my-app (mock/request :get "/invalid"))]
14 | (:status response) => 404)))
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json]
9 | end
10 |
11 | # To enable root element in JSON for ActiveRecord objects.
12 | # ActiveSupport.on_load(:active_record) do
13 | # self.include_root_in_json = true
14 | # end
15 |
--------------------------------------------------------------------------------
/clients/php/native/.bootstrap.atoum.php:
--------------------------------------------------------------------------------
1 |
10 | Vals = jsx:decode(<<"{\"prices\":[75.87],\"quantities\":[5],\"country\":\"FR\"}">>),
11 | Key = <<"prices">>,
12 | ?assertEqual({Key, [75.87]}, proplists:lookup(Key, Vals)).
13 |
14 | encoding_test() ->
15 | Data = #{total => 0.0},
16 | Json = jsx:encode(Data),
17 | ?assertEqual(<<"{\"total\":0.0}">>, Json).
18 |
--------------------------------------------------------------------------------
/clients/java/java-spark/src/main/java/extremecarpaccio/Strings.java:
--------------------------------------------------------------------------------
1 | package extremecarpaccio;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | public class Strings {
8 |
9 | public static String stringify(InputStream is, String charset) throws IOException {
10 | byte[] buffer = new byte[1024];
11 | ByteArrayOutputStream bout = new ByteArrayOutputStream();
12 | int read;
13 | while ((read = is.read(buffer)) >= 0) {
14 | bout.write(buffer, 0, read);
15 | }
16 | return bout.toString(charset);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/src/xcarpaccio/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/clients/python/flask-server/README.md:
--------------------------------------------------------------------------------
1 | #Flask python Client server
2 |
3 | The server is developed with Flask (http://flask.pocoo.org/).
4 | To run the test you need at least python 2.7.8.
5 |
6 | ## How to Install
7 | ```
8 | pip install Flask
9 | ```
10 |
11 | ## How to run the server
12 |
13 | The server runs by defaut on port 5000 and listens to any open interface.
14 |
15 | ### Console
16 | You can run it with python console :
17 |
18 | ```
19 | import client
20 | client.start_server()
21 | ```
22 |
23 | ### Python call
24 | Calling python . in the project directory :
25 |
26 | ```
27 | python .
28 | ```
29 |
30 | Or use your favorite IDE.
31 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2 | #
3 | # If you find yourself ignoring temporary files generated by your text editor
4 | # or operating system, you probably want to add a global ignore instead:
5 | # git config --global core.excludesfile '~/.gitignore_global'
6 |
7 | # Ignore bundler config.
8 | /.bundle
9 |
10 | # Ignore the default SQLite database.
11 | /db/*.sqlite3
12 | /db/*.sqlite3-journal
13 |
14 | # Ignore all logfiles and tempfiles.
15 | /log/*
16 | /tmp/*
17 | !/log/.keep
18 | !/tmp/.keep
19 |
20 | # Ignore Byebug command history file.
21 | .byebug_history
22 |
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/test/xcarpaccio.tests/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0-*",
3 | "buildOptions": {
4 | "debugType": "portable"
5 | },
6 | "dependencies": {
7 | "xunit": "2.1.0",
8 | "dotnet-test-xunit": "2.2.0-preview2-build1029",
9 | "xcarpaccio": { "target": "project" }
10 | },
11 | "testRunner": "xunit",
12 | "frameworks": {
13 | "netcoreapp1.0": {
14 | "dependencies": {
15 | "Microsoft.NETCore.App": {
16 | "type": "platform",
17 | "version": "1.0.0"
18 | }
19 | },
20 | "imports": [
21 | "dotnet5.4",
22 | "portable-net451+win8"
23 | ]
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/clients/javascript/express/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "carpaccio-client-express",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "app.js",
6 | "scripts": {
7 | "test": "mocha test",
8 | "nodemon": "nodemon server.js"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "chai": "^3.4.1",
14 | "mocha": "^2.3.4",
15 | "nodemon": "^1.17.3",
16 | "sinon": "^1.17.2",
17 | "sinon-chai": "^2.8.0",
18 | "supertest": "^1.1.0"
19 | },
20 | "dependencies": {
21 | "body-parser": "^1.14.1",
22 | "express": "^4.13.3",
23 | "morgan": "^1.6.1",
24 | "request": "^2.67.0"
25 | }
26 | }
--------------------------------------------------------------------------------
/clients/racket/README.md:
--------------------------------------------------------------------------------
1 | # Extreme Carpaccio Racket starting code
2 |
3 | ## Prerequisites
4 |
5 | You will need [Racket](http://racket-lang.org/) installed.
6 |
7 | ## Test Driven Development
8 |
9 | 1. Lauch DrRacket
10 | 2. Load file ```carpaccio.rkt ```
11 | 3. Run it with ```Ctrl-R```
12 | 4. Check tests are ok with message ```all test run```
13 |
14 | You can start your TDD loops.
15 |
16 | ## Running in "production"
17 |
18 | To start a web server for the application, run:
19 |
20 | $ racket -tm web-server.rkt
21 |
22 | You can save the output in a log file with the ```tee``` command:
23 |
24 | $ racket -tm web-server.rkt | tee -a log.txt
25 |
26 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.1.0",
3 | "command": "dotnet",
4 | "isShellCommand": true,
5 | "args": [],
6 | "tasks": [
7 | {
8 | "taskName": "build",
9 | "args": [
10 | "${workspaceRoot}\\src\\xcarpaccio\\project.json"
11 | ],
12 | "isBuildCommand": true,
13 | "problemMatcher": "$msCompile"
14 | },
15 | {
16 | "taskName": "test",
17 | "args": [
18 | "${workspaceRoot}\\test\\xcarpaccio.tests\\project.json"
19 | ],
20 | "isTestCommand" : true
21 | }
22 | ]
23 | }
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.1.0",
3 | "command": "dotnet",
4 | "isShellCommand": true,
5 | "args": [],
6 | "tasks": [
7 | {
8 | "taskName": "build",
9 | "args": [
10 | "${workspaceRoot}\\src\\xcarpaccio\\project.json"
11 | ],
12 | "isBuildCommand": true,
13 | "problemMatcher": "$msCompile"
14 | },
15 | {
16 | "taskName": "test",
17 | "args": [
18 | "${workspaceRoot}\\test\\xcarpaccio.tests\\project.json"
19 | ],
20 | "isTestCommand" : true
21 | }
22 | ]
23 | }
--------------------------------------------------------------------------------
/clients/c#/nancy/NancyApplication1/Program.cs:
--------------------------------------------------------------------------------
1 | namespace NancyApplication1
2 | {
3 | using System;
4 | using Nancy.Hosting.Self;
5 |
6 | class Program
7 | {
8 | static void Main(string[] args)
9 | {
10 | var uri =
11 | new Uri("http://localhost:3579");
12 |
13 | using (var host = new NancyHost(uri))
14 | {
15 | host.Start();
16 |
17 | Console.WriteLine("Your application is running on " + uri);
18 | Console.WriteLine("Press any [Enter] to close the host.");
19 | Console.ReadLine();
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/clients/clojure/project.clj:
--------------------------------------------------------------------------------
1 | (defproject extremecarpaccio "0.1.0-SNAPSHOT"
2 | :description "Dumbed down Clojure example code for Extreme Carpaccio kata"
3 | :url "https://github.com/dlresende/extreme-carpaccio"
4 | :min-lein-version "2.0.0"
5 | :dependencies [[org.clojure/clojure "1.10.0"]
6 | [compojure "1.6.1"]
7 | [ring "1.8.0"]
8 | [ring/ring-mock "0.4.0"]
9 | [ring-middleware-format "0.7.4"]]
10 | :plugins [[lein-ring "0.12.5"]
11 | [lein-midje "3.2.2"]]
12 | :ring {:handler extremecarpaccio.core/my-app}
13 | :profiles {:dev {:dependencies [[midje "1.9.9"]]}})
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/clients/php/socket/src/Starter.php:
--------------------------------------------------------------------------------
1 | Start();
--------------------------------------------------------------------------------
/clients/groovy/groovy-ratpack/src/ratpack/Ratpack.groovy:
--------------------------------------------------------------------------------
1 | import static ratpack.groovy.Groovy.ratpack
2 | import groovy.json.JsonSlurper
3 | import groovy.util.logging.Slf4j;
4 |
5 |
6 |
7 |
8 | ratpack {
9 | handlers {
10 |
11 | get("hello") {
12 | render "Hello world!"
13 | }
14 | post("ping") {
15 |
16 | render "pong"
17 | }
18 |
19 | post("") {
20 | if (request.body.text) {
21 | def body = new JsonSlurper().parseText(request.body.text)
22 | println "Incoming request on '/': $body"
23 | }
24 |
25 | render "pong"
26 | }
27 |
28 | }
29 | }
30 |
31 |
32 |
33 | public String asJSON(total) {
34 | '{ "total": ' + total + ' }'
35 | }
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/README.md:
--------------------------------------------------------------------------------
1 | A Java client to with a simple net.codestory.http.WebServer implementation.
2 |
3 | ## Dependencies
4 | - maven 3
5 | - JDK 8
6 |
7 | ## Install
8 | - `mvn clean package`
9 |
10 | ## Run
11 | You don't need any application server. No Tomcat, no WAR to deploy. The server is embedded.
12 |
13 | - `mvn exec:java -Dexec.mainClass="xcarpaccio.MyFluentHttpServer"`
14 |
15 | The server listens on port 9000: [http://localhost:9000/ping](http://localhost:9000/ping)
16 |
17 | You can also launch the server with your IDE. You just have to launch `MyFluentHttpServer` class. It has a `main` method.
18 |
19 | The API is implemented in `WebConfiguration` class.
20 |
--------------------------------------------------------------------------------
/clients/php/socket/tests/TestJsonFeedbackMapper.php:
--------------------------------------------------------------------------------
1 | setValues($json);
19 |
20 | $this->assertEquals($expectedFeedbackMessage, $feedbackMessage);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite version 3.x
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem 'sqlite3'
6 | #
7 | default: &default
8 | adapter: sqlite3
9 | pool: 5
10 | timeout: 5000
11 |
12 | development:
13 | <<: *default
14 | database: db/development.sqlite3
15 |
16 | # Warning: The database defined as "test" will be erased and
17 | # re-generated from your development database when you run "rake".
18 | # Do not set this db to the same as development or production.
19 | test:
20 | <<: *default
21 | database: db/test.sqlite3
22 |
23 | production:
24 | <<: *default
25 | database: db/production.sqlite3
26 |
--------------------------------------------------------------------------------
/clients/typescript/src/server.ts:
--------------------------------------------------------------------------------
1 | import * as Koa from 'koa';
2 | import * as Router from 'koa-router';
3 | import bodyParser = require("koa-bodyparser");
4 | import { sayHello } from './calc';
5 |
6 | const app = new Koa();
7 | app.use(bodyParser());
8 | const router = new Router();
9 |
10 | router.get('/*', async (ctx) => {
11 | ctx.body = sayHello();
12 | });
13 |
14 | router.post('/feedback', async (ctx) => {
15 | console.log('Feedback received', ctx.request.body);
16 | });
17 |
18 | router.post('/order', async (ctx) => {
19 | // your code here
20 | });
21 |
22 | app.use(router.routes());
23 |
24 | app.listen(8080);
25 |
26 | console.log('Server running on port 8080');
27 |
28 |
--------------------------------------------------------------------------------
/clients/java/java-httpserver/src/main/java/xcarpaccio/Order.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import java.util.Arrays;
4 |
5 | public class Order {
6 | public Double[] prices;
7 | public Double[] quantities;
8 | public String country;
9 | public String reduction;
10 |
11 | @Override
12 | public String toString() {
13 | final StringBuilder sb = new StringBuilder("Order{");
14 | sb.append("prices=").append(Arrays.toString(prices));
15 | sb.append(", quantities=").append(Arrays.toString(quantities));
16 | sb.append(", country='").append(country).append('\'');
17 | sb.append(", reduction='").append(reduction).append('\'');
18 | sb.append('}');
19 | return sb.toString();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/clients/d/source/utils.d:
--------------------------------------------------------------------------------
1 | module utils;
2 |
3 | import vibe.d : HTTPStatus, HTTPStatusException;
4 | import std.stdio : writefln;
5 |
6 | /**
7 | * Displays a yellow message.
8 | */
9 | void info(Args...)(string info, Args args)
10 | {
11 | writefln("\033[0;33m" ~ info ~ "\033[0m", args);
12 | }
13 |
14 | /**
15 | * Displays a red message.
16 | */
17 | void error(Args...)(string error, Args args)
18 | {
19 | writefln("\033[1;31m" ~ error ~ "\033[0m", args);
20 | }
21 |
22 | /**
23 | * Throw an HTTP exception and returns the specified status code.
24 | */
25 | void throwHTTPError(HTTPStatus status)
26 | {
27 | error("Sending HTTP code %d.", status);
28 | throw new HTTPStatusException(status);
29 | }
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/src/main/java/xcarpaccio/Message.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
4 | import com.fasterxml.jackson.annotation.JsonCreator;
5 | import com.fasterxml.jackson.annotation.JsonProperty;
6 |
7 | @JsonAutoDetect(
8 | fieldVisibility = JsonAutoDetect.Visibility.ANY // mandatory for serialization
9 | )
10 | public class Message {
11 |
12 | final String type;
13 | final String content;
14 |
15 | @JsonCreator
16 | public Message(
17 | @JsonProperty("type") String type,
18 | @JsonProperty("content") String content) {
19 | this.type = type;
20 | this.content = content;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/clients/java/java-springboot/src/main/java/xcarpaccio/Order.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 | import java.io.Serializable;
3 | import java.util.Arrays;
4 |
5 | public class Order implements Serializable {
6 | public Double[] prices;
7 | public Long[] quantities;
8 | public String country;
9 | public String reduction;
10 |
11 | public Order() {
12 | }
13 |
14 | @Override
15 | public String toString() {
16 | return "Order{" +
17 | "prices=" + Arrays.toString(prices) +
18 | ", quantities=" + Arrays.toString(quantities) +
19 | ", country='" + country + '\'' +
20 | ", reduction='" + reduction + '\'' +
21 | '}';
22 | }
23 | }
--------------------------------------------------------------------------------
/clients/c#/nancy/extreme-carpaccio.client/Program.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Threading;
3 |
4 | namespace xCarpaccio.client
5 | {
6 | using System;
7 | using Nancy.Hosting.Self;
8 |
9 | class Program
10 | {
11 | static void Main(string[] args)
12 | {
13 | var uri =
14 | new Uri("http://localhost:8080");
15 |
16 | using (var host = new NancyHost(uri))
17 | {
18 | host.Start();
19 |
20 | Console.WriteLine("Your application is running on " + uri);
21 | Console.WriteLine("Press any [Enter] to close the host.");
22 | Console.ReadLine();
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/src/main/java/xcarpaccio/Order.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import java.util.List;
4 |
5 | public class Order {
6 | public List prices;
7 | public List quantities;
8 | public List names;
9 | public String country;
10 | public String reduction;
11 |
12 | @Override
13 | public String toString() {
14 | final StringBuilder sb = new StringBuilder("Order{");
15 | sb.append("prices=").append(prices);
16 | sb.append(", quantities=").append(quantities);
17 | sb.append(", names=").append(names);
18 | sb.append(", country='").append(country).append('\'');
19 | sb.append(", reduction='").append(reduction).append('\'');
20 | sb.append('}');
21 | return sb.toString();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/clients/php/native/tests/units/src/ExtremeCarpaccio/Model/OrderProduct.php:
--------------------------------------------------------------------------------
1 | given(
13 | $unitPrice = mt_rand() / mt_rand(),
14 | $quantity = mt_rand()
15 | )
16 | ->if(
17 | $this->newTestedInstance($unitPrice, $quantity)
18 | )
19 | ->then
20 | ->integer($this->testedInstance->getQuantity())->isEqualTo($quantity)
21 | ->float($this->testedInstance->getUnitPrice())->isEqualTo($unitPrice)
22 | ;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/clients/php/silex/tests/units/src/ExtremeCarpaccio/Model/OrderProduct.php:
--------------------------------------------------------------------------------
1 | given(
13 | $unitPrice = mt_rand() / mt_rand(),
14 | $quantity = mt_rand()
15 | )
16 | ->if(
17 | $this->newTestedInstance($unitPrice, $quantity)
18 | )
19 | ->then
20 | ->integer($this->testedInstance->getQuantity())->isEqualTo($quantity)
21 | ->float($this->testedInstance->getUnitPrice())->isEqualTo($unitPrice)
22 | ;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, '\1en'
8 | # inflect.singular /^(ox)en/i, '\1'
9 | # inflect.irregular 'person', 'people'
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym 'RESTful'
16 | # end
17 |
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/src/xcarpaccio/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.0.1-*",
3 | "buildOptions": {
4 | "debugType": "portable",
5 | "emitEntryPoint": true
6 | },
7 | "description":"my c# version of the extreme-carpaccio",
8 | "dependencies": {
9 | "Microsoft.NETCore.App": {
10 | "version": "1.0.0",
11 | "type": "platform"
12 | },
13 | "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
14 | "Microsoft.AspNetCore.Owin": "1.0.0",
15 | "Nancy": "2.0.0-barneyrubble"
16 | },
17 | "commands": {
18 | "web": "Microsoft.AspNet.Server.Kestrel --server.urls http://*:5000"
19 | },
20 | "frameworks": {
21 | "netcoreapp1.0": {}
22 | },
23 | "tooling": {
24 | "defaultNamespace": "XCarpaccio"
25 | }
26 | }
27 |
28 |
29 |
--------------------------------------------------------------------------------
/clients/php/silex/behat.yml:
--------------------------------------------------------------------------------
1 | aliases:
2 | - &baseUrl http://project.loc
3 |
4 | default:
5 | extensions:
6 | Behat\MinkExtension:
7 | base_url: *baseUrl
8 | sessions:
9 | default:
10 | goutte: ~
11 | suites:
12 | ping:
13 | paths: [%paths.base%/tests/functionals/features/Ping.feature]
14 | contexts:
15 | - 'Tests\Functionals\ExtremeCarpaccio\ApiContext\PingContext':
16 | - *baseUrl
17 | order:
18 | paths: [%paths.base%/tests/functionals/features/Order.feature]
19 | contexts:
20 | - 'Tests\Functionals\ExtremeCarpaccio\ApiContext\OrderContext':
21 | - *baseUrl
22 |
--------------------------------------------------------------------------------
/clients/php/silex/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "extreme-carpaccio/clients-php-silex",
3 | "require": {
4 | "silex/silex": "~2.0",
5 | "monolog/monolog": "~1.22"
6 | },
7 | "autoload": {
8 | "psr-4": {
9 | "ExtremeCarpaccio\\": "src/ExtremeCarpaccio"
10 | }
11 | },
12 | "require-dev": {
13 | "atoum/atoum": "~3.0",
14 | "atoum/stubs": "~2.5",
15 | "behat/behat": "~3.3",
16 | "behat/mink-extension": "~2.2",
17 | "behat/mink-goutte-driver": "~1.0"
18 | },
19 | "autoload-dev": {
20 | "psr-4": {
21 | "Tests\\Units\\": "tests/units",
22 | "Tests\\Units\\ExtremeCarpaccio\\": "tests/units/src/ExtremeCarpaccio",
23 | "Tests\\Functionals\\": "tests/functionals/features/bootstrap"
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization
2 | # and are automatically loaded by Rails. If you want to use locales other
3 | # than English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t 'hello'
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t('hello') %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # To learn more, please read the Rails Internationalization guide
20 | # available at http://guides.rubyonrails.org/i18n.html.
21 |
22 | en:
23 | hello: "Hello world"
24 |
--------------------------------------------------------------------------------
/clients/f#/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if test "$OS" = "Windows_NT"
3 | then
4 | # use .Net
5 |
6 | .paket/paket.bootstrapper.exe
7 | exit_code=$?
8 | if [ $exit_code -ne 0 ]; then
9 | exit $exit_code
10 | fi
11 |
12 | .paket/paket.exe restore
13 | exit_code=$?
14 | if [ $exit_code -ne 0 ]; then
15 | exit $exit_code
16 | fi
17 |
18 | packages/FAKE/tools/FAKE.exe $@ --fsiargs build.fsx
19 | else
20 | # use mono
21 | mono .paket/paket.bootstrapper.exe
22 | exit_code=$?
23 | if [ $exit_code -ne 0 ]; then
24 | exit $exit_code
25 | fi
26 |
27 | mono .paket/paket.exe restore
28 | exit_code=$?
29 | if [ $exit_code -ne 0 ]; then
30 | exit $exit_code
31 | fi
32 | mono packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx
33 | fi
34 |
--------------------------------------------------------------------------------
/clients/clojure/README.md:
--------------------------------------------------------------------------------
1 | # Extreme Carpaccio Clojure starting code
2 |
3 | ## Prerequisites
4 |
5 | You will need **Leiningen 2.0.0** or above installed.
6 |
7 | https://leiningen.org/#install
8 |
9 | ## Development
10 | 1. Fire up a REPL
11 | 2. Hack away, redefine functions they will be hot reloaded, live coding FTW!
12 | 3. Beat the shit out of those crappy java servers :)
13 |
14 | ## Run test
15 | To start a web server and run tests for the application, run:
16 |
17 | ```
18 | lein midje
19 | ```
20 |
21 | Tests can be run in watch mode like this
22 |
23 | ```
24 | lein midje :autotest
25 | ```
26 |
27 |
28 | ## Running in "production"
29 | To start a web server for the application, listening on , type:
30 |
31 |
32 | ```
33 | lein ring server [port]
34 | ```
35 |
36 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/src/xcarpaccio/Controllers/FeedbackController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using Microsoft.Extensions.Logging;
3 | using XCarpaccio.Models;
4 |
5 | namespace XCarpaccio.Controllers
6 | {
7 | [Route("[controller]")]
8 | public class FeedbackController : Controller
9 | {
10 | ILogger logger;
11 |
12 | public FeedbackController(ILogger logger){
13 | this.logger = logger;
14 | }
15 |
16 | [HttpPost]
17 | public IActionResult Post([FromBody]Feedback feedBack)
18 | {
19 | logger.LogDebug($"Feedback: Type is {feedBack.Type}, Content is {feedBack.Content}");
20 | return this.Ok();
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/clients/php/native/tests/functionals/casperjs/04-feedback.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | casper.test.begin('/feedback : Method not allowed', function suite(test) {
4 | casper.start('http://project.loc/feedback', function(response) {
5 | casper.test.assertHttpStatus(405);
6 | casper.test.assertMatch(
7 | response.headers.get('Content-Type'),
8 | new RegExp('|^application/json|', 'i'),
9 | 'Content-Type match the expected value'
10 | );
11 | });
12 | casper.then(function() {
13 | var content = JSON.parse(this.getPageContent());
14 | casper.test.assertEquals(content.error, 'Method not allowed; You must use POST', "Method not allowed");
15 | });
16 | casper.run(function () {
17 | test.done();
18 | });
19 | });
20 |
21 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/src/xcarpaccio/Program.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Linq;
3 | using Microsoft.AspNetCore.Hosting;
4 | using XCarpaccio;
5 |
6 | namespace WebApplication
7 | {
8 | public class Program
9 | {
10 | public static void Main(string[] args)
11 | {
12 | var port = 5000.ToString();
13 | if (args != null && args.Any())
14 | {
15 | port = args[0];
16 | }
17 |
18 | var host = new WebHostBuilder()
19 | .UseKestrel()
20 | .UseContentRoot(Directory.GetCurrentDirectory())
21 | .UseStartup()
22 | .UseUrls($"http://*:{port}")
23 | .Build();
24 |
25 | host.Run();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/clients/javascript/express/test/000-server-start.js:
--------------------------------------------------------------------------------
1 | var supertest = require('supertest');
2 | var Server = require('../server');
3 |
4 | describe('the server', function () {
5 | var previousPort, server;
6 | beforeEach(function () {
7 | previousPort = process.env.PORT;
8 | process.env.PORT = 21345;
9 | })
10 | afterEach(function () {
11 | process.env.PORT = previousPort;
12 | });
13 |
14 | beforeEach(function (done) {
15 | server = new Server();
16 | server.start(done);
17 | })
18 |
19 | afterEach(function (done) {
20 | server.stop(done);
21 | })
22 |
23 | it('starts on the port in PORT', function (done) {
24 | supertest('http://localhost:21345')
25 | .get('/status')
26 | .expect(200)
27 | .expect({up: true})
28 | .end(done)
29 | });
30 | })
31 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/test/xcarpaccio.tests/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0-*",
3 | "buildOptions": {
4 | "debugType": "portable"
5 | },
6 | "dependencies": {
7 | "xunit": "2.1.0",
8 | "dotnet-test-xunit": "2.2.0-preview2-build1029",
9 | "Microsoft.DotNet.InternalAbstractions": "1.0.0",
10 | "NSubstitute":"2.0.0-rc",
11 | "xcarpaccio": { "target": "project" }
12 | },
13 | "testRunner": "xunit",
14 | "frameworks": {
15 | "netcoreapp1.1": {
16 | "dependencies": {
17 | "Microsoft.NETCore.App": {
18 | "type": "platform",
19 | "version": "1.1.0"
20 | }
21 | },
22 | "imports": [
23 | "dotnet5.0"
24 | ]
25 | }
26 | },
27 | "tools": {
28 | "Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final"
29 | },
30 | }
--------------------------------------------------------------------------------
/clients/clojure/src/extremecarpaccio/core.clj:
--------------------------------------------------------------------------------
1 | (ns extremecarpaccio.core
2 | (:require [compojure.core :refer [routes GET POST]]
3 | [compojure.route :refer [not-found]]
4 |
5 | [ring.middleware.format :refer [wrap-restful-format]]
6 | [ring.util.response :refer [response]]))
7 |
8 | (defn handle-feedback [req]
9 | (let [body (:body-params req)]
10 | (println (:type body) ":" (:content body))
11 | (response nil)))
12 |
13 | (defn cannot-handle [req]
14 | (println "Cannot handle " req)
15 | (response nil))
16 |
17 | (def my-app
18 | (-> (routes
19 | (POST "/feedback" [] handle-feedback)
20 | (GET "/ping" [] "pong")
21 | (GET "/" [] "I'm alive!")
22 | (not-found cannot-handle))
23 | (wrap-restful-format :formats [:json-kw])))
24 |
25 |
26 |
--------------------------------------------------------------------------------
/clients/java/java-httpserver/README.md:
--------------------------------------------------------------------------------
1 | A Java client to with a simple com.sun.net.httpserver.HttpServer implementation.
2 |
3 | ## Dependencies
4 | - maven 3
5 | - JDK 8
6 |
7 | ## Install
8 | - `mvn clean install`
9 |
10 | ## Code
11 | The game server will post orders on `/order` endpoint.
12 | `OrderHttpHandler` inner class inside `MyHttpServer.java` file will handle this so this is where to start coding.
13 |
14 | ## Run
15 | You don't need any application server. No Tomcat, no WAR to deploy. The server is embedded.
16 |
17 | - `PORT=9000 java -jar target/extreme-carpaccio-java-httpserver-1.0-SNAPSHOT-jar-with-dependencies.jar`
18 |
19 | In the example above the server listens on port 9000: [http://localhost:9000/ping](http://localhost:9000/ping)
20 |
21 | You can also launch the server with your IDE. You just have to launch `MyHttpServer` class. It has a `main` method.
22 |
--------------------------------------------------------------------------------
/clients/d/README.md:
--------------------------------------------------------------------------------
1 | D language client for extreme-carpaccio game
2 | ============================================
3 |
4 | This implementation is based on [vibe-d 0.8.6](http://vibed.org/docs). It provides basic routing and models for the following routes:
5 | - POST `/order` (returns 404 by default)
6 | - POST `/feedback` (returns 404 by default)
7 |
8 | The default port is `9000`. You can pass a specific ip and port to the `HTTPServerSettings` object in `app.d` with the following syntax :
9 |
10 | ```d
11 | auto settings = HTTPServerSettings("0.0.0.0:1337");
12 | ```
13 |
14 |
15 | How to use this client
16 | ================
17 |
18 | Install the [dub package manager](http://code.dlang.org/download) and a [D compiler](https://dlang.org/download.html) (dmd is the best option in this context).
19 |
20 | Clone this repository and type `dub` in current directory.
21 |
22 | Have fun!
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "extreme-carpaccio-server",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node bin/www",
7 | "test": "jasmine-node .",
8 | "lint": "eslint javascripts/",
9 | "postinstall": "bower install"
10 | },
11 | "dependencies": {
12 | "body-parser": "^2.2.0",
13 | "chalk": "^4.1.2",
14 | "debug": "^4.3.4",
15 | "express": "^5.1.0",
16 | "lodash": "^4.17.21",
17 | "url-assembler": "^2.1.1"
18 | },
19 | "devDependencies": {
20 | "bower": "^1.8.14",
21 | "eslint": "^8.57.0",
22 | "eslint-config-standard": "^17.1.0",
23 | "eslint-plugin-import": "^2.29.1",
24 | "eslint-plugin-node": "^11.1.0",
25 | "eslint-plugin-promise": "^6.1.1",
26 | "eslint-plugin-react": "^7.34.1",
27 | "jasmine-node": "^3.0.0",
28 | "supertest": "^7.0.0"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/clients/php/silex/tests/functionals/features/bootstrap/ExtremeCarpaccio/ApiContext/PingContext.php:
--------------------------------------------------------------------------------
1 | visitPath('/ping');
26 | }
27 |
28 | /**
29 | * @Then I must validate my registration
30 | */
31 | public function iMustValidateMyRegistration()
32 | {
33 | $this->assertResponseContains('pong');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/clients/haskell/README.md:
--------------------------------------------------------------------------------
1 | # Extreme Carpaccio Haskell starting code
2 |
3 | ## Prerequisites
4 |
5 | You will need [Haskell](https://www.haskell.org/) installed with `ghc`
6 | and `cabal` available.
7 |
8 | The application is based on the
9 | [Scotty](https://github.com/scotty-web/scotty) web framework (a Ruby
10 | Sinatra clone).
11 |
12 | ## Build
13 |
14 | To build the application:
15 |
16 | $ cabal install
17 | $ cabal sandbox init
18 | $ cabal build
19 |
20 | Launch it:
21 |
22 | $ .cabal-sandbox/bin/carpaccio
23 |
24 | To run unit-tests:
25 |
26 | $ cabal install --only-dependencies --enable-tests
27 | $ cabal test
28 |
29 | ## Test Driven Development
30 |
31 | Code your algorithm using TDD:
32 |
33 | 1. Launch the `tdd.sh` script
34 | 2. From now, as soon you modify a source file, it will build and test
35 | it.
36 | 3. `ctrl-c` to exit
37 |
38 | Happy coding!
39 |
--------------------------------------------------------------------------------
/clients/php/socket/src/Response.php:
--------------------------------------------------------------------------------
1 | formatAnswer($result);
10 | socket_write($spawn, $answer, strlen($answer));
11 | }
12 |
13 | private function formatAnswer($result)
14 | {
15 | $answer = "";
16 | if($result != null) {
17 | $answer = json_encode($result);
18 | }
19 | $result = $this->GetHeader($answer);
20 | $result .= $answer;
21 |
22 | return $result;
23 | }
24 |
25 | private function GetHeader(string $answer): string
26 | {
27 | $result = "HTTP/1.0 200 OK\n";
28 | $result .= "Content-Type: application/json\n";
29 | $result .= "Content-Length: " . strlen($answer) . "\n";
30 | $result .= "\r\n";
31 | return $result;
32 | }
33 | }
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/initializers/new_framework_defaults.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 | #
3 | # This file contains migration options to ease your Rails 5.0 upgrade.
4 | #
5 | # Read the Guide for Upgrading Ruby on Rails for more info on each option.
6 |
7 | # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
8 | # Previous versions had false.
9 | ActiveSupport.to_time_preserves_timezone = true
10 |
11 | # Require `belongs_to` associations by default. Previous versions had false.
12 | Rails.application.config.active_record.belongs_to_required_by_default = true
13 |
14 | # Do not halt callback chains when a callback returns false. Previous versions had true.
15 | ActiveSupport.halt_callback_chains_on_return_false = false
16 |
17 | # Configure SSL options to enable HSTS with subdomains. Previous versions had false.
18 | Rails.application.config.ssl_options = { hsts: { subdomains: true } }
19 |
--------------------------------------------------------------------------------
/clients/f#/build.fsx:
--------------------------------------------------------------------------------
1 | // include Fake libs
2 | #r "./packages/FAKE/tools/FakeLib.dll"
3 |
4 | open Fake
5 |
6 | // Directories
7 | let buildDir = "./build/"
8 | let deployDir = "./deploy/"
9 |
10 |
11 | // Filesets
12 | let appReferences =
13 | !! "/**/*.csproj"
14 | ++ "/**/*.fsproj"
15 |
16 | // version info
17 | let version = "0.1" // or retrieve from CI server
18 |
19 | // Targets
20 | Target "Clean" (fun _ ->
21 | CleanDirs [buildDir; deployDir]
22 | )
23 |
24 | Target "Build" (fun _ ->
25 | // compile all projects below src/app/
26 | MSBuildDebug buildDir "Build" appReferences
27 | |> Log "AppBuild-Output: "
28 | )
29 |
30 | Target "Deploy" (fun _ ->
31 | !! (buildDir + "/**/*.*")
32 | -- "*.zip"
33 | |> Zip buildDir (deployDir + "ApplicationName." + version + ".zip")
34 | )
35 |
36 | // Build order
37 | "Clean"
38 | ==> "Build"
39 | ==> "Deploy"
40 |
41 | // start build
42 | RunTargetOrDefault "Build"
43 |
--------------------------------------------------------------------------------
/clients/php/native/docker/nginx/site.conf:
--------------------------------------------------------------------------------
1 | server {
2 | server_name project.loc;
3 | root /home/project/web;
4 |
5 | location / {
6 | # try to serve file directly, fallback to front controller
7 | try_files $uri /app.php$is_args$args;
8 | }
9 |
10 | # If you have 2 front controllers for dev|prod use the following line instead
11 | # location ~ ^/(index|index_dev)\.php(/|$) {
12 | location ~ ^/app\.php(/|$) {
13 | fastcgi_pass php:9000;
14 | fastcgi_index app.php;
15 | fastcgi_split_path_info ^(.+\.php)(/.*)$;
16 | include fastcgi_params;
17 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
18 | fastcgi_param HTTPS off;
19 | }
20 |
21 | #return 404 for all php files as we do have a front controller
22 | location ~ \.php$ {
23 | return 404;
24 | }
25 |
26 | error_log /var/log/nginx/project_error.log;
27 | access_log /var/log/nginx/project_access.log;
28 | }
29 |
--------------------------------------------------------------------------------
/clients/php/silex/Makefile:
--------------------------------------------------------------------------------
1 | DOCKER_COMPOSE ?= $(shell which docker-compose)
2 | PHP ?= $(shell $(DOCKER_COMPOSE) run php which php)
3 | COMPOSER ?= $(shell $(DOCKER_COMPOSE) run php which composer)
4 | THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
5 |
6 | .PHONY: start
7 | start:
8 | $(DOCKER_COMPOSE) up -d
9 |
10 | .PHONY: stop
11 | stop:
12 | $(DOCKER_COMPOSE) down
13 |
14 | .PHONY: restart
15 | restart:
16 | $(MAKE) -f $(THIS_MAKEFILE) stop
17 | $(MAKE) -f $(THIS_MAKEFILE) start
18 |
19 | .PHONY: up
20 | up: vendor
21 |
22 | composer.lock: composer.json
23 | $(DOCKER_COMPOSE) run php $(PHP) $(COMPOSER) update
24 |
25 | vendor: composer.lock
26 | $(DOCKER_COMPOSE) run php $(PHP) $(COMPOSER) install
27 |
28 | .PHONY: functional-tests
29 | functional-tests:
30 | $(DOCKER_COMPOSE) run php $(PHP) vendor/bin/behat
31 |
32 | .PHONY: unit-tests
33 | unit-tests:
34 | $(DOCKER_COMPOSE) run php $(PHP) vendor/bin/atoum
35 |
36 | .PHONY: tests
37 | tests: functional-tests unit-tests
38 |
--------------------------------------------------------------------------------
/clients/php/silex/docker/nginx/site.conf:
--------------------------------------------------------------------------------
1 | server {
2 | server_name project.loc;
3 | root /home/project/web;
4 |
5 | location / {
6 | # try to serve file directly, fallback to front controller
7 | try_files $uri /app.php$is_args$args;
8 | }
9 |
10 | # If you have 2 front controllers for dev|prod use the following line instead
11 | # location ~ ^/(index|index_dev)\.php(/|$) {
12 | location ~ ^/app\.php(/|$) {
13 | fastcgi_pass php:9000;
14 | fastcgi_index app.php;
15 | fastcgi_split_path_info ^(.+\.php)(/.*)$;
16 | include fastcgi_params;
17 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
18 | fastcgi_param HTTPS off;
19 | }
20 |
21 | #return 404 for all php files as we do have a front controller
22 | location ~ \.php$ {
23 | return 404;
24 | }
25 |
26 | error_log /var/log/nginx/project_error.log;
27 | access_log /var/log/nginx/project_access.log;
28 | }
29 |
--------------------------------------------------------------------------------
/clients/groovy/groovy-ratpack/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | }
5 | dependencies {
6 | classpath "io.ratpack:ratpack-gradle:0.9.14"
7 | }
8 | }
9 |
10 | apply plugin: "io.ratpack.ratpack-groovy"
11 | apply plugin: "eclipse"
12 |
13 | repositories {
14 | jcenter()
15 | maven { url "http://clinker.netty.io/nexus/content/repositories/snapshots" }
16 | maven { url "http://oss.jfrog.org/artifactory/repo" }
17 | }
18 |
19 | dependencies {
20 | runtime "org.slf4j:slf4j-simple:1.7.5"
21 |
22 | // Spock for testing
23 | testCompile "org.spockframework:spock-core:1.0-groovy-2.4"
24 |
25 | // optional dependencies for using Spock
26 | testCompile "org.hamcrest:hamcrest-core:1.3" // only necessary if Hamcrest matchers are used
27 | testRuntime "cglib:cglib-nodep:3.1" // allows mocking of classes (in addition to interfaces)
28 | testRuntime "org.objenesis:objenesis:2.1" // allows mocking of classes without default constructor (together with CGLIB)
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/clients/haskell/carpaccio.cabal:
--------------------------------------------------------------------------------
1 | name: carpaccio
2 | version: 0.0.1
3 | synopsis: A haskell client for extreme-carpaccio
4 | homepage: https://github.com/dlresende/extreme-carpaccio
5 | build-type: Simple
6 | cabal-version: >=1.8
7 |
8 | executable carpaccio
9 | main-is: Main.hs
10 | hs-source-dirs: src
11 | build-depends: base ==4.7.*
12 | , wai
13 | , warp
14 | , http-types
15 | , resourcet
16 | , scotty
17 | , aeson
18 | , text
19 | , bytestring
20 | , blaze-html
21 | , transformers
22 | , mtl
23 |
24 | test-suite spec
25 | main-is: Spec.hs
26 | hs-source-dirs: test src
27 | type: exitcode-stdio-1.0
28 | build-depends: base == 4.*
29 | , hspec >= 1.3
30 |
--------------------------------------------------------------------------------
/clients/c#/nancy/extreme-carpaccio.client.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "extreme-carpaccio.client", "extreme-carpaccio.client\extreme-carpaccio.client.csproj", "{35460AA4-B94A-4B64-9418-7243EC3D2F01}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {35460AA4-B94A-4B64-9418-7243EC3D2F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {35460AA4-B94A-4B64-9418-7243EC3D2F01}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {35460AA4-B94A-4B64-9418-7243EC3D2F01}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {35460AA4-B94A-4B64-9418-7243EC3D2F01}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/src/xcarpaccio/modules.cs:
--------------------------------------------------------------------------------
1 | namespace XCarpaccio
2 | {
3 | using Nancy;
4 | using Nancy.ModelBinding;
5 | using System;
6 | using static System.Console;
7 |
8 | public class HomeModule : NancyModule
9 | {
10 | public HomeModule()
11 | {
12 |
13 | Get("/", p => "DNX-CSharp Carpaccio Online!
");
14 |
15 | Post("/order", p =>
16 | {
17 | WriteLine($"[{DateTime.Now}]");
18 | return new { Ignored = true };
19 | });
20 |
21 | Post("/feedback", p =>
22 | {
23 | try
24 | {
25 | var feedback = this.Bind();
26 | WriteLine($"[{feedback.Type}] {feedback.Content}");
27 | }
28 | catch (Exception e)
29 | {
30 | int i = 1;
31 | }
32 | return Negotiate.WithStatusCode(200);
33 |
34 |
35 | });
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/secrets.yml:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key is used for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 |
6 | # Make sure the secret is at least 30 characters and all random,
7 | # no regular words or you'll be exposed to dictionary attacks.
8 | # You can use `rails secret` to generate a secure secret key.
9 |
10 | # Make sure the secrets in this file are kept private
11 | # if you're sharing your code publicly.
12 |
13 | development:
14 | secret_key_base: ba8519cb5a196ccb5c48f3228c150253ec5ba55406abefa6dd44c341dd94eee2f6ab2aa484ffda5687e054782b27641083df4e219484b16863dde14bd5dbb4fe
15 |
16 | test:
17 | secret_key_base: 16a85ae14ca8aecbaab5c1b7aa633aca3272f62c67025490dbdcd8a57c5b9f353b0248c1f61b12d3a193b7fba670ee5a5d075a90acbf5235ca58f3ebaf521782
18 |
19 | # Do not keep production secrets in the repository,
20 | # instead read values from the environment.
21 | production:
22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
23 |
--------------------------------------------------------------------------------
/clients/d/source/app.d:
--------------------------------------------------------------------------------
1 | import vibe.d;
2 |
3 | import models.order;
4 | import models.feedback;
5 |
6 | import utils;
7 |
8 | void main()
9 | {
10 | auto router = new URLRouter();
11 | router.post("/order", &handleOrder);
12 | router.post("/feedback", &handleFeedback);
13 |
14 | auto settings = new HTTPServerSettings(":9000");
15 |
16 | // Starting the server
17 | listenHTTP(settings, router);
18 | runApplication();
19 | }
20 |
21 | /**
22 | * Handling POST /order request.
23 | */
24 | void handleOrder(HTTPServerRequest request, HTTPServerResponse response)
25 | {
26 | info("\n");
27 | info("Received order JSON: %s", request.json);
28 |
29 | auto order = deserializeJson!Order(request.json);
30 |
31 | throwHTTPError(HTTPStatus.notFound);
32 | }
33 |
34 | /**
35 | * Handling POST /feedback request.
36 | */
37 | void handleFeedback(HTTPServerRequest request, HTTPServerResponse response)
38 | {
39 | auto feedback = deserializeJson!Feedback(request.json);
40 |
41 | error("Received feedback %s: %s", feedback.type, feedback.content);
42 | }
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/src/xcarpaccio/RequestLoggerMiddleware.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Threading.Tasks;
3 | using Microsoft.AspNetCore.Http;
4 | using Microsoft.Extensions.Logging;
5 |
6 | namespace XCarpaccio
7 | {
8 | public class RequestLoggerMiddleware
9 | {
10 | private readonly RequestDelegate _next;
11 | private readonly ILogger _logger;
12 |
13 | public RequestLoggerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
14 | {
15 | _next = next;
16 | _logger = loggerFactory.CreateLogger();
17 | }
18 |
19 | public async Task Invoke(HttpContext context)
20 | {
21 | using (var bodyReader = new StreamReader(context.Request.Body))
22 | {
23 | string body = await bodyReader.ReadToEndAsync();
24 | context.Request.Body = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(body));
25 | _logger.LogDebug(body);
26 | }
27 | await _next.Invoke(context);
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/clients/php/native/Makefile:
--------------------------------------------------------------------------------
1 | DOCKER_COMPOSE ?= $(shell which docker-compose)
2 | PHP ?= $(shell $(DOCKER_COMPOSE) run php which php)
3 | COMPOSER ?= $(shell $(DOCKER_COMPOSE) run php which composer)
4 | CASPERJS ?= $(shell $(DOCKER_COMPOSE) run testing which casperjs)
5 | THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
6 |
7 | .PHONY: start
8 | start:
9 | $(DOCKER_COMPOSE) up -d
10 |
11 | .PHONY: stop
12 | stop:
13 | $(DOCKER_COMPOSE) down
14 |
15 | .PHONY: restart
16 | restart:
17 | $(MAKE) -f $(THIS_MAKEFILE) stop
18 | $(MAKE) -f $(THIS_MAKEFILE) start
19 |
20 | .PHONY: up
21 | up: vendor
22 |
23 | composer.lock: composer.json
24 | $(DOCKER_COMPOSE) run php $(PHP) $(COMPOSER) update
25 |
26 | vendor: composer.lock
27 | $(DOCKER_COMPOSE) run php $(PHP) $(COMPOSER) install
28 |
29 | .PHONY: functional-tests
30 | functional-tests:
31 | $(DOCKER_COMPOSE) run testing $(CASPERJS) test /home/project/tests/functionals/casperjs/
32 |
33 | .PHONY: unit-tests
34 | unit-tests:
35 | $(DOCKER_COMPOSE) run php $(PHP) vendor/bin/atoum
36 |
37 | .PHONY: tests
38 | tests: functional-tests unit-tests
39 |
--------------------------------------------------------------------------------
/server/app.js:
--------------------------------------------------------------------------------
1 | var CONFIGURATION_FILE = './configuration.json';
2 |
3 | var express = require('express');
4 | var path = require('path');
5 | var bodyParser = require('body-parser');
6 |
7 | var services = require('./javascripts/services');
8 | var repositories = require('./javascripts/repositories');
9 | var routes = require('./javascripts/routes');
10 | var config = require('./javascripts/config');
11 |
12 |
13 | var configuration = new config.Configuration(CONFIGURATION_FILE);
14 | var sellers = new repositories.Sellers();
15 | var sellerService = new services.SellerService(sellers, configuration);
16 | var orderService = new services.OrderService(configuration);
17 | var dispatcher = new services.Dispatcher(sellerService, orderService, configuration);
18 |
19 | var app = express();
20 |
21 | app.use(bodyParser.json());
22 | app.use(bodyParser.urlencoded({ extended: false }));
23 | app.use('/', routes(sellerService, dispatcher));
24 | app.use(express.static(path.join(__dirname, 'public')));
25 |
26 | configuration.watch(function() {}, false, 500);
27 | dispatcher.startBuying(1);
28 |
29 | module.exports = app;
30 |
--------------------------------------------------------------------------------
/clients/kotlin/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | plugins {
3 | id "org.jetbrains.kotlin.jvm" version "1.3.61"
4 | id 'org.jetbrains.kotlin.plugin.serialization' version '1.3.60'
5 |
6 | id 'java'
7 | id 'application'
8 | id 'idea'
9 | }
10 |
11 | repositories {
12 | jcenter()
13 | }
14 |
15 | group 'extreme-carpaccio'
16 | version '1.0-SNAPSHOT'
17 |
18 | dependencies {
19 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
20 | implementation "org.jetbrains.kotlin:kotlin-reflect"
21 | implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0"
22 |
23 | implementation "io.ktor:ktor-server-netty:1.3.0"
24 | implementation "io.ktor:ktor-serialization:1.3.0"
25 | implementation "org.slf4j:slf4j-simple:1.7.30"
26 |
27 | testImplementation "org.jetbrains.kotlin:kotlin-test"
28 | testImplementation "io.ktor:ktor-server-test-host:1.3.0"
29 | testImplementation "org.mockito:mockito-core:3.2.4"
30 | }
31 |
32 | application {
33 | mainClassName = 'xcarpaccio.MyServerKt'
34 | }
35 |
36 | idea.module {
37 | downloadSources = true
38 | downloadJavadoc = true
39 | }
40 |
--------------------------------------------------------------------------------
/clients/javascript/express/server.js:
--------------------------------------------------------------------------------
1 | var http = require('http');
2 | var express = require('express');
3 | var morgan = require('morgan');
4 | var bodyParser = require('body-parser');
5 | var routes = require('./lib/routes');
6 |
7 | module.exports = Server;
8 |
9 | function Server(doLogRequests) {
10 | var app = express();
11 | app.set('json spaces', 2);
12 |
13 | if (doLogRequests) {
14 | app.use(morgan('dev'));
15 | }
16 | app.use(bodyParser.json());
17 |
18 | app.get('/status', function (req, res) {
19 | res.json({ up: true })
20 | })
21 |
22 | app.post('/order', function (req, res, next) {
23 | routes.order(req, res, next);
24 | });
25 | app.post('/feedback', function (req, res, next) {
26 | routes.feedback(req, res, next);
27 | });
28 |
29 | var server = http.createServer(app);
30 | server.start = server.listen.bind(server, process.env.PORT || 3000);
31 | server.stop = server.close.bind(server);
32 | return server;
33 | }
34 |
35 |
36 | if (!module.parent) {
37 | var server = new Server(true);
38 | server.start(function () {
39 | console.log('server listening on port', server.address().port);
40 | });
41 | }
42 |
--------------------------------------------------------------------------------
/clients/rust/src/main.rs:
--------------------------------------------------------------------------------
1 | #[macro_use] extern crate nickel;
2 | extern crate rustc_serialize;
3 |
4 | use std::collections::BTreeMap;
5 |
6 | use nickel::{
7 | Nickel, Request, HttpRouter
8 | };
9 |
10 | use rustc_serialize::json::{Json, ToJson};
11 |
12 | #[derive(RustcDecodable, RustcEncodable)]
13 | struct Res {
14 | res: String,
15 | }
16 |
17 | impl ToJson for Res {
18 | fn to_json(&self) -> Json {
19 | let mut map = BTreeMap::new();
20 | map.insert("pong".to_string(), self.res.to_json());
21 | Json::Object(map)
22 | }
23 | }
24 |
25 |
26 | fn main() {
27 | let mut server = Nickel::new();
28 |
29 | server.utilize(middleware! { |request|
30 | println!("logging request: {:?}", request.origin.uri);
31 | });
32 |
33 |
34 | let mut router = Nickel::router();
35 |
36 | router.get("/hello", middleware!("hello"));
37 | router.get("/ping", middleware! {
38 | let res = Res {
39 | res: "pong".to_string()
40 | };
41 | res.to_json()
42 | });
43 |
44 | router.get("**", middleware!("Hello All"));
45 |
46 | server.utilize(router);
47 | server.listen("127.0.0.1:6767");
48 | }
49 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/src/xcarpaccio/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
4 | "Microsoft.AspNetCore.Owin": "1.1.0",
5 | "Microsoft.AspNetCore.Mvc": "1.1.0",
6 | "Microsoft.AspNetCore.Routing": "1.1.0",
7 | "Microsoft.Extensions.Configuration.Json": "1.1.0",
8 | "Microsoft.Extensions.Logging": "1.1.0",
9 | "Microsoft.Extensions.Logging.Console": "1.1.0",
10 | "Microsoft.Extensions.Logging.Debug": "1.1.0",
11 | "Microsoft.AspNetCore.Diagnostics":"1.1.0"
12 | },
13 |
14 |
15 |
16 | "frameworks": {
17 | "netcoreapp1.1": {
18 | "dependencies": {
19 | "Microsoft.NETCore.App": {
20 | "type": "platform",
21 | "version": "1.1.0"
22 | }
23 | },
24 | "imports": "dnxcore50"
25 | }
26 | },
27 |
28 | "buildOptions": {
29 | "debugType": "portable",
30 | "emitEntryPoint": true,
31 | "preserveCompilationContext": true
32 | },
33 |
34 | "tooling": {
35 | "defaultNamespace": "XCarpaccio"
36 | },
37 |
38 | "commands": {
39 | "web": "Microsoft.AspNet.Server.Kestrel --server.urls=http://*:60000"
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/clients/javascript/node-plain/specs/server_spec.js:
--------------------------------------------------------------------------------
1 | var conf = require('../conf'),
2 | request = require('request'),
3 | server = require('../lib/server'),
4 | serverInstance;
5 |
6 | describe('Default server', function () {
7 | beforeEach(function() {
8 | serverInstance = server.start(conf, function() {
9 | return {total:500};
10 | });
11 | });
12 | afterEach(function() {
13 | serverInstance.close();
14 | });
15 |
16 | it('should handle feedback', function(done) {
17 | var feedback = request('http://' + conf.host + ':' + conf.port + '/feedback', function (error, response) {
18 | expect(response.statusCode).toBe(204);
19 | done();
20 | });
21 | feedback.write('{type: "INFO", content: "this is my precious feedback"}');
22 | });
23 |
24 | it('should handle order', function(done) {
25 | var order = request('http://' + conf.host + ':' + conf.port + '/order', function (error, response, body) {
26 | expect(response.statusCode).toBe(200);
27 | expect(body).toBe('{total:0}');
28 | done();
29 | });
30 | order.write('{prices: [], quantities: [], country: "DE", reduction: "STANDARD"}');
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/clients/typescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "extreme-carpaccio-client-typescript",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "jest --watch",
8 | "start-watch": "nodemon --watch 'src/**/*' --ignore 'src/**/*.spec.ts' -e ts,tsx --exec ts-node ./src/server.ts",
9 | "start": "ts-node ./src/server.ts"
10 | },
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "koa": "^2.7.0",
15 | "koa-bodyparser": "^4.2.1",
16 | "koa-router": "^7.4.0"
17 | },
18 | "devDependencies": {
19 | "@types/jest": "^23.3.13",
20 | "@types/koa": "^2.0.48",
21 | "@types/koa-bodyparser": "^4.2.1",
22 | "@types/koa-router": "^7.0.39",
23 | "jest": "^24.1.0",
24 | "nodemon": "^1.18.9",
25 | "ts-jest": "^23.10.5",
26 | "ts-node": "^8.0.2",
27 | "typescript": "^3.3.1"
28 | },
29 | "jest": {
30 | "transform": {
31 | ".(ts|tsx)": "/node_modules/ts-jest/preprocessor.js"
32 | },
33 | "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
34 | "moduleFileExtensions": [
35 | "ts",
36 | "tsx",
37 | "js"
38 | ]
39 | }
40 | }
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/application.rb:
--------------------------------------------------------------------------------
1 | require_relative 'boot'
2 |
3 | require "rails"
4 | # Pick the frameworks you want:
5 | require "active_model/railtie"
6 | require "active_job/railtie"
7 | require "active_record/railtie"
8 | require "action_controller/railtie"
9 | require "action_mailer/railtie"
10 | require "action_view/railtie"
11 | require "action_cable/engine"
12 | # require "sprockets/railtie"
13 | require "rails/test_unit/railtie"
14 |
15 | # Require the gems listed in Gemfile, including any gems
16 | # you've limited to :test, :development, or :production.
17 | Bundler.require(*Rails.groups)
18 |
19 | module RubyRails
20 | class Application < Rails::Application
21 | # Settings in config/environments/* take precedence over those specified here.
22 | # Application configuration should go into files in config/initializers
23 | # -- all .rb files in that directory are automatically loaded.
24 |
25 | # Only loads a smaller set of middleware suitable for API only apps.
26 | # Middleware like session, flash, cookies can be added back manually.
27 | # Skip views, helpers and assets when generating a new resource.
28 | config.api_only = true
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/clients/python/flask-server/client/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | Carpaccio server using Flask.
3 | To start the kata, complete the order() function
4 | """
5 |
6 | from flask import Flask, request, jsonify
7 | import re
8 |
9 | app = Flask(__name__)
10 |
11 | #Main function of the kata
12 | @app.route("/order", methods=['POST'])
13 | def order():
14 | order = request.get_json()
15 |
16 | #TODO YOUR CODE HERE
17 |
18 | result = {'total': 1000}
19 | # You should probably comment this line before you register your client
20 | return jsonify(result)
21 |
22 | #Server's feedback to your work.
23 | @app.route("/feedback", methods=['POST'])
24 | def feedback():
25 | feedback = request.get_json()
26 |
27 | #TODO HERE YOU RECEIVE WHAT THE SERVER THINKS ABOUT YOUR WORK
28 |
29 | return jsonify(request.get_json())
30 |
31 | # Returns 'hello world' on any get request
32 | @app.route("/", methods=['GET'])
33 | @app.route("/", methods=['GET'])
34 | def index2(path=''):
35 | return "hello world"
36 |
37 | @app.route("/ping", methods=['POST'])
38 | def ping():
39 | return "pong"
40 | # Subject of the Kata.
41 |
42 | def start_server():
43 | app.run(host='0.0.0.0',
44 | port=int("5000"))
45 |
--------------------------------------------------------------------------------
/clients/java/java-httpserver/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | pom.xml.tag
3 | pom.xml.releaseBackup
4 | pom.xml.versionsBackup
5 | pom.xml.next
6 | release.properties
7 |
8 | *.class
9 |
10 | # Package Files #
11 | *.jar
12 | *.war
13 | *.ear
14 |
15 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
16 | hs_err_pid*
17 |
18 | *.pydevproject
19 | .metadata
20 | .gradle
21 | bin/
22 | tmp/
23 | *.tmp
24 | *.bak
25 | *.swp
26 | *~.nib
27 | local.properties
28 | .settings/
29 | .loadpath
30 |
31 | # Eclipse Core
32 | .project
33 |
34 | # External tool builders
35 | .externalToolBuilders/
36 |
37 | # Locally stored "Eclipse launch configurations"
38 | *.launch
39 |
40 | # CDT-specific
41 | .cproject
42 |
43 | # JDT-specific (Eclipse Java Development Tools)
44 | .classpath
45 |
46 | # PDT-specific
47 | .buildpath
48 |
49 | # sbteclipse plugin
50 | .target
51 |
52 | # TeXlipse plugin
53 | .texlipse
54 |
55 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
56 |
57 | *.iml
58 |
59 | ## Directory-based project format:
60 | .idea/
61 |
62 | ## File-based project format:
63 | *.ipr
64 | *.iws
65 |
66 | ## Plugin-specific files:
67 |
68 | # IntelliJ
69 | out/
70 |
71 | # mpeltonen/sbt-idea plugin
72 | .idea_modules/
73 |
74 |
--------------------------------------------------------------------------------
/clients/php/native/tests/units/src/ExtremeCarpaccio/Model/Order.php:
--------------------------------------------------------------------------------
1 | given(
13 | $country = uniqid('country'),
14 | $product = new \mock\ExtremeCarpaccio\Model\OrderProductInterface,
15 | $this->calling($product)->getUnitPrice = mt_rand(),
16 | $this->calling($product)->getQuantity = mt_rand(),
17 | $products = [
18 | $product
19 | ],
20 | $reductionType = uniqid('reductionType')
21 | )
22 | ->if(
23 | $this->newTestedInstance($country, $products, $reductionType)
24 | )
25 | ->then
26 | ->object($this->testedInstance)->isInstanceOf(\ExtremeCarpaccio\Model\OrderInterface::class)
27 | ->string($this->testedInstance->getCountry())->isEqualTo($country)
28 | ->array($this->testedInstance->getProducts())->isIdenticalTo($products)
29 | ->string($this->testedInstance->getReductionType())->isEqualTo($reductionType)
30 | ;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/clients/php/silex/tests/units/src/ExtremeCarpaccio/Model/Order.php:
--------------------------------------------------------------------------------
1 | given(
13 | $country = uniqid('country'),
14 | $product = new \mock\ExtremeCarpaccio\Model\OrderProductInterface,
15 | $this->calling($product)->getUnitPrice = mt_rand(),
16 | $this->calling($product)->getQuantity = mt_rand(),
17 | $products = [
18 | $product
19 | ],
20 | $reductionType = uniqid('reductionType')
21 | )
22 | ->if(
23 | $this->newTestedInstance($country, $products, $reductionType)
24 | )
25 | ->then
26 | ->object($this->testedInstance)->isInstanceOf(\ExtremeCarpaccio\Model\OrderInterface::class)
27 | ->string($this->testedInstance->getCountry())->isEqualTo($country)
28 | ->array($this->testedInstance->getProducts())->isIdenticalTo($products)
29 | ->string($this->testedInstance->getReductionType())->isEqualTo($reductionType)
30 | ;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/server/javascripts/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | var http = require('http')
4 |
5 | var Utils = function (_http) {
6 | this.http = _http || http
7 | }
8 |
9 | Utils.prototype = {
10 | stringify: function (object) {
11 | return JSON.stringify(object)
12 | },
13 |
14 | jsonify: function (string) {
15 | try {
16 | return JSON.parse(string)
17 | } catch (exception) {
18 | throw new Error('The object "' + string + '" is not a valid json object')
19 | }
20 | },
21 |
22 | fixPrecision: function (number, precision) {
23 | return parseFloat(number.toFixed(precision))
24 | },
25 |
26 | post: function (hostname, port, path, body, onSuccess, onError) {
27 | var bodyStringified = this.stringify(body)
28 | var options = {
29 | hostname: hostname,
30 | port: port,
31 | path: (path || '').replace('//', '/'),
32 | method: 'POST',
33 | headers: {
34 | 'Content-Type': 'application/json',
35 | Accept: 'application/json',
36 | 'Content-Length': bodyStringified.length
37 | }
38 | }
39 | var request = this.http.request(options, onSuccess)
40 | request.on('error', onError || function () {})
41 | request.write(bodyStringified)
42 | request.end()
43 | }
44 | }
45 |
46 | module.exports = new Utils()
47 |
--------------------------------------------------------------------------------
/clients/kotlin/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | pom.xml.tag
3 | pom.xml.releaseBackup
4 | pom.xml.versionsBackup
5 | pom.xml.next
6 | release.properties
7 |
8 | *.class
9 |
10 | # Package Files #
11 | *.jar
12 | !gradle/wrapper/gradle-wrapper.jar
13 | *.war
14 | *.ear
15 |
16 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
17 | hs_err_pid*
18 |
19 | *.pydevproject
20 | .metadata
21 | .gradle
22 | bin/
23 | tmp/
24 | *.tmp
25 | *.bak
26 | *.swp
27 | *~.nib
28 | local.properties
29 | .settings/
30 | .loadpath
31 |
32 | # Eclipse Core
33 | .project
34 |
35 | # External tool builders
36 | .externalToolBuilders/
37 |
38 | # Locally stored "Eclipse launch configurations"
39 | *.launch
40 |
41 | # CDT-specific
42 | .cproject
43 |
44 | # JDT-specific (Eclipse Java Development Tools)
45 | .classpath
46 |
47 | # PDT-specific
48 | .buildpath
49 |
50 | # sbteclipse plugin
51 | .target
52 |
53 | # TeXlipse plugin
54 | .texlipse
55 |
56 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
57 |
58 | *.iml
59 |
60 | ## Directory-based project format:
61 | .idea/
62 |
63 | ## File-based project format:
64 | *.ipr
65 | *.iws
66 |
67 | ## Plugin-specific files:
68 |
69 | # IntelliJ
70 | out/
71 | build/
72 | classes/
73 |
74 | # mpeltonen/sbt-idea plugin
75 | .idea_modules/
76 |
77 |
--------------------------------------------------------------------------------
/clients/groovy/groovy-ratpack/src/test/groovy/ExtremeCarpaccioSpec.groovy:
--------------------------------------------------------------------------------
1 | import ratpack.groovy.test.GroovyRatpackMainApplicationUnderTest
2 | import ratpack.http.Status;
3 | import ratpack.http.client.RequestSpec;
4 | import ratpack.test.ServerBackedApplicationUnderTest
5 | import ratpack.test.http.TestHttpClient
6 | import spock.lang.Specification
7 |
8 |
9 | class ExtremeCarpaccioSpec extends Specification {
10 |
11 | ServerBackedApplicationUnderTest aut = new GroovyRatpackMainApplicationUnderTest()
12 | @Delegate TestHttpClient client = TestHttpClient.testHttpClient(aut)
13 |
14 |
15 | def "a GET on /hello returns 'Hello world!"() {
16 | when:
17 | get("hello")
18 |
19 | then:
20 | response.statusCode == 200
21 | response.body.text == "Hello world!"
22 | }
23 |
24 | def "a POST request on /ping returns 'pong'"() {
25 | when:
26 | post("ping")
27 |
28 | then:
29 | response.statusCode == 200
30 | response.body.text == "pong"
31 |
32 | }
33 |
34 | def "index accepts JSON body"() {
35 | when:
36 | requestSpec { RequestSpec requestSpec ->
37 | requestSpec.body.type("application/json")
38 | requestSpec.body.text('{ "foo": "bar" }')
39 | }
40 |
41 | post("/")
42 |
43 | then:
44 | response.statusCode == 200
45 | response.body.text == "pong"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/server/javascripts/services/reduction.js:
--------------------------------------------------------------------------------
1 | var _ = require('lodash')
2 |
3 | function PayThePriceReduction () {
4 | this.name = 'PAY THE PRICE'
5 | this.apply = function (amount) {
6 | return amount
7 | }
8 | }
9 |
10 | function HalfPriceReduction () {
11 | this.name = 'HALF PRICE'
12 | this.apply = function (amount) {
13 | return amount / 2
14 | }
15 | }
16 |
17 | function ReductionStep (sum, reduction) {
18 | this.sum = sum
19 | this.reduction = reduction
20 | }
21 |
22 | function StandardReduction (sum, reduction) {
23 | this.name = 'STANDARD'
24 | var reductions = [
25 | new ReductionStep(50000, 0.15),
26 | new ReductionStep(10000, 0.10),
27 | new ReductionStep(7000, 0.07),
28 | new ReductionStep(5000, 0.05),
29 | new ReductionStep(1000, 0.03)
30 | ]
31 |
32 | this.apply = function (amount) {
33 | return amount * (1 - this.reductionFor(amount))
34 | }
35 | this.reductionFor = function (total) {
36 | var reduction = _.result(_.find(reductions, function (reduc) { return reduc.sum <= total }), 'reduction')
37 | if (reduction === undefined) {
38 | return 0
39 | }
40 | return reduction
41 | }
42 | }
43 |
44 | exports.STANDARD = new StandardReduction()
45 | exports.PAY_THE_PRICE = new PayThePriceReduction()
46 | exports.HALF_PRICE = new HalfPriceReduction()
47 |
--------------------------------------------------------------------------------
/clients/f#/extreme-carpaccio.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2013
3 | VisualStudioVersion = 12.0.40629.0
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{E3B27B6E-D10F-4B36-A712-914C0FC682E7}"
6 | ProjectSection(SolutionItems) = preProject
7 | paket.dependencies = paket.dependencies
8 | EndProjectSection
9 | EndProject
10 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "carpaccio-client", "carpaccio-client\carpaccio-client.fsproj", "{7FB4BC27-7497-475F-BEDA-4B298BA08ED1}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {7FB4BC27-7497-475F-BEDA-4B298BA08ED1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {7FB4BC27-7497-475F-BEDA-4B298BA08ED1}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {7FB4BC27-7497-475F-BEDA-4B298BA08ED1}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {7FB4BC27-7497-475F-BEDA-4B298BA08ED1}.Release|Any CPU.Build.0 = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(SolutionProperties) = preSolution
24 | HideSolutionNode = FALSE
25 | EndGlobalSection
26 | EndGlobal
27 |
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | extreme-carpaccio
6 | java-fluent-http
7 | jar
8 | 1.0-SNAPSHOT
9 | java-fluent-http
10 |
11 |
12 | UTF-8
13 | UTF-8
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 |
21 | net.code-story
22 | http
23 | 2.97
24 |
25 |
26 | junit
27 | junit
28 | 4.12
29 | test
30 |
31 |
32 | com.jayway.restassured
33 | rest-assured
34 | 2.4.0
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": ".NET Core Launch (web)",
6 | "type": "coreclr",
7 | "request": "launch",
8 | "preLaunchTask": "build",
9 | "program": "${workspaceRoot}\\src\\xcarpaccio\\bin\\Debug\\netcoreapp1.1\\xcarpaccio.dll",
10 | "args": [],
11 | "cwd": "${workspaceRoot}",
12 | "stopAtEntry": false,
13 | "internalConsoleOptions": "openOnSessionStart",
14 | "launchBrowser": {
15 | "enabled": true,
16 | "args": "${auto-detect-url}",
17 | "windows": {
18 | "command": "cmd.exe",
19 | "args": "/C start ${auto-detect-url}"
20 | },
21 | "osx": {
22 | "command": "open"
23 | },
24 | "linux": {
25 | "command": "xdg-open"
26 | }
27 | },
28 | "env": {
29 | "ASPNETCORE_ENVIRONMENT": "Development"
30 | },
31 | "sourceFileMap": {
32 | "/Views": "${workspaceRoot}/Views"
33 | }
34 | },
35 | {
36 | "name": ".NET Core Attach",
37 | "type": "coreclr",
38 | "request": "attach",
39 | "processId": "${command.pickProcess}"
40 | }
41 | ]
42 | }
--------------------------------------------------------------------------------
/clients/c#/dnx-csharp/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": ".NET Core Launch (web)",
6 | "type": "coreclr",
7 | "request": "launch",
8 | "preLaunchTask": "build",
9 | "program": "${workspaceRoot}\\src\\xcarpaccio\\bin\\Debug\\netcoreapp1.0\\xcarpaccio.dll",
10 | "args": [],
11 | "cwd": "${workspaceRoot}",
12 | "stopAtEntry": false,
13 | "internalConsoleOptions": "openOnSessionStart",
14 | "launchBrowser": {
15 | "enabled": true,
16 | "args": "${auto-detect-url}",
17 | "windows": {
18 | "command": "cmd.exe",
19 | "args": "/C start ${auto-detect-url}"
20 | },
21 | "osx": {
22 | "command": "open"
23 | },
24 | "linux": {
25 | "command": "xdg-open"
26 | }
27 | },
28 | "env": {
29 | "ASPNETCORE_ENVIRONMENT": "Development"
30 | },
31 | "sourceFileMap": {
32 | "/Views": "${workspaceRoot}/Views"
33 | }
34 | },
35 | {
36 | "name": ".NET Core Attach",
37 | "type": "coreclr",
38 | "request": "attach",
39 | "processId": "${command.pickProcess}"
40 | }
41 | ]
42 | }
--------------------------------------------------------------------------------
/clients/scala/src/main/scala/main/Server.scala:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import akka.http.scaladsl.marshalling.ToResponseMarshallable
4 | import akka.http.scaladsl.model.ContentTypes.`application/json`
5 | import akka.http.scaladsl.model.HttpEntity
6 | import akka.http.scaladsl.server.{HttpApp, Route}
7 | import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._
8 | import io.circe.generic.auto._
9 |
10 | case class Order(prices: Seq[Float], quantities: Seq[Int], country: String)
11 |
12 | case class Result(total: Float)
13 |
14 | case class Feedback(`type`: String, content: String)
15 |
16 | object Server extends HttpApp with App {
17 |
18 | type ProcessOrder = Order => Option[Float]
19 |
20 | lazy val process: ProcessOrder = {
21 | // TODO To implement
22 | order => Some(0.0f)
23 | }
24 |
25 | override def routes: Route =
26 | path("order") {
27 | post {
28 | entity(as[Order]) { order =>
29 | complete {
30 | println("Request received : " + order)
31 |
32 | val total = process(order)
33 |
34 | Result(total.getOrElse(0f))
35 | }
36 | }
37 | }
38 | } ~
39 | path("feedback") {
40 | post {
41 | entity(as[Feedback]) { feedback =>
42 | complete {
43 | println("Feedback received : " + feedback)
44 | ""
45 | }
46 | }
47 | }
48 | }
49 |
50 | startServer(host = "0.0.0.0", port = 9000)
51 |
52 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016, Diego Lemos de Resende
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5 |
6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 |
8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 |
10 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11 |
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13 |
--------------------------------------------------------------------------------
/clients/java/java-springboot/src/main/java/xcarpaccio/WebController.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import org.springframework.http.HttpStatus;
4 | import org.springframework.web.bind.annotation.RequestBody;
5 | import org.springframework.web.bind.annotation.RequestMapping;
6 | import org.springframework.web.bind.annotation.RequestMethod;
7 | import org.springframework.web.bind.annotation.RestController;
8 | import org.springframework.web.server.ResponseStatusException;
9 |
10 | @RestController
11 | public class WebController {
12 |
13 | @RequestMapping(value = "/order", method = RequestMethod.POST)
14 | public Amount answerQuote(@RequestBody Order order) {
15 | System.out.println("Order received: " + order.toString());
16 | if (order.prices.length == 0)
17 | return new Amount(computeAmount(order));
18 |
19 | // Throw a 404 if you don't want to respond to an order, without penalty
20 | throw new ResponseStatusException(HttpStatus.NOT_FOUND, "cannot answer");
21 | }
22 |
23 | @RequestMapping(value = "/feedback", method = RequestMethod.POST)
24 | public void logFeedback(@RequestBody FeedbackMessage message) {
25 | System.out.println("feedback received: " + message.toString());
26 | }
27 |
28 | @RequestMapping(value = "/ping", method = RequestMethod.GET)
29 | public String ping() {
30 | System.out.println("ping received");
31 | return "pong";
32 | }
33 |
34 | Double computeAmount(Order order) {
35 | return 0.0;
36 | }
37 | }
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | git_source(:github) do |repo_name|
4 | repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
5 | "https://github.com/#{repo_name}.git"
6 | end
7 |
8 |
9 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
10 | gem 'rails', '~> 5.0.2'
11 | # Use sqlite3 as the database for Active Record
12 | gem 'sqlite3'
13 | # Use Puma as the app server
14 | gem 'puma', '~> 3.0'
15 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
16 | # gem 'jbuilder', '~> 2.5'
17 | # Use Redis adapter to run Action Cable in production
18 | # gem 'redis', '~> 3.0'
19 | # Use ActiveModel has_secure_password
20 | # gem 'bcrypt', '~> 3.1.7'
21 |
22 | # Use Capistrano for deployment
23 | # gem 'capistrano-rails', group: :development
24 |
25 | # Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
26 | # gem 'rack-cors'
27 |
28 | group :development, :test do
29 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console
30 | gem 'byebug', platform: :mri
31 | end
32 |
33 | group :development do
34 | gem 'listen', '~> 3.0.5'
35 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
36 | gem 'spring'
37 | gem 'spring-watcher-listen', '~> 2.0.0'
38 | end
39 |
40 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
41 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
42 |
--------------------------------------------------------------------------------
/clients/c#/nancy/NancyApplication1/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("NancyApplication1")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("NancyApplication1")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("cc3adbca-2baf-46d6-96f3-5438dfe2189e")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/clients/c#/nancy/extreme-carpaccio.client/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("katazon.client")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("katazon.client")]
13 | [assembly: AssemblyCopyright("Copyright © 2013")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("cc3adbca-2baf-46d6-96f3-5438dfe2189e")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/clients/haskell/src/Main.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE OverloadedStrings #-}
2 | import Data.Aeson
3 | import Data.Text
4 | import Data.Monoid
5 | import Control.Applicative ((<$>), (<*>))
6 | import Control.Monad
7 | import Control.Monad.Trans (liftIO)
8 | import Web.Scotty
9 | import Model
10 |
11 | instance FromJSON Order where
12 | parseJSON (Object v) =
13 | Order <$>
14 | (v .: "prices") <*>
15 | (v .: "quantities") <*>
16 | (v .: "country") <*>
17 | (v .: "reduction")
18 |
19 | data Feedback = Feedback
20 | { feedbackType :: Text
21 | , content :: Text
22 | } deriving (Show)
23 |
24 | instance FromJSON Feedback where
25 | parseJSON (Object v) =
26 | Feedback <$>
27 | (v .: "type") <*>
28 | (v .: "content")
29 | parseJSON _ = mzero
30 |
31 | instance ToJSON Quantity where
32 | toJSON (Quantity total) = object [ "total" .= total]
33 |
34 | main :: IO ()
35 | main = scotty 8000 $ do
36 |
37 | get "/" $ do
38 | html "Hello extreme-carpaccio!"
39 |
40 | post "/feedback" $ do
41 | b <- body
42 | f <- case decode b of
43 | Just x -> return x
44 | Nothing -> fail "no feedback"
45 |
46 | liftIO $ print $ show (f :: Feedback)
47 | html "Thanx for this very usefull feedback"
48 |
49 | post "/order" $ do
50 | b <- body
51 | o <- case decode b of
52 | Just x -> return x
53 | Nothing -> fail "no order"
54 |
55 | liftIO $ print $ show (o :: Order)
56 |
57 | let answer = computeTotal o
58 |
59 | liftIO $ print $ show answer
60 |
61 | raw $ encode $ answer
62 |
--------------------------------------------------------------------------------
/server/javascripts/routes.js:
--------------------------------------------------------------------------------
1 | var express = require('express')
2 | var _ = require('lodash')
3 |
4 | module.exports = function (sellerService, dispatcher) {
5 | var router = express.Router()
6 | var OK = 200
7 | var BAD_REQUEST = 400
8 | var UNAUTHORIZED = 401
9 |
10 | router.get('/sellers', function (request, response) {
11 | // seller view is returned, to prevent any confidential information leaks
12 | var sellerViews = _.map(sellerService.allSellers(), function (seller) {
13 | return {
14 | cash: seller.cash,
15 | name: seller.name,
16 | online: seller.online
17 | }
18 | })
19 | response.status(OK).send(sellerViews)
20 | })
21 |
22 | router.get('/sellers/history', function (request, response) {
23 | var chunk = request.query.chunk || 10
24 | response.status(OK).send(sellerService.getCashHistory(chunk))
25 | })
26 |
27 | router.post('/seller', function (request, response) {
28 | var sellerName = request.body.name
29 | var sellerUrl = request.body.url
30 | var sellerPwd = request.body.password
31 |
32 | if (_.isEmpty(sellerName) || _.isEmpty(sellerUrl) || _.isEmpty(sellerPwd)) {
33 | response.status(BAD_REQUEST).send({ message: 'missing name, password or url' })
34 | } else if (sellerService.isAuthorized(sellerName, sellerPwd)) {
35 | sellerService.register(sellerUrl, sellerName, sellerPwd)
36 | response.status(OK).end()
37 | } else {
38 | response.status(UNAUTHORIZED).send({ message: 'invalid name or password' })
39 | }
40 | })
41 |
42 | return router
43 | }
44 |
--------------------------------------------------------------------------------
/clients/java/java-spark/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | extreme-carpaccio
6 | extreme-carpaccio-spark
7 | 1.0-SNAPSHOT
8 |
9 |
10 | 1.8
11 | 1.8
12 | UTF-8
13 |
14 |
15 |
16 |
17 | com.sparkjava
18 | spark-core
19 | 2.2
20 |
21 |
22 |
23 | com.google.code.gson
24 | gson
25 | 2.3.1
26 |
27 |
28 |
29 | org.assertj
30 | assertj-core
31 | 3.0.0
32 | test
33 |
34 |
35 |
36 | junit
37 | junit
38 | 4.12
39 | test
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/clients/go/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "io/ioutil"
6 | "log"
7 | "net/http"
8 | "os"
9 |
10 | "fmt"
11 | )
12 |
13 | type Order struct {
14 | Prices []float32
15 | Quantities []int
16 | Country string
17 | Reduction string
18 | }
19 |
20 | type Reply struct {
21 | Total float32 `json:"total"`
22 | }
23 |
24 | func main() {
25 | http.HandleFunc("/order", handler)
26 | http.HandleFunc("/feedback", func(rw http.ResponseWriter, req *http.Request) {
27 | defer req.Body.Close()
28 |
29 | body, err := ioutil.ReadAll(req.Body)
30 | if err != nil {
31 | fmt.Printf("error reading body: %v\n", err)
32 | rw.WriteHeader(204)
33 | return
34 | }
35 |
36 | fmt.Printf("Feedback: %s\n", body)
37 |
38 | rw.WriteHeader(200)
39 | })
40 |
41 | err := http.ListenAndServe(fmt.Sprintf(":%s", getPort()), nil)
42 | if err != nil {
43 | log.Fatal("Listen and serve:", err)
44 | }
45 | }
46 |
47 | func handler(rw http.ResponseWriter, req *http.Request) {
48 | defer req.Body.Close()
49 |
50 | body, err := ioutil.ReadAll(req.Body)
51 | if err != nil {
52 | fmt.Printf("error reading body: %v\n", err)
53 | rw.WriteHeader(204)
54 | return
55 | }
56 |
57 | var order Order
58 | json.Unmarshal(body, &order)
59 |
60 | fmt.Printf("Got order: %#v\n", order)
61 |
62 | rw.Header().Add("Content-Type", "application/json")
63 | rw.WriteHeader(200)
64 | // encoder := json.NewEncoder(rw)
65 | // encoder.Encode(Reply{0})
66 | }
67 |
68 | func getPort() string {
69 | port := os.Getenv("PORT")
70 | if port == "" {
71 | return "9000"
72 | }
73 | return port
74 | }
75 |
--------------------------------------------------------------------------------
/clients/f#/carpaccio-client/carpaccio-client.fs:
--------------------------------------------------------------------------------
1 | module CarpaccioClient
2 | open Suave
3 | open Suave.Filters
4 | open Suave.Operators
5 | open Suave.Successful
6 | open System.Net
7 | open System.Text
8 | open Newtonsoft.Json
9 | open CarpaccioModel
10 |
11 | let decodeUTF8ContentToString (request:HttpRequest) =
12 | Encoding.UTF8.GetString request.rawForm
13 |
14 | let deserialize<'a> (s:string) : 'a option =
15 | try
16 | Some (JsonConvert.DeserializeObject<'a> s)
17 | with
18 | _ -> printfn "ERROR can't deserialize : %s" s
19 | None
20 |
21 | let handleFeedback (r:HttpRequest) =
22 | let feedback = decodeUTF8ContentToString >> deserialize <| r
23 | printfn "Feedback -> %A" <| feedback
24 | OK ""
25 |
26 | let handleOrder (r:HttpRequest) =
27 | let order = decodeUTF8ContentToString >> deserialize <| r
28 | printfn "order received -> %A" order
29 | OK ""
30 |
31 | let app =
32 | choose [
33 | GET >=> choose
34 | [ path "/order" >=> OK "Hello World!"
35 | path "/ping" >=> OK "pong" ]
36 | POST >=> choose
37 | [ path "/order" >=> request ( fun r -> r |> handleOrder )
38 | path "/feedback" >=> request (fun r -> r |> handleFeedback ) ]
39 | ]
40 |
41 | let port = Sockets.Port.Parse <| "8080"
42 | let ip = IPAddress.Any
43 |
44 | let serverConfig =
45 | { defaultConfig with
46 | bindings = [ HttpBinding.mk HTTP ip port ]
47 | }
48 |
49 | []
50 | let main argv =
51 | printfn "Starting server ..."
52 | startWebServer serverConfig app
53 | 0
54 |
--------------------------------------------------------------------------------
/clients/php/native/tests/functionals/casperjs/03-order.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | casper.test.begin('/order : Managed data', function suite(test) {
4 | var managedOrders = [
5 | {
6 | order: {
7 | 'prices[]': [15.99],
8 | 'quantities[]': [1],
9 | 'country': 'ES',
10 | 'reduction': 'STANDARD'
11 | },
12 | expected: {
13 | value: 19.03
14 | }
15 | },
16 | {
17 | order: {
18 | 'prices[]': [4.1,8.03,86.83,65.62,44.82],
19 | 'quantities[]': [10,3,5,4,5],
20 | 'country': 'AT',
21 | 'reduction':'STANDARD'
22 | },
23 | expected: {
24 | value: 1166.62
25 | }
26 | }
27 | ];
28 |
29 | casper.each(managedOrders, function(self, orderData) {
30 | self.thenOpen('http://project.loc/order', {
31 | method: 'post',
32 | data: orderData.order
33 | }).then(function(response) {
34 | casper.test.assertHttpStatus(200);
35 | casper.test.assertMatch(
36 | response.headers.get('Content-Type'),
37 | new RegExp('|^application/json|', 'i'),
38 | 'Content-Type match the expected value'
39 | );
40 | var content = JSON.parse(this.getPageContent());
41 | casper.test.assertEquals(content.total, orderData.expected.value, 'Order total computation equals the expected value');
42 | });
43 | }).run(function () {
44 | test.done();
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/src/main/java/xcarpaccio/WebConfiguration.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import net.codestory.http.Configuration;
4 | import net.codestory.http.payload.Payload;
5 | import net.codestory.http.routes.Routes;
6 |
7 | public class WebConfiguration implements Configuration {
8 |
9 | private final Logger logger = new Logger();
10 |
11 | @Override
12 | public void configure(Routes routes) {
13 | routes.
14 | get("/ping", "pong").
15 | post("/feedback", (context) -> {
16 | Message message = context.extract(Message.class);
17 | logger.log(message.type + ": " + message.content);
18 | return new Payload(204);
19 | }).
20 | post("/order", (context -> {
21 | String method = context.method();
22 | String uri = context.uri();
23 | String body = context.extract(String.class);
24 | logger.log(method + " " + uri + " " + body);
25 | Order order = context.extract(Order.class);
26 | logger.log("Unserialized order: " + order);
27 |
28 | // Use the following line to choose not to handle an order
29 | return new Payload("application/json", "", 200);
30 |
31 | // Use the following lines to return a total:
32 | // double total = 42.0;
33 | // Answer answer = new Answer(total);
34 | // return new Payload("application/json", answer, 200);
35 | }))
36 | ;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/clients/php/socket/src/Server.php:
--------------------------------------------------------------------------------
1 | _reader = $reader;
17 | $this->_response = $response;
18 | $this->_output = $output;
19 | $this->_feedbackMapper = $feedbackMapper;
20 | }
21 |
22 | public function Start()
23 | {
24 | $this->_reader->Listen(5000);
25 | do {
26 | $readerSpawn = $this->_reader->Read();
27 | $resource = $this->_reader->GetResource();
28 | if($resource == "Ping"){
29 | $this->_output->Print($resource);
30 | $this->_response->Post("pong", $readerSpawn);
31 | }
32 | if ($resource == "Order") {
33 | $this->_output->Print($resource . " : " . $this->_reader->GetMessage());
34 |
35 | //$result = new Result(30); //TODO compute correct result or you'll get a penalty
36 | $result = null;
37 |
38 | $this->_response->Post($result, $readerSpawn);
39 | }
40 | if ($resource == "Feedback"){
41 | $feedbackMessage = $this->_feedbackMapper->setValues($this->_reader->GetMessage());
42 | $this->_output->Print($feedbackMessage->GetType() . " : " . $feedbackMessage->GetMessage());
43 | }
44 | }
45 | while($readerSpawn);
46 | $this->_reader->Close();
47 | }
48 | }
--------------------------------------------------------------------------------
/clients/c#/coreWebApi/src/xcarpaccio/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.Extensions.Configuration;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.Extensions.Logging;
6 |
7 | namespace XCarpaccio
8 | {
9 | public class Startup
10 | {
11 | public Startup(IHostingEnvironment env)
12 | {
13 | var builder = new ConfigurationBuilder()
14 | .SetBasePath(env.ContentRootPath)
15 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
16 | .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
17 |
18 | Configuration = builder.Build();
19 | }
20 |
21 | public IConfigurationRoot Configuration { get; }
22 |
23 | // This method gets called by the runtime. Use this method to add services to the container.
24 | public void ConfigureServices(IServiceCollection services)
25 | {
26 | services.AddMvc();
27 | }
28 |
29 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
30 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
31 | {
32 | loggerFactory.AddConsole(Configuration.GetSection("Logging"));
33 | loggerFactory.AddDebug();
34 | app.UseMiddleware();
35 | app.UseMvc(routes =>
36 | {
37 | routes.MapRoute(
38 | name: "default",
39 | template: "{controller=Home}/{action=Index}/{id?}");
40 | });
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/server/javascripts/config.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs')
2 | var utils = require('../javascripts/utils')
3 | var _ = require('lodash')
4 | var chalk = require('chalk')
5 |
6 | var Configuration = function (filepath) {
7 | this.filepath = filepath
8 | this.props = {}
9 | }
10 |
11 | Configuration.prototype = (function () {
12 | function loadFile (self, callback) {
13 | console.info(chalk.red('Reloading ' + self.filepath))
14 |
15 | fs.readFile(self.filepath, function (err, data) {
16 | if (err) {
17 | console.error('%j', err)
18 | } else {
19 | try {
20 | self.props = utils.jsonify(data)
21 |
22 | if (typeof callback !== 'undefined') {
23 | callback(err)
24 | }
25 | } catch (exception) {
26 | console.error('Oops something wrong happened', exception)
27 | }
28 | }
29 | })
30 | }
31 |
32 | function readContent (self) {
33 | console.info('Reading %s.', self.filepath)
34 | var fileContent = fs.readFileSync(self.filepath)
35 | return utils.jsonify(fileContent)
36 | }
37 |
38 | return {
39 | load: function (callback) {
40 | return loadFile(this, callback)
41 | },
42 |
43 | all: function () {
44 | var self = this
45 |
46 | if (_.isEmpty(self.props)) {
47 | self.props = readContent(self)
48 | }
49 |
50 | return self.props
51 | },
52 |
53 | watch: function (callback, watchOnce, interval) {
54 | var self = this
55 |
56 | fs.watchFile(self.filepath, { persistent: !watchOnce, interval: interval }, function (curr, prev) {
57 | self.load(callback)
58 | })
59 | }
60 | }
61 | })()
62 |
63 | var exports = module.exports
64 | exports.Configuration = Configuration
65 |
--------------------------------------------------------------------------------
/clients/java/java-fluent-http/src/test/java/xcarpaccio/MyFluentHttpServerTest.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import static com.jayway.restassured.RestAssured.given;
4 | import static com.jayway.restassured.RestAssured.when;
5 | import static com.jayway.restassured.http.ContentType.JSON;
6 | import static org.hamcrest.Matchers.containsString;
7 | import static org.hamcrest.Matchers.equalTo;
8 |
9 | import org.junit.Test;
10 | import com.jayway.restassured.RestAssured;
11 |
12 | public class MyFluentHttpServerTest {
13 |
14 | private static final int PORT = 9001;
15 | private static final MyFluentHttpServer myFluentHttpServer = new MyFluentHttpServer(PORT);
16 |
17 | static {
18 | RestAssured.port = PORT;
19 | }
20 |
21 | @Test public void
22 | should_respond_pong_when_requesting_ping() {
23 | when().
24 | get("/ping").
25 | then().
26 | statusCode(200).
27 | body(containsString("pong"))
28 | ;
29 | }
30 |
31 | @Test public void
32 | should_post_feedback() {
33 | given().
34 | contentType(JSON).
35 | body(new Message("myType", "myContent")).
36 | when().
37 | post("/feedback").
38 | then().
39 | statusCode(204)
40 | ;
41 | }
42 |
43 | @Test public void
44 | should_post_an_order() {
45 | given().
46 | contentType(JSON).
47 | body("{\"prices\":[31.01],\"quantities\":[8],\"names\":[\"Tea\"],\"country\":\"IT\",\"reduction\":\"STANDARD\"}").
48 | when().
49 | post("/order").
50 | then().
51 | statusCode(200).
52 | body(equalTo(""))
53 | ;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/clients/erlang/README.md:
--------------------------------------------------------------------------------
1 | # Get Started
2 |
3 | Compile the application using rebar:
4 |
5 | ./rebar get-deps compile
6 |
7 | Start the application:
8 |
9 | erl -pa ebin deps/*/ebin -s xcarpaccio
10 |
11 | Execute tests:
12 |
13 | ./rebar compile eunit skip_deps=true
14 |
15 | Execute tests for dependencies too:
16 |
17 | ./rebar compile eunit
18 |
19 |
20 | # Developer Notes
21 |
22 | ```
23 | $ wget https://github.com/rebar/rebar/wiki/rebar
24 | $ chmod +x rebar
25 | ```
26 |
27 | ## Live code reload
28 |
29 | **First shell: start the application**
30 |
31 | ```
32 | $ erl -pa ebin deps/*/ebin -s xcarpaccio -sname bob -noshell
33 | ```
34 |
35 | **Second Shell: remote shell on the first shell**
36 |
37 | ```
38 | $ erl -sname razowski -remsh bob@Mentem
39 | → c("src/xcarpaccio_webhandler").
40 | ```
41 |
42 | or
43 |
44 | ```
45 | $ erl -sname razowski -remsh bob@Mentem
46 | → cd("src/").
47 | → c(xcarpaccio_webhandler).
48 | ```
49 |
50 |
51 | **Warning**
52 | By default, beam files - created from shell compilation - are not created within the `ebin/` folder but in the root folder (or in `src` if you changed the current directory). You should take care to recompile the application if it is restarted from scratch afterwards. Otherwise you may still run old behaviors from previous beam files.
53 |
54 | A solution is to define the output dir of the compilation.
55 |
56 | ```
57 | $ erl -sname razowski -remsh bob@Mentem
58 | → cd("src/").
59 | → OPTs = [{outdir,"../ebin"}].
60 | → c(xcarpaccio_webhandler, OPTs).
61 | ```
62 |
63 | # Resources
64 |
65 | * [cowboy](https://github.com/extend/cowboy): Small, fast, modular HTTP server written in Erlang
66 | * [jsx](https://github.com/talentdeficit/jsx): JSON parser (in erlang no NIF)
67 | * [rebar](https://github.com/rebar/rebar)
68 |
--------------------------------------------------------------------------------
/clients/erlang/src/xcarpaccio_app.erl:
--------------------------------------------------------------------------------
1 | -module(xcarpaccio_app).
2 |
3 | -behaviour(application).
4 |
5 | %% Application callbacks
6 | -export([start/2, stop/1]).
7 |
8 | -define(C_ACCEPTORS, 100).
9 |
10 | %% ===================================================================
11 | %% Application callbacks
12 | %% ===================================================================
13 |
14 | start(_StartType, _StartArgs) ->
15 | Routes = routes(),
16 | Dispatch = cowboy_router:compile(Routes),
17 | Port = port(),
18 | TransOpts = [{port, Port}],
19 | ProtoOpts = [{env, [{dispatch, Dispatch}]}],
20 | HttpStart = cowboy:start_http(http, ?C_ACCEPTORS, TransOpts, ProtoOpts),
21 | io:format("cowboy:start_http (on port ~p): ~p~n", [Port, HttpStart]),
22 | {ok, _} = HttpStart.
23 |
24 | stop(_State) ->
25 | ok.
26 |
27 | %% ===================================================================
28 | %% Internal functions
29 | %% ===================================================================
30 |
31 | %%
32 | %% Cowboy routes mapping -
33 | %% route does not support HTTP Method constraint
34 | %% https://groups.google.com/forum/#!topic/erlang-programming/-v2sBGxhDMY
35 | %%
36 | %% To prevent path duplication, dispatching is done in the handler itself
37 | %%
38 | routes() ->
39 | [
40 | {'_', [
41 | {"/[...]", xcarpaccio_webhandler, []}
42 | ]}
43 | ].
44 |
45 | %%
46 | %% Retrieve the PORT either from an os environment variable
47 | %% e.g. in Heroku environment, or from the application conf.
48 | %%
49 | port() ->
50 | case os:getenv("PORT") of
51 | false ->
52 | {ok, Port} = application:get_env(http_port),
53 | Port;
54 | Other ->
55 | list_to_integer(Other)
56 | end.
57 |
--------------------------------------------------------------------------------
/clients/c#/nancy/extreme-carpaccio.client/IndexModule.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.IO;
3 | using System.Net;
4 | using System.Text;
5 |
6 | namespace xCarpaccio.client
7 | {
8 | using Nancy;
9 | using System;
10 | using Nancy.ModelBinding;
11 |
12 | public class IndexModule : NancyModule
13 | {
14 | public IndexModule()
15 | {
16 | Post["/order"] = _ =>
17 | {
18 | var order = this.Bind();
19 | var bill = HandlerOrder(order);
20 | if (bill == null)
21 | {
22 | return new {};
23 |
24 | }
25 | else
26 | {
27 | return bill;
28 |
29 | }
30 |
31 | };
32 |
33 | Post["/feedback"] = _ =>
34 | {
35 | var feedback = this.Bind();
36 |
37 | HandleFeedback(feedback);
38 | return Negotiate.WithStatusCode(HttpStatusCode.OK);
39 | };
40 | }
41 |
42 | private string RequestAsString()
43 | {
44 | string request;
45 | using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
46 | {
47 | request = reader.ReadToEnd();
48 | }
49 | return request;
50 | }
51 |
52 | private void HandleFeedback(Feedback feedback)
53 | {
54 | Console.Write("Type: {0}: ", feedback.type);
55 | Console.WriteLine(feedback.content);
56 | }
57 |
58 |
59 | private Bill HandlerOrder(Order order)
60 | {
61 | // TODO HERE. Return null if you do not what to return a total
62 | return null;
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # In the development environment your application's code is reloaded on
5 | # every request. This slows down response time but is perfect for development
6 | # since you don't have to restart the web server when you make code changes.
7 | config.cache_classes = false
8 |
9 | # Do not eager load code on boot.
10 | config.eager_load = false
11 |
12 | # Show full error reports.
13 | config.consider_all_requests_local = true
14 |
15 | # Enable/disable caching. By default caching is disabled.
16 | if Rails.root.join('tmp/caching-dev.txt').exist?
17 | config.action_controller.perform_caching = true
18 |
19 | config.cache_store = :memory_store
20 | config.public_file_server.headers = {
21 | 'Cache-Control' => 'public, max-age=172800'
22 | }
23 | else
24 | config.action_controller.perform_caching = false
25 |
26 | config.cache_store = :null_store
27 | end
28 |
29 | # Don't care if the mailer can't send.
30 | config.action_mailer.raise_delivery_errors = false
31 |
32 | config.action_mailer.perform_caching = false
33 |
34 | # Print deprecation notices to the Rails logger.
35 | config.active_support.deprecation = :log
36 |
37 | # Raise an error on page load if there are pending migrations.
38 | config.active_record.migration_error = :page_load
39 |
40 |
41 | # Raises error for missing translations
42 | # config.action_view.raise_on_missing_translations = true
43 |
44 | # Use an evented file watcher to asynchronously detect changes in source code,
45 | # routes, locales, etc. This feature depends on the listen gem.
46 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker
47 | end
48 |
--------------------------------------------------------------------------------
/clients/php/socket/src/Reader.php:
--------------------------------------------------------------------------------
1 | _resource;
22 | }
23 |
24 | public function GetMessage()
25 | {
26 | return $this->_message;
27 | }
28 |
29 | public function Listen($port)
30 | {
31 | $host = "0.0.0.0";
32 | $this->_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
33 | socket_bind($this->_socket, $host, $port);
34 | socket_listen($this->_socket, SOMAXCONN);
35 | }
36 |
37 | public function Read()
38 | {
39 |
40 | $spawn = socket_accept($this->_socket);
41 | $body = socket_read($spawn, 1048576);
42 | $this->_message = $this->GetMessageFrom($body);
43 | $this->_resource = $this->GetResourceFrom($body);
44 | return $spawn;
45 |
46 | }
47 |
48 | public function Close()
49 | {
50 | socket_close($this->_socket);
51 | }
52 |
53 | public function GetMessageFrom(string $body)
54 | {
55 | $parts = explode("\r\n\r\n", $body);
56 |
57 | if ($parts)
58 | {
59 | $message = $parts[1];
60 | }
61 |
62 | return $message;
63 | }
64 |
65 | public function GetResourceFrom(string $body)
66 | {
67 | $parts = explode("\r\n\r\n", $body);
68 | $type = "";
69 | if ($parts)
70 | {
71 | $headers = array_shift($parts);
72 | $matches = preg_split('/ /', $headers);
73 | $type = str_replace("/", "", $matches[1]);
74 | }
75 |
76 | return ucfirst($type);
77 | }
78 | }
--------------------------------------------------------------------------------
/clients/java/java-httpserver/src/test/java/xcarpaccio/AbstractHttpServerTest.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import java.io.DataOutputStream;
4 | import java.io.IOException;
5 | import java.net.HttpURLConnection;
6 | import java.net.ProtocolException;
7 | import java.net.URL;
8 |
9 | import static xcarpaccio.StringUtils.stringify;
10 |
11 | public abstract class AbstractHttpServerTest
12 | {
13 | private static final String UTF_8 = "utf-8";
14 |
15 | protected String get(String url) throws IOException {
16 | return get(url, "");
17 | }
18 |
19 | protected String get(String url, String query) throws IOException {
20 | URL localhost = new URL(url + "?" + query);
21 | HttpURLConnection connection = (HttpURLConnection) localhost.openConnection();
22 | connection.setRequestMethod( "GET" );
23 | connection.disconnect();
24 | return stringify(connection.getInputStream());
25 | }
26 |
27 | protected String post(String path, String body) throws IOException {
28 | URL url = new URL(path);
29 | HttpURLConnection connection = (HttpURLConnection) url.openConnection();
30 | connection.setDoOutput(true);
31 | connection.setDoInput(true);
32 | connection.setInstanceFollowRedirects(false);
33 | connection.setRequestMethod("POST");
34 | connection.setRequestProperty("Content-Type", "application/json");
35 | connection.setRequestProperty("charset", UTF_8);
36 | connection.setRequestProperty("Content-Length", Integer.toString(body.length()));
37 | connection.setUseCaches(false);
38 | try( DataOutputStream wr = new DataOutputStream( connection.getOutputStream())) {
39 | wr.write( body.getBytes(UTF_8) );
40 | return stringify(connection.getInputStream());
41 | } finally {
42 | connection.disconnect();
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/server/specs/config_spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _1000_MILLIS_TIMEOUT = 1000;
4 | var _200_MILLIS = 200;
5 |
6 | var fs = require('fs'),
7 | Configuration = require('../javascripts/config').Configuration;
8 |
9 | describe('Configuration', function(){
10 | var config,
11 | synchronized,
12 | configFilepath = "specs/config.json.tmp";
13 |
14 | beforeEach(function () {
15 | fs.writeFileSync(configFilepath, '{"reduction": "STANDARD"}');
16 | config = new Configuration(configFilepath);
17 | synchronized = false;
18 | });
19 |
20 | it('should load configuration from file', function() {
21 | runs(function() {
22 | config.load(function (err) {
23 | expect(err).toBeNull(); // Arnauld a voulu faire ce test, parce qu'il trouve que c'est une bonne idee!
24 | synchronized = true;
25 | });
26 | });
27 |
28 | waitsFor(function() {
29 | return synchronized;
30 | }, "Properties should be loaded in time", _1000_MILLIS_TIMEOUT);
31 |
32 | runs(function() {
33 | var properties = config.all();
34 | expect(properties).toEqual({reduction: 'STANDARD'});
35 | });
36 | });
37 |
38 | it('should reload configuration on the fly', function() {
39 | runs(function() {
40 | config.watch(function() {
41 | synchronized = true;
42 | }, true, _200_MILLIS);
43 |
44 | fs.writeFileSync(configFilepath, '{"reduction": "HALF PIPE"}');
45 | });
46 |
47 | waitsFor(function() {
48 | return synchronized;
49 | }, "File change should be detected", _1000_MILLIS_TIMEOUT);
50 |
51 | runs(function() {
52 | var properties = config.all();
53 | expect(properties).toEqual({reduction: 'HALF PIPE'});
54 | });
55 | });
56 | });
57 |
--------------------------------------------------------------------------------
/clients/ruby/ruby-rails/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Do not eager load code on boot. This avoids loading your whole application
11 | # just for the purpose of running a single test. If you are using a tool that
12 | # preloads Rails for running tests, you may have to set it to true.
13 | config.eager_load = false
14 |
15 | # Configure public file server for tests with Cache-Control for performance.
16 | config.public_file_server.enabled = true
17 | config.public_file_server.headers = {
18 | 'Cache-Control' => 'public, max-age=3600'
19 | }
20 |
21 | # Show full error reports and disable caching.
22 | config.consider_all_requests_local = true
23 | config.action_controller.perform_caching = false
24 |
25 | # Raise exceptions instead of rendering exception templates.
26 | config.action_dispatch.show_exceptions = false
27 |
28 | # Disable request forgery protection in test environment.
29 | config.action_controller.allow_forgery_protection = false
30 | config.action_mailer.perform_caching = false
31 |
32 | # Tell Action Mailer not to deliver emails to the real world.
33 | # The :test delivery method accumulates sent emails in the
34 | # ActionMailer::Base.deliveries array.
35 | config.action_mailer.delivery_method = :test
36 |
37 | # Print deprecation notices to the stderr.
38 | config.active_support.deprecation = :stderr
39 |
40 | # Raises error for missing translations
41 | # config.action_view.raise_on_missing_translations = true
42 | end
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Extreme Carpaccio
2 |
3 | French version [here](./README-FR.md).
4 |
5 | Extreme Carpaccio is a coding game designed to encourage and favour incremental development and Continuous Delivery best practices.
6 |
7 | During a Extreme Carpaccio session, the facilitator uses his/her computer as a server and sends HTTP requests to participant machines (generally organised in teams). Each request is a purchasing order, like those you have when you buy something somewhere. Participants then calculate the order's total amount and send the correct response back to the server. For every correct response, the participant earns points and increases his/her score. For bad responses, penalties are charged and the participant loses points. Participants should slice (or decouple) the problem in order to deploy small chunks of the solution into production as soon as possible and then score before others. This is the purpose of this exercise: define a slicing strategy, implement, deploy, check feedback, adapt the strategy, implement, deploy... and iterate as fast as possible. **Those who don't slice and try go to production only once the whole solution is implemented risk to spend too much time before scoring, leaving the way free to other teams win.**
8 |
9 | This workshop, kata, or coding game is intented to help teams to practice concepts like Continuous Delivery, Lean Startup, eXtreme Programming, Agile Development, and more.
10 |
11 | Ready for the challenge?
12 |
13 | If you are a **participant**, go to [clients/](./clients/README.md) to get more instructions and start playing.
14 |
15 | If you are a **facilitator**, go to [server/](./server/README.md) and find out how to facilitate a session.
16 |
17 | Have fun :D
18 |
19 | ## People running Extreme Carpaccio
20 | - Find out what people are saying about Extreme Carpaccio on [Twitter](https://twitter.com/search?vertical=default&q=%22extreme%20carpaccio%22%20OR%20%22Xtreme%20carpaccio%22%20OR%20%23ExtremeCarpaccio&src=typd)
21 |
--------------------------------------------------------------------------------
/server/javascripts/services/order.js:
--------------------------------------------------------------------------------
1 | var repositories = require('../repositories')
2 | var _ = require('lodash')
3 | var utils = require('../utils')
4 | var chalk = require('chalk')
5 |
6 | function OrderService (configuration) {
7 | this.countries = new repositories.Countries(configuration)
8 | }
9 |
10 | module.exports = OrderService
11 |
12 | var service = OrderService.prototype
13 |
14 | service.sendOrder = function (seller, order, cashUpdater, logError) {
15 | console.info(chalk.grey('Sending order ' + utils.stringify(order) + ' to seller ' + utils.stringify(seller)))
16 | utils.post(seller.hostname, seller.port, seller.path + '/order', order, cashUpdater, logError)
17 | }
18 |
19 | service.createOrder = function (reduction) {
20 | var items = _.random(1, 10)
21 | var prices = new Array(items)
22 | var quantities = new Array(items)
23 | var country = this.countries.randomOne()
24 |
25 | for (var item = 0; item < items; item++) {
26 | var price = _.random(1, 100, true)
27 | prices[item] = utils.fixPrecision(price, 2)
28 | quantities[item] = _.random(1, 10)
29 | }
30 |
31 | return {
32 | prices: prices,
33 | quantities: quantities,
34 | country: country,
35 | reduction: reduction.name
36 | }
37 | }
38 |
39 | service.bill = function (order, reduction) {
40 | var prices = order.prices
41 | var quantities = order.quantities
42 | var sum = quantities
43 | .map(function (q, i) { return q * prices[i] })
44 | .reduce(function (sum, current) { return sum + current }, 0)
45 |
46 | var taxRule = this.countries.taxRule(order.country)
47 | sum = taxRule.applyTax(sum)
48 | sum = reduction.apply(sum)
49 | return { total: sum }
50 | }
51 |
52 | service.validateBill = function (bill) {
53 | if (!_.has(bill, 'total')) {
54 | throw new Error('The field "total" in the response is missing.')
55 | }
56 |
57 | if (!_.isNumber(bill.total)) {
58 | throw new Error('"Total" is not a number.')
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/clients/java/java-httpserver/src/main/java/xcarpaccio/FeedbackMessage.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import org.codehaus.jackson.map.ObjectMapper;
4 |
5 | import java.io.IOException;
6 |
7 | public class FeedbackMessage {
8 | private final ObjectMapper objectMapper = new ObjectMapper();
9 |
10 | private String type;
11 | private String content;
12 |
13 | // Required by Jackson
14 | private FeedbackMessage() {
15 | }
16 |
17 | public FeedbackMessage(String type, String content) {
18 | this.type = type;
19 | this.content = content;
20 | }
21 |
22 | public String getType() {
23 | return type;
24 | }
25 |
26 | public void setType(String type) {
27 | this.type = type;
28 | }
29 |
30 | public String getContent() {
31 | return content;
32 | }
33 |
34 | public void setContent(String content) {
35 | this.content = content;
36 | }
37 |
38 | public String json() throws IOException {
39 | return objectMapper.writeValueAsString(this);
40 | }
41 |
42 | @Override
43 | public boolean equals(Object o) {
44 | if (this == o) return true;
45 | if (o == null || getClass() != o.getClass()) return false;
46 |
47 | FeedbackMessage message = (FeedbackMessage) o;
48 |
49 | if (type != null ? !type.equals(message.type) : message.type != null) return false;
50 | return !(content != null ? !content.equals(message.content) : message.content != null);
51 |
52 | }
53 |
54 | @Override
55 | public int hashCode() {
56 | int result = type != null ? type.hashCode() : 0;
57 | result = 31 * result + (content != null ? content.hashCode() : 0);
58 | return result;
59 | }
60 |
61 | @Override
62 | public String toString() {
63 | return "Message{" +
64 | "type='" + type + '\'' +
65 | ", content='" + content + '\'' +
66 | '}';
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/server/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('xcarpaccio:server');
9 | var http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | var port = normalizePort(process.env.PORT || '3000');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | var server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | var port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | var bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | var addr = server.address();
86 | var bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/clients/java/java-springboot/src/test/java/xcarpaccio/WebControllerMockedServerTest.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.http.MediaType;
9 | import org.springframework.test.context.junit4.SpringRunner;
10 | import org.springframework.test.web.servlet.MockMvc;
11 |
12 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
13 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
14 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
15 |
16 | /**
17 | * Testing web API without the cost of starting the server but yet all the layers below
18 | * and for this using MockMvc
19 | */
20 | @RunWith(SpringRunner.class)
21 | @SpringBootTest
22 | @AutoConfigureMockMvc
23 | public class WebControllerMockedServerTest {
24 |
25 | @Autowired
26 | private MockMvc mockMvc;
27 |
28 | @Test
29 | public void orderWithEmptyPriceListShouldReturn0() throws Exception {
30 | this.mockMvc.perform(
31 | post("/order/")
32 | .content("{\"prices\":[]}")
33 | .contentType(MediaType.APPLICATION_JSON_UTF8))
34 | .andExpect(status().isOk())
35 | .andExpect(content().json("{\"total\":0}"))
36 | ;
37 | }
38 |
39 | @Test
40 | public void aNominalTest() throws Exception {
41 | this.mockMvc.perform(
42 | post("/order/")
43 | .content("{\"prices\":[1]}")
44 | .contentType(MediaType.APPLICATION_JSON_UTF8))
45 | // Throws a 404 for now, to avoid penalty
46 | .andExpect(status().isNotFound());
47 | }
48 | }
--------------------------------------------------------------------------------
/clients/java/java-httpserver/src/test/java/xcarpaccio/MyHttpServerTest.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import org.junit.After;
4 | import org.junit.Before;
5 | import org.junit.Ignore;
6 | import org.junit.Test;
7 |
8 | import static org.assertj.core.api.Assertions.assertThat;
9 | import static org.mockito.BDDMockito.then;
10 | import static org.mockito.Mockito.mock;
11 |
12 | public class MyHttpServerTest extends AbstractHttpServerTest
13 | {
14 | private static final int TEST_PORT = 8001;
15 | private static final String LOCALHOST = "http://localhost:" + TEST_PORT;
16 |
17 | private MyHttpServer server;
18 | private Logger logger;
19 |
20 | @Before
21 | public void startServer() throws Exception {
22 | logger = mock(Logger.class);
23 | server = new MyHttpServer(TEST_PORT, logger);
24 | server.start();
25 | }
26 |
27 | @After
28 | public void stopServer() {
29 | server.shutdown();
30 | }
31 |
32 | @Test
33 | public void should_respond_pong_when_receive_ping() throws Exception {
34 | assertThat(get(LOCALHOST + "/ping")).isEqualTo("pong");
35 | }
36 |
37 | @Test
38 | public void should_print_received_message_via_post() throws Exception {
39 | post(LOCALHOST + "/feedback", new FeedbackMessage("info", "test").json());
40 |
41 | then(logger).should().log("info: test");
42 | }
43 |
44 | @Test
45 | @Ignore
46 | public void should_deserialize_JSON_order_and_render_total() throws Exception {
47 | String body = post(LOCALHOST + "/order", "{\"prices\":[3.5],\"quantities\":[2],\"country\":\"ES\",\"reduction\":\"STANDARD\"}");
48 |
49 | assertThat(body).isEqualTo("{\"total\":7.0}");
50 | }
51 |
52 | @Test
53 | @Ignore
54 | public void should_reject_an_order() throws Exception {
55 | String body = post(LOCALHOST + "/order", "{\"prices\":[3.5],\"quantities\":[2],\"country\":\"ES\",\"reduction\":\"STANDARD\"}");
56 |
57 | assertThat(body).isEqualTo("");
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/server/specs/utils_spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var http = require('http');
4 |
5 | var utils = require('../javascripts/utils');
6 |
7 | describe('Utils', function() {
8 |
9 | it('should fix precision for numbers', function() {
10 | expect(utils.fixPrecision(1, 2)).toBe(1.00);
11 | expect(utils.fixPrecision(1.234, 2)).toBe(1.23);
12 | });
13 |
14 | it('should parse a string into a json object', function() {
15 | expect(utils.jsonify('{"name": "Bob"}')).toEqual({name: 'Bob'})
16 | });
17 |
18 | it('should not parse a string but return an empty object when input is not a valid json object', function() {
19 | expect(function(){utils.jsonify('not valid json object')}).toThrow();
20 | expect(function(){utils.jsonify('')}).toThrow();
21 | expect(function(){utils.jsonify(undefined)}).toThrow();
22 | });
23 |
24 | it('should send post request to someone else', function() {
25 | var fakeRequest = {
26 | write: function() {},
27 | on: function() {},
28 | end: function() {}
29 | };
30 | spyOn(http, 'request').andReturn(fakeRequest);
31 | spyOn(fakeRequest, 'write');
32 | spyOn(fakeRequest, 'end');
33 | var body = {content: 'some content'};
34 | var callback = function() {};
35 |
36 | utils.post('localhost', '3000', '/path', body, callback);
37 |
38 | var bodyStringified = utils.stringify(body);
39 | expect(http.request).toHaveBeenCalledWith({
40 | hostname : 'localhost',
41 | port : '3000',
42 | path : '/path',
43 | method : 'POST',
44 | headers : {
45 | 'Content-Type' : 'application/json',
46 | 'Accept' : 'application/json',
47 | 'Content-Length' : bodyStringified.length
48 | }
49 | }, callback);
50 | expect(fakeRequest.write).toHaveBeenCalledWith(bodyStringified);
51 | expect(fakeRequest.end).toHaveBeenCalled();
52 | });
53 | });
--------------------------------------------------------------------------------
/clients/java/java-springboot/src/test/java/xcarpaccio/WebControllerServerTest.java:
--------------------------------------------------------------------------------
1 | package xcarpaccio;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.test.context.SpringBootTest;
7 | import org.springframework.boot.test.web.client.TestRestTemplate;
8 | import org.springframework.boot.web.server.LocalServerPort;
9 | import org.springframework.http.HttpStatus;
10 | import org.springframework.http.ResponseEntity;
11 | import org.springframework.test.context.junit4.SpringRunner;
12 |
13 | import static org.junit.Assert.assertEquals;
14 |
15 | /**
16 | * Testing web API, starting the server
17 | */
18 | @RunWith(SpringRunner.class)
19 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
20 | public class WebControllerServerTest {
21 |
22 | @LocalServerPort
23 | private int port;
24 |
25 | @Autowired
26 | private TestRestTemplate restTemplate;
27 |
28 | @Test
29 | public void orderWithEmptyPriceListShouldReturn0() {
30 | TestRestTemplate testRestTemplate = new TestRestTemplate();
31 | Order order = new Order();
32 | order.prices = new Double[] {};
33 | ResponseEntity response = testRestTemplate.
34 | postForEntity("http://localhost:" + this.port + "/order", order, Amount.class);
35 | assertEquals(HttpStatus.OK, response.getStatusCode());
36 | assertEquals(new Double(0.0), response.getBody().total);
37 | }
38 |
39 | @Test
40 | public void aNominalTest() {
41 | TestRestTemplate testRestTemplate = new TestRestTemplate();
42 | Order order = new Order();
43 | order.prices = new Double[] {0.0};
44 | ResponseEntity response = testRestTemplate.
45 | postForEntity("http://localhost:" + this.port + "/order", order, Amount.class);
46 | // Throws a 404 for now, to avoid penalty
47 | assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
48 | }
49 | }
50 |
--------------------------------------------------------------------------------