Skip to content

Commit a1a18eb

Browse files
committed
Merge branch 'master' of github.com:bkaestner/codewars-rules
2 parents 879d28f + efe02fc commit a1a18eb

File tree

7 files changed

+170
-30
lines changed

7 files changed

+170
-30
lines changed

pandoc.css

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ pre::after{
107107
pre.c:after{
108108
content:"C";
109109
}
110+
pre.bash:after{
111+
content:"bash";
112+
}
110113
pre.cs:after{
111114
content:"C#";
112115
}
@@ -125,9 +128,7 @@ pre.python:after{
125128
pre.ruby:after{
126129
content:"Ruby";
127130
}
128-
pre.c:after{
129-
content:"C";
130-
}
131+
131132
code {
132133
/* font-family: monospace; */
133134
}

publish.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ set -x
33
rev=$(git rev-parse --short HEAD)
44
branch=$(git rev-parse --abbrev-ref HEAD)
55

6+
echo Previous branch was $branch
7+
68
# If we cannot checkout master, stop immediately
79
git checkout master || exit 1
810

@@ -14,7 +16,7 @@ git checkout --orphan gh-pages || exit 1
1416

1517
# Ignore all already added files, but stop if we would forget
1618
# changes.
17-
git rm --cached \* || git checkout $branch && exit 1
19+
git rm --cached \* || exit 1
1820

1921
# Create the page
2022
make html
@@ -26,5 +28,4 @@ git commit -m "Publish GitHub pages, based on $rev"
2628
# Publish GH pages
2729
git push origin gh-pages -f
2830

29-
# Go back to previous branch
30-
git checkout $branch -f
31+
echo Use 'git checkout $branch -f' to change back to the previous branch.

rules/0100-Writing-a-kata.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ provide reflection or similar means to check your preloaded code, which enables
288288
a user to cheat rather easily. Instead, put your solution into a local scope
289289
(see [Hide your solution](#hide-your-solution)).
290290

291+
For more information about preloaded code, see [the next section](#the-preload-section).
292+
291293

292294
Provide helpers for tasks that are dull
293295
---------------------------------------
@@ -334,7 +336,7 @@ It's bad for several reasons:
334336

335337
- it doesn't return any helpful error message if the solution is wrong
336338
- it's not modular
337-
- it's not compatible to the CodeWars testing framework
339+
- it's not compatible to the Codewars testing framework
338340

339341
Another variant, which uses Hspec and random tests could be written as
340342

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
Intermezzo: The Codewars platform
2+
=================================
3+
4+
Now that you have read all those tips and tricks, you probably cannot
5+
wait to write your next kata, right? However, before you jump in, you
6+
should learn a little bit about the Codewars platform, if you want to
7+
run random tests or use the "preload" section.
8+
9+
10+
## How Codewars works
11+
12+
Whenever you write a kata, you have at least six input windows:
13+
14+
1. the description (cannot be blank)
15+
2. the initial solution (cannot be blank)
16+
3. the solution (cannot be blank)
17+
4. the example test fixtures
18+
5. the test fixtures (cannot be blank)
19+
6. the preloaded code
20+
21+
All of this is used by the [runner]. The runner is basically a `node`
22+
process, which calls the languages interpreter and either
23+
24+
- creates a temporary dictionary structure containing all code
25+
(Haskell, Java, CSharp or other module/file based languages)
26+
- or ___concatenates___ and passes the code to the interpreter via command
27+
line argument (Ruby, JavaScript, CoffeeScript, Python).
28+
29+
It then checks the output of the process for some fields, filters them,
30+
and shows the filtered text to the user. If the fields indicate that
31+
the user has passed the tests, they will have passed the kata.
32+
33+
This is the big difference between Codewars and other code running sites
34+
like SPOJ, Hackerrank and other. There, you will have to read from STDIN,
35+
and give formatted answers to STDOUT. You often don't learn details about
36+
your failed tests, only that you've failed them, since the tests are often
37+
only different `*.txt` files that get streamed into your file.
38+
39+
Unfortunately, the _running_ parts of the Codewars runner are currently
40+
missing in the repository, but still available in its history. They
41+
are lacking new content like transpilers though.
42+
43+
In case of JavaScript, the code will get transformed via [`babel`][babel]
44+
_before_ it is passed to `node`. All of this preprocessing is _not_
45+
counted into the users runtime.
46+
47+
However, the important part is the concatenation in interpreted languages.
48+
That's the part where you have to look out, since it works like this:
49+
50+
```bash
51+
$ cp python-framework run.py # add framework
52+
$ echo "" >> run.py
53+
$ cat preload.py >> run.py # add preloaded code
54+
$ echo "" >> run.py
55+
$ cat solution.py >> run.py # add user solution
56+
$ echo "" >> run.py
57+
$ cat tests.py >> run.py # add tests
58+
$ cat run.py | python -e -
59+
```
60+
61+
The `echo ""` parts are there for newlines. Either way, as you can see,
62+
all of your _and_ the user's code are in the same file. This means that
63+
while you have access on everything the user has defined, declared and
64+
written, it also means that they have access to everything you have written.
65+
66+
They can also change the test framework unless it's frozen. Keep in mind
67+
that there's an asynchronous cheating test, that adds non-passing tests.
68+
For example if the user solution exits prematurely with a "passed" output,
69+
they will get a penalty.
70+
71+
Note that there has been a [heated discussion][issue-214] about the tests
72+
in Ruby. @danielpclark discusses some of the issues in the thread, and its
73+
worth a read.
74+
75+
Now to the other languages. For Haskell, the runner will automatically
76+
create a temporary dictionary structure that matches the module names.
77+
This dictionary will reside in `/tmp/` and get run via `runhaskell`.
78+
The `hspec` framework has been replaced with another one that has some
79+
more features. Java and CSharp get handled similarly.
80+
81+
So remember: in interpreted languages, all your code and the user's code
82+
will reside in the same context, whereas in compiled languages all code
83+
will reside in the same directory.
84+
85+
By the way, this is the reason you cannot use `process.argv` in Node,
86+
as it would give a user immediate access to the tests.
87+
88+
[issue-214]: https://github.com/Codewars/codewars.com/issues/214
89+
[runner]: https://github.com/Codewars/codewars-runner
90+
[babel]: http://babeljs.io/
91+
92+
93+
## The "preloaded" section {#the-preload-section}
94+
95+
The preloaded section in the kata editor is meant for things that should
96+
be done first, before any other code (beside the import of the test framework)
97+
is being read, evaluated or executed (in interpreted languages).
98+
99+
You want to provide some extra functions for the user? Put them in the preloaded
100+
section.
101+
You want to disable features, like `Math.random` or `Math.abs`? Do
102+
so in the preloaded section.
103+
You want to make sure that no one panders the testing framework? Freeze it in
104+
the preloaded section.
105+
106+
I think you get it. In interpreted languages, use the preloaded section for
107+
whatever helper you think the user might need, and for whatever security measures
108+
you want to enable. It's the first thing that gets read during the execution, so
109+
you're still in charge at that point.
110+
111+
In Haskell, the preloaded section needs a module name and can be imported. It's
112+
handy for additional functions or data types, as disabling features is done there
113+
with `hidden`.

rules/0120-Tests.md

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
Tested testing theories
2-
------------------------
1+
# Tested testing theories
32

43
Tests are the bread and butter of Codewars. Without tests, you couldn't
54
check whether the user has solved your kata, so they're very important. Yet
@@ -13,7 +12,7 @@ cannot change the tests in approved katas with more than 500 solutions.
1312
[#123]: https://github.com/Codewars/codewars.com/issues/123
1413

1514

16-
### Make your test descriptive
15+
## Make your test descriptive
1716

1817
Let's have a look at the following test:
1918

@@ -45,7 +44,7 @@ Test.assertEquals(fizzBuzz(15), 'FizzBuzz', "testing on 15")
4544
This tells the user immediately that their function failed on `15`.
4645

4746

48-
#### Group your tests
47+
### Group your tests
4948

5049
Furthermore, you should group your tests with `describe` and `it`. After all,
5150
a tests _describes_ the behaviour of something, for example the behaviour
@@ -90,21 +89,47 @@ Test.describe('foo', function(){
9089
```
9190

9291

93-
#### Make errors obvious
92+
### Make errors obvious
9493

9594
Especially if you use random tests (see below), you want to make sure that the
9695
user knows _why_ the test failed. You could print the arguments. You could
9796
show a hint. Either way, a user shouldn't be left alone in face of an error.
9897

99-
### Always test all corner cases of your input domain
98+
99+
### Think of the HTML
100+
101+
Keep in mind that every output will be interpreted as HTML. If you want to
102+
use `<`, `>` or `&` in your error messages or description, make sure to
103+
escape it---unless you actually want to use HTML tags:
104+
105+
Character | [HTML entity] | Mnemonic
106+
----------|---------------|-------------------------------------------
107+
`<` | `&lt;` | **l**esser **t**han
108+
`>` | `&gt;` | **g**reater **t**han
109+
`&` | `&amp;` | **amp**ersand
110+
111+
All other characters are usually safe to use in UTF8 encoded documents.
112+
113+
[HTML entity]: http://dev.w3.org/html5/html-author/charref
114+
115+
116+
## Always test all corner cases of your input domain
100117

101118
If you ask the user to create a function that should work for
102119
`1 <= N <= 1,000,000`, make sure that their function works for *both* 1 and
103120
1,000,000. If you specified that "negative input should return a monkey",
104121
make sure that you actually test negative input.
105122

106123

107-
### Use random tests
124+
## Use the tools of your testing framework
125+
126+
If possible, try to use multiple kinds of assertions, e.g. `assertEquals`
127+
and `assertNotEquals`, or `shouldSatisfy` and `shouldNotSatisfy`. That
128+
way, a cheating user will have some more work to circumvent equality or
129+
predicate based tests.
130+
131+
132+
## Use random tests
108133

109134
Whenever when you state a kata you also have to write a solution. This is
110135
great, as you can use exactly that function to check the users code
@@ -116,7 +141,7 @@ sufficient random input is most often harder than creating the kata itself.
116141
But it is worth every honour.
117142

118143

119-
### Use __more__ random tests
144+
## Use __more__ random tests
120145

121146
While it's nice to have a random test which validates that the user returns
122147
the same as your hidden solution, there's no guarantee that your solution
@@ -152,7 +177,7 @@ Test.it('returns something valid', function(){
152177
```
153178

154179

155-
### Hide your solution
180+
## Hide your solution
156181

157182
If you use random tests, make sure to hide your solution. In Java or C#, this
158183
includes making your function `private`. Haskell doesn't allow mutual imports,
@@ -185,14 +210,14 @@ There are more creative ways to hide/store the function, but that's one way
185210
at least. Note that all dynamic languages on Codewars (Ruby, Python, CS, JS)
186211
support this kind of local scopes.
187212

188-
### Always have some example tests
213+
## Always have some example tests
189214

190215
Unless you're creating a puzzle where the user has to find *the answer*,
191216
present some example tests. Those tests should also contain the corner
192217
cases and some easy random tests, e.g. check that the user actually returns
193218
a number for arbitrary negative numbers.
194219

195-
### Handle floating point values the right way
220+
## Handle floating point values the right way
196221

197222
Whenever the user returns a floating point number, make sure that you take
198223
floating point behaviour into account. The user might not add the numbers
@@ -210,7 +235,7 @@ want to have something "almost exact" and `1e-7` if I want something
210235
For more information about floating-point arithmetic, read
211236
[What Every Computer Scientist Should Know About Floating-Point Arithmetic](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).
212237

213-
#### An example of floating point dangers
238+
### An example of floating point dangers
214239

215240
```python
216241
def add_three(a,b,c):
@@ -223,7 +248,7 @@ print(add_three_reference(1e-12,1e-12,1) == add_three(1e-12,1e-12,1))
223248
# False
224249
```
225250

226-
#### Relative error testing
251+
### Relative error testing
227252

228253
The following example shows one way to check floating point values in a more
229254
sane way:
@@ -250,14 +275,14 @@ def assertFuzzyEquals(actual, expected, msg=""):
250275
Most language sections contain their equivalent and use `expect` or a similar
251276
function of their test framework.
252277

253-
#### Consider integral tests
278+
### Consider integral tests
254279

255280
If your number is guaranteed to be an integral number, use `int`, `long`
256281
or your language's equivalent instead of floating point numbers. However, keep
257282
in mind that all values, either input, output, or intermediate should fit in
258283
this type, otherwise you might encounter overflow or underflow issues.
259284

260-
### Fix broken tests early and fix them right
285+
## Fix broken tests early and fix them right
261286

262287
While [#163](https://github.com/Codewars/codewars.com/issues/163) will give you
263288
the tools to fix a kata even late, you should take every reported test issue by
@@ -277,17 +302,17 @@ might get rejected.
277302

278303
So what can you do?
279304

280-
#### Change description to address the bug
305+
### Change description to address the bug
281306
You should definitely tell your users if your kata is broken. Especially if your
282307
tests have a defect in only one particular language. It's not the best you can
283308
do, but as long as #163 is still there, it might be the only thing you can do.
284309

285-
#### Reject old solutions, they didn't follow the description
310+
### Reject old solutions, they didn't follow the description
286311
This is fine as long as there haven't been many solutions. If your kata has been
287312
solved by hundreds, it might seem a little bit unfair, but correct tests are
288313
a little bit more important.
289314

290-
#### Experimental solutions
315+
### Experimental solutions
291316
There are also other alternatives:
292317

293318
- check the time: if the kata solution is submitted after a certain point in

rules/0140-Collaborating.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
Collaborative Codewars Catches
2-
------------------------------
1+
## Collaborative Codewars Catches
32

4-
The previous section mentioned some practices for your tests. However,
3+
The previous sections mentioned some practices for your tests. However,
54
what if you don't know Haskell? Or Java? Or Ruby? You shouldn't provide
65
tests for a language you don't know, as this will usually lead to bugs
76
in your test cases (see section

rules/0260-JavaScript.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
JavaScript / CoffeeScript
22
-------------------------
33

4-
The JavaScript tests on CodeWars use a [custom] test framework. Any kata written
4+
The JavaScript tests on Codewars use a [custom] test framework. Any kata written
55
in CoffeeScript will use the same framework, since CoffeeScript gets compiled
66
to JavaScript.
77

@@ -11,7 +11,6 @@ you won't get the real source code if you use `.toString()`, but the result of
1111
the Babel compiler.
1212

1313
[custom]: http://www.codewars.com/docs/js-slash-coffeescript-test-reference
14-
[Babel]: https://babeljs.io/
1514

1615

1716
### Floating point tests

0 commit comments

Comments
 (0)