{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies #-} {-# LANGUAGE OverloadedStrings, GADTs, FlexibleContexts, MultiParamTypeClasses #-} {-# LANGUAGE NoMonomorphismRestriction, GeneralizedNewtypeDeriving #-} module Movies where import Database.Persist (insertMany) import Database.Persist.Sqlite (runSqlite, runMigration) import Database.Persist.TH (mkPersist, mkMigrate, persistUpperCase, share, sqlSettings) share [mkPersist sqlSettings, mkMigrate "migrateTables"] [persistUpperCase| Movies title String year Int rating Int deriving Eq Show |] mkMoviesDB :: IO () mkMoviesDB = runSqlite "/tmp/movies.db" $ do runMigration migrateTables insertMany [ Movies "Rise of the Planet of the Apes" 2011 77 , Movies "Dawn of the Planet of the Apes" 2014 91 , Movies "Alien" 1979 97 , Movies "Aliens" 1986 98 , Movies "Mad Max" 1979 95 , Movies "Mad Max 2: The Road Warrior" 1981 100 ] return ()
- {-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies #-}
- {-# LANGUAGE OverloadedStrings, GADTs, FlexibleContexts, MultiParamTypeClasses #-}
- {-# LANGUAGE NoMonomorphismRestriction, GeneralizedNewtypeDeriving #-}
- module Movies where
- import Database.Persist (insertMany)
- import Database.Persist.Sqlite (runSqlite, runMigration)
- import Database.Persist.TH (mkPersist, mkMigrate, persistUpperCase, share, sqlSettings)
- share [mkPersist sqlSettings, mkMigrate "migrateTables"] [persistUpperCase|
- Movies
- title String
- year Int
- rating Int
- deriving Eq Show
- |]
- mkMoviesDB :: IO ()
- mkMoviesDB = runSqlite "/tmp/movies.db" $ do
- runMigration migrateTables
- insertMany
- [ Movies "Rise of the Planet of the Apes" 2011 77
- , Movies "Dawn of the Planet of the Apes" 2014 91
- , Movies "Alien" 1979 97
- , Movies "Aliens" 1986 98
- , Movies "Mad Max" 1979 95
- , Movies "Mad Max 2: The Road Warrior" 1981 100
- ]
- return ()
In this varation, I have refactored the code so that the execute helper wraps up the transaction rollback as part of its method call. It also will try to parse the response as json and provide that as the 2nd argument, DRYing up the code as more tests are added.
describe "Solution" do it "should test for something" do RequestHelpers.execute('GET', SolutionController, 'show') do |response, json| Test.assert_equals(json['title'], 'Test') end end end
require "rack/utils"def with_dbActiveRecord::Base.transaction doyieldraise ActiveRecord::Rollbackendend- describe "Solution" do
- it "should test for something" do
with_db doresponse = RequestHelpers.execute('GET', SolutionController, 'show')json = JSON.parse(response.body)- RequestHelpers.execute('GET', SolutionController, 'show') do |response, json|
- Test.assert_equals(json['title'], 'Test')
- end
- end
- end
class SolutionController < ActionController::Base
def show
tag = Tag.create!(title: 'Test')
render json: tag
end
end
ActiveRecord::Schema.define do
create_table :tags do |table|
table.column :title, :string
end
end
class Tag < ActiveRecord::Base
end
require "rack/utils"
def with_db
ActiveRecord::Base.transaction do
yield
raise ActiveRecord::Rollback
end
end
describe "Solution" do
it "should test for something" do
with_db do
response = RequestHelpers.execute('GET', SolutionController, 'show')
json = JSON.parse(response.body)
Test.assert_equals(json['title'], 'Test')
end
end
end
This example shows how to do random numbers in Swift.
import Glibc
for count in 1...20 {
print(random() % 100)
}
This is a very basic example of how you can start a redis server using async code and wrapping it so that you can enable the solution to run only after the server has started.
This example also demonstrates how you can support async code within it
tests. To enable async mode, you can pass true
or a number value as the 2nd argument to describe
. If true
is provided, 2000
is used as the default number value, which is used as the timeout for each it
run.
Notice how the it
function has a done
callback. You are required to call this when using async code so that the function knows when the it
test has finished and can move on to the next test.
const redis = require("redis");
const Promise = require("bluebird");
// promisfy redis client to make it much easier to work with.
Promise.promisifyAll(redis.RedisClient.prototype);
// solution is your entry point. The redis server will not be available until solution is called. Since
// we are using async code you must call done() once you have completed the requirements.
function solution(done){
let client = redis.createClient();
// use Promise.join to make sure the done callback is fired after all other async operations have fired.
Promise.join(
client.setAsync("foo", "bar"),
client.hsetAsync("h", "key", "value"),
done
)
}
startRedis().then(stop => {
let client = redis.createClient();
solution(_ => {
describe("redis challenge", true, _ => {
it ("should have set foo to == 'bar'", done => {
client.getAsync('foo').then(actual => {
Test.assertEquals(actual, "bar");
done();
});
});
it ("should set h.key to == 'value'", done => {
client.hgetAsync('h', 'key').then(actual => {
Test.assertEquals(actual, "value");
done();
});
});
})
.then(stop); // describe returns a promise so we can hook into that to shut down our spawned process.
});
});
This is a basic example of rendering a plot chart to the output window. It uses matplotlib and mpld3.
Some dummy tests were added at the end to demonstrate how you could have a challenge based on rendering data to a chart and then you could have tests that test the chart data after the fact - allowing you to have an interactive visualazation for the data that is being tested.
# Example taken from http://mpld3.github.io/examples/drag_points.html
import numpy as np
import matplotlib
matplotlib.use('Agg') # need to do this to set the display type
import matplotlib.pyplot as plt
import matplotlib as mpl
fig, ax = plt.subplots()
np.random.seed(0)
points = ax.plot(np.random.normal(size=20),
np.random.normal(size=20), 'or', alpha=0.5,
markersize=50, markeredgewidth=1)
ax.set_title("Click and Drag", fontsize=18)
# See Preloaded code for JS DragPlugin
plugins.connect(fig, DragPlugin(points[0]))
print(mpld3.fig_to_html(fig))
Test.describe("You can add tests after the plot is rendered")
Test.it("should do something that passes or fails")
test.expect(True)
Test.it("should do something else that passes or fails")
test.expect(True)
Often times kata authors want to prevent certain code from being used within a kata, to increase the level of difficulty. This is an example of how you can read the solution.txt file into your code.
This example is in JavaScript, but the /home/codewarrior/solution.txt
file is available for all languages.
// write a add function that doesn't use the plus symbol
function add(a, b){
return a + b;
}
// Make sure to view the test cases to see how this test fails
const fs = require('fs');
const solution = fs.readFileSync('/home/codewarrior/solution.txt', 'utf8');
describe("Check Solution", function(){
it("should prevent the '+' symbol from being used anywhere in the code", function(){
Test.expect(solution.indexOf('+') == -1, "Your code isn't allowed to include the + symbol!");
});
});
A basic proof of how you can create content that writes to the file system.
# you can write to your codewarrior home folder
`echo "example text" > /home/codewarrior/example.txt`
describe "Solution" do
it "should by able to ready the example file" do
File.open("/home/codewarrior/example.txt", "r") do |f|
f.each_line do |line|
puts line
Test.assert_equals(line, "example text\n")
end
end
end
end
A basic example of how to setup an active record challenge.
Note: Make sure to check out the preloaded section for how to configure the database.
ActiveRecord::Schema.define do
create_table :albums do |table|
table.column :title, :string
table.column :performer, :string
end
create_table :tracks do |table|
table.column :album_id, :integer
table.column :track_number, :integer
table.column :title, :string
end
end
class Album < ActiveRecord::Base
has_many :tracks
end
class Track < ActiveRecord::Base
belongs_to :album
end
# TODO: Replace examples and use TDD development by writing your own tests
# These are some of the methods available:
# Test.expect(boolean, [optional] message)
# Test.assert_equals(actual, expected, [optional] message)
# Test.assert_not_equals(actual, expected, [optional] message)
describe "Solution" do
album = Album.create(title: "The Downward Spiral", performer: "Nine Inch Nails")
describe "Album" do
it "should have a title" do
Test.assert_equals(album.title, "The Downward Spiral")
end
it "should have a performer" do
Test.assert_equals(album.performer, "Nine Inch Nails")
end
end
end
require "sqlite3"
db = SQLite3::Database.new ":memory:"
rows = db.execute <<-SQL
create table numbers (
name varchar(30),
val int
);
SQL
{
"one" => 1,
"two" => 2,
}.each do |pair|
db.execute "insert into numbers values ( ?, ? )", pair
end
p db.execute( "select * from numbers" ).to_a
describe "DB" do
it "should have two rows" do
rows = db.execute( "select * from numbers" ).to_a
Test.assert_equals(rows.size, 2, "Should have 2 rows")
end
end
add = -> a, b { a + b } square = -> x { x * x } # sigh, if only Ruby supported pipes! result = square.(add.(add.(add.(1,2), 3), 4)) puts result
let add a b = a + blet square x = x * xlet result = add 1 2 |> add 3 |> add 4 |> square- add = -> a, b { a + b }
- square = -> x { x * x }
printfn result- # sigh, if only Ruby supported pipes!
- result = square.(add.(add.(add.(1,2), 3), 4))
- puts result
Test.assert_equals(result, 100)
- Test.assert_equals(result, 100)
In this version end
is protected so that it is only called once, and once its called next()
no longer does anything.
function Chain(){ this.links = []; } Chain.prototype.link = function link(cb){ this.links.push(cb); return this; } Chain.prototype.run = function run(end){ var self = this, ended = false, _end = function(){ end(); ended = true; }, next = function(){ if (!ended){ if(self.links.length) { self.links.shift()(next, _end); } else { _end(); } } }; next(); }
- function Chain(){
- this.links = [];
- }
- Chain.prototype.link = function link(cb){
- this.links.push(cb);
- return this;
- }
- Chain.prototype.run = function run(end){
if(this.links.length) {this.links.shift()(Chain.prototype.run.bind(this, end), end);} else {end();}- var self = this,
- ended = false,
- _end = function(){
- end();
- ended = true;
- },
- next = function(){
- if (!ended){
- if(self.links.length) {
- self.links.shift()(next, _end);
- } else {
- _end();
- }
- }
- };
- next();
- }
This shows a very simple example for displaying interactive Angular content within the output window. Click "View Output" to see.
var script = `<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.5/angular.min.js"></script>`;
var styles = `
html, body {
background-color: #ecf0f1;
margin: 20px auto;
display: block;
max-width: 600px;
height: 100%;
text-align: center;
}
body {
padding: 20px;
position: relative;
}
h2, a, p, *:before,h1 {
font-family: "Helvetica Neue", sans-serif;
font-weight: 300;
}
h1 {
color: #3498db;
}
h2 {
color: #2980b9;
margin-bottom: 9px;
margin-top: 0;
font-size: 20px;
background-color: white;
/*width: 100px;*/
text-align: center;
padding: 16px;
z-index: 15;
border-radius: 4px;
transition: all 2s ease-out;
}
p {
display: block;
width: 100%;
color: #2c3e50;
clear: both;
}
.description {
margin-bottom: 70px;
}
button {
border: 0;
background-color: #3498db;
color: white;
border-radius: 4px;
padding: 5px 10px;
transition: background-color 0.2s ease-out;
cursor: pointer;
}
button:hover {
background-color: #2980b9;
}
button:active, button:hover {
outline: none;
}
a {
color: #2c3e50;
transition: color 0.2s ease-out;
/*padding: 5px 10px;*/
margin-right: 16px;
}
a:hover {
color: #2ecc71;
}
.wrapper {
border: 1px dashed #95a5a6;
height: 56px;
margin-top: 16px;
border-radius: 4px;
position: relative;
font-size: 12px;
}
.wrapper p {
line-height: 31px;
}
`
var html = `
<div ng-app="">
<h1>Ng-show & ng-hide</h1>
<p class="description">Click on the "show"-link to see the content.</p>
<a href="" ng-click="showme=true">Show</a>
<button ng-click="showme=false">Hide</button>
<div class="wrapper">
<p ng-hide="showme">I am hidden content</p>
<h2 ng-show="showme">I am visible content</h2>
</div>
</div>
`
console.log(`${script}<style>${styles}</style>${html}`);
Test.expect(script.length > 0);
Quick example of a basic resource pool. The test cases are pretty bad and could use some work, but they demonstrate the basic idea.
// sample Resource
function Resource(name){
this.run = function(cb){
console.log("resource ran: " + name)
if (cb) cb()
}
var events = {}
this.on = function(event, cb){
events[event] = events[event] || []
events[event].push(cb);
}
this.emit = function(event){
var self = this;
events[event].forEach(function(cb){
cb(self);
})
}
}
function Pool(){
this.ready = [];
this.waiting = [];
this.resources = [];
}
Pool.prototype.checkout = function(cb)
{
if (this.ready.length > 0)
{
this.ready.shift().run(cb);
}
else
{
this.waiting.push(cb);
}
}
Pool.prototype.checkin = function(resource)
{
if (this.ready.indexOf(resource) == -1){
this.ready.push(resource);
}
if (this.waiting.length > 0)
{
this.checkout(this.waiting.shift());
}
}
Pool.prototype.register = function(resource)
{
this.resources.push(resource);
var self = this;
resource.on('ready', function()
{
self.checkin(resource);
});
}
var pool = new Pool();
pool.register(new Resource('a'))
pool.register(new Resource('b'))
pool.register(new Resource('c'))
// we can checkout even if nothing is ready
pool.checkout(function(){console.log(1)})
// simulate some ready events, some of these will fire even before there are any handlers to play with
pool.resources[0].emit('ready')
pool.resources[1].emit('ready')
pool.resources[2].emit('ready')
pool.checkout(function(){
console.log(2)
Test.pass()
})
pool.checkout()
pool.checkout()
pool.checkout()
pool.resources[0].emit('ready')
A little utility that I came up with recently to deal with needing to loop through multiple items and run an async operation within each. This makes it very easy to chain together a sequence of callbacks.
For example:
var chain = new Chain();
someItemsToProcess.forEach(function(item){
chain.link(function(next){
asyncProcess(item, next);
});
});
chain.run(function(){
// done
});
Some possible room for improvement:
- Promise support
- Events
- ?
function Chain(){
this.links = [];
}
Chain.prototype.link = function link(cb){
this.links.push(cb);
return this;
}
Chain.prototype.run = function run(end){
var self = this;
var next = function(i){
return function(){
if (i < self.links.length){
self.links[i++](next(i), end);
}
}
};
next(0)();
}
var chain = new Chain();
var i = 0;
chain.link(function(next, end){
i++;
next();
});
chain.link(function(next, end){
i++;
end();
});
chain.link(function(next, end){
i++;
console.log('Should not have ran');
});
chain.run(function(){
Test.assertEquals(i, 2);
});