This commit is contained in:
Ilya Kantor 2017-02-23 19:03:14 +03:00
parent 20784e7f26
commit 7019d1470d
48 changed files with 1019 additions and 464 deletions

View file

@ -1,50 +1,48 @@
# Ответ
Вы могли заметить следующие недостатки, сверху-вниз:
You could note the following:
```js no-beautify
function pow(x,n) // <- отсутствует пробел между аргументами
{ // <- фигурная скобка на отдельной строке
var result=1; // <- нет пробелов вокруг знака =
for(var i=0;i<n;i++) {result*=x;} // <- нет пробелов
// содержимое скобок { ... } лучше вынести на отдельную строку
function pow(x,n) // <- no space between arguments
{ // <- figure bracket on a separate line
let result=1; // <- no spaces to the both sides of =
for(let i=0;i<n;i++) {result*=x;} // <- no spaces
// the contents of { ... } should be on a new line
return result;
}
x=prompt("x?",'') // <- не объявлена переменная, нет пробелов, ;
n=prompt("n?",'')
if (n<0) // <- нет пробелов, стоит добавить вертикальную отбивку
{ // <- фигурная скобка на отдельной строке
// ниже - слишком длинная строка, нет пробелов
alert('Степень '+n+'не поддерживается, введите целую степень, большую 0');
let x=prompt("x?",''), n=prompt("n?",'') // <-- technically possible,
// but better make it 2 lines, also there's no spaces and ;
if (n<0) // <- no spaces inside (n < 0), and should be extra line above it
{ // <- figure bracket on a separate line
// below - a long line, may be worth to split into 2 lines
alert(`Power ${n} is not supported, please enter an integer number greater than zero`);
}
else // <- можно на одной строке } else {
else // <- could write it on a single line like "} else {"
{
alert(pow(x,n)) // нет точки с запятой
alert(pow(x,n)) // no spaces and ;
}
```
Исправленный вариант:
The fixed variant:
```js
function pow(x, n) {
var result = 1;
let result = 1;
for (var i = 0; i < n; i++) {
for (let i = 0; i < n; i++) {
result *= x;
}
return result;
}
var x = prompt("x?", "");
var n = prompt("n?", "");
let x = prompt("x?", "");
let n = prompt("n?", "");
if (n < 0) {
alert('Степень ' + n +
'не поддерживается, введите целую степень, большую 0');
alert(`Power ${n} is not supported,
please enter an integer number greater than zero`);
} else {
alert( pow(x, n) );
}
```

View file

@ -2,23 +2,22 @@ importance: 4
---
# Ошибки в стиле
# Bad style
Какие недостатки вы видите в стиле этого примера?
What's wrong with the code style below?
```js no-beautify
function pow(x,n)
{
var result=1;
for(var i=0;i<n;i++) {result*=x;}
let result=1;
for(let i=0;i<n;i++) {result*=x;}
return result;
}
x=prompt("x?",'')
n=prompt("n?",'')
let x=prompt("x?",''), n=prompt("n?",'')
if (n<=0)
{
alert('Степень '+n+'не поддерживается, введите целую степень, большую 0');
alert(`Power ${n} is not supported, please enter an integer number greater than zero`);
}
else
{
@ -26,3 +25,4 @@ else
}
```
Fix it.

View file

@ -1,10 +0,0 @@
function pow(x, n) {
if (n < 0) return NaN;
if (Math.round(n) != n) return NaN;
var result = 1;
for (var i = 0; i < n; i++) {
result *= x;
}
return result;
}

View file

@ -1,8 +0,0 @@
/* исправьте этот код */
function pow(x, n) {
var result = 1;
for (var i = 0; i < n; i++) {
result *= x;
}
return result;
}

View file

@ -1,26 +0,0 @@
describe("pow", function() {
describe("возводит x в степень n", function() {
function makeTest(x) {
var expected = x * x * x;
it("при возведении " + x + " в степень 3 результат: " + expected, function() {
assert.equal(pow(x, 3), expected);
});
}
for (var x = 1; x <= 5; x++) {
makeTest(x);
}
});
it("при возведении в отрицательную степень результат NaN", function() {
assert(isNaN(pow(2, -1)), "pow(2, -1) не NaN");
});
it("при возведении в дробную степень результат NaN", function() {
assert(isNaN(pow(2, 1.5)), "pow(2, -1.5) не NaN");
});
});

View file

@ -1,17 +0,0 @@
```js
function pow(x, n) {
*!*
if (n < 0) return NaN;
if (Math.round(n) != n) return NaN;
*/!*
var result = 1;
for (var i = 0; i < n; i++) {
result *= x;
}
return result;
}
```

View file

@ -1,19 +0,0 @@
importance: 5
---
# Сделать pow по спецификации
Исправьте код функции `pow`, чтобы тесты проходили.
Для этого ниже в задаче вы найдёте ссылку на песочницу.
Она содержит HTML с тестами. Обратите внимание, что HTML-страница в ней короче той, что обсуждалась в статье <info:testing>. Это потому что библиотеки Chai, Mocha и Sinon объединены в один файл:
```html
<script src="https://js.cx/test/libs.js"></script>
```
Этот файл содержит код библиотек, стили, настройки для них и запуск `mocha.run` по окончании загрузки страницы. Если нет элемента с `id="mocha"`, то результаты выводятся в `<body>`.
Сборка сделана исключительно для более компактного представления задач, без рекомендаций использовать именно её в проектах.

View file

@ -1,38 +0,0 @@
Новый тест может быть, к примеру, таким:
```js
it("любое число в степени 0 равно 1", function() {
assert.equal(pow(123, 0), 1);
});
```
Конечно, желательно проверить на нескольких числах.
Поэтому лучше будет создать блок `describe`, аналогичный тому, что мы делали для произвольных чисел:
```js
describe("любое число, кроме нуля, в степени 0 равно 1", function() {
function makeTest(x) {
it("при возведении " + x + " в степень 0 результат: 1", function() {
assert.equal(pow(x, 0), 1);
});
}
for (var x = -5; x <= 5; x += 2) {
makeTest(x);
}
});
```
И не забудем добавить отдельный тест для нуля:
```js no-beautify
...
it("ноль в нулевой степени даёт NaN", function() {
assert( isNaN(pow(0, 0)), "0 в степени 0 не NaN");
});
...
```

View file

@ -1,27 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://js.cx/test/libs.js"></script>
<script src="test.js"></script>
</head>
<body>
<script>
function pow(x, n) {
if (n < 0) return NaN;
if (Math.round(n) != n) return NaN;
if (n == 0 && x == 0) return NaN;
var result = 1;
for (var i = 0; i < n; i++) {
result *= x;
}
return result;
}
</script>
</body>
</html>

View file

@ -1,44 +0,0 @@
describe("pow", function() {
describe("возводит x в степень n", function() {
function makeTest(x) {
var expected = x * x * x;
it("при возведении " + x + " в степень 3 результат: " + expected, function() {
assert.equal(pow(x, 3), expected);
});
}
for (var x = 1; x <= 5; x++) {
makeTest(x);
}
});
it("при возведении в отрицательную степень результат NaN", function() {
assert(isNaN(pow(2, -1)), "pow(2, -1) не NaN");
});
it("при возведении в дробную степень результат NaN", function() {
assert(isNaN(pow(2, 1.5)), "pow(2, -1.5) не NaN");
});
describe("любое число, кроме нуля, в степени 0 равно 1", function() {
function makeTest(x) {
it("при возведении " + x + " в степень 0 результат: 1", function() {
assert.equal(pow(x, 0), 1);
});
}
for (var x = -5; x <= 5; x += 2) {
makeTest(x);
}
});
it("ноль в нулевой степени даёт NaN", function() {
assert(isNaN(pow(0, 0)), "0 в степени 0 не NaN");
});
});

View file

@ -1,26 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://js.cx/test/libs.js"></script>
<script src="test.js"></script>
</head>
<body>
<script>
function pow(x, n) {
if (n < 0) return NaN;
if (Math.round(n) != n) return NaN;
var result = 1;
for (var i = 0; i < n; i++) {
result *= x;
}
return result;
}
</script>
</body>
</html>

View file

@ -1,26 +0,0 @@
describe("pow", function() {
describe("возводит x в степень n", function() {
function makeTest(x) {
var expected = x * x * x;
it("при возведении " + x + " в степень 3 результат: " + expected, function() {
assert.equal(pow(x, 3), expected);
});
}
for (var x = 1; x <= 5; x++) {
makeTest(x);
}
});
it("при возведении в отрицательную степень результат NaN", function() {
assert(isNaN(pow(2, -1)), "pow(2, -1) не NaN");
});
it("при возведении в дробную степень результат NaN", function() {
assert(isNaN(pow(2, 1.5)), "pow(2, -1.5) не NaN");
});
});

View file

@ -1,9 +0,0 @@
importance: 5
---
# Добавьте тест к задаче
Добавьте к [предыдущей задаче](/task/pow-nan-spec) тесты, которые будут проверять, что любое число, кроме нуля, в нулевой степени равно `1`, а ноль в нулевой степени даёт `NaN` (это математически корректно, результат 0<sup>0</sup> не определён).
При необходимости, исправьте реализацию, чтобы тесты проходили без ошибок.

View file

@ -4,28 +4,47 @@ What we have here is actually 3 tests, but layed out as a single function with 3
Sometimes it's easier to write this way, but if an error occurs, it's much less obvious what went wrong.
If an error happens inside a complex execution flow, then we'll have to figure out what was the data at that point.
If an error happens inside a complex execution flow, then we'll have to figure out the data at that point. We'll actually have to *debug the test*.
TODO
Если в сложном тесте произошла ошибка где-то посередине потока вычислений, то придётся выяснять, какие конкретно были входные и выходные данные на этот момент, то есть по сути -- отлаживать код самого теста.
Гораздо лучше будет разбить тест на несколько блоков `it`, с чётко прописанными входными и выходными данными.
It would be much better to break the test into multiple `it` blocks with clearly written inputs and outputs.
Like this:
```js
describe("Возводит x в степень n", function() {
it("5 в степени 1 равно 5", function() {
describe("Raises x to power n", function() {
it("5 in the power of 1 equals 5", function() {
assert.equal(pow(5, 1), 5);
});
it("5 в степени 2 равно 25", function() {
it("5 in the power of 2 equals 25", function() {
assert.equal(pow(5, 2), 25);
});
it("5 в степени 3 равно 125", function() {
it("5 in the power of 3 equals 125", function() {
assert.equal(pow(5, 3), 125);
});
});
```
Можно использовать цикл для генерации блоков `it`, в этом случае важно, чтобы сам код такого цикла был достаточно простым. Иногда проще записать несколько блоков `it` вручную, как сделано выше, чем "городить огород" из синтаксических конструкций.
We replaced the single `it` with `describe` and a group of `it` blocks. Now if something fails we would see clearly what the data was.
Also we can isolate a single test and run it in standalone mode by writing `it.only` instead of `it`:
```js
describe("Raises x to power n", function() {
it("5 in the power of 1 equals 5", function() {
assert.equal(pow(5, 1), 5);
});
*!*
// Mocha will run only this block
it.only("5 in the power of 2 equals 25", function() {
assert.equal(pow(5, 2), 25);
});
*/!*
it("5 in the power of 3 equals 125", function() {
assert.equal(pow(5, 3), 125);
});
});
```