test: add tests for translated challenge parser
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
f9ffcf0c61
commit
fa931134a4
@@ -0,0 +1,149 @@
|
||||
const ENGLISH_CHALLENGE = {
|
||||
id: 'id',
|
||||
title: 'Title',
|
||||
challengeType: 0,
|
||||
videoUrl: 'https://scrimba.com/',
|
||||
forumTopicId: 12345,
|
||||
tests: [
|
||||
{
|
||||
text: 'Test text',
|
||||
testString: 'assertions'
|
||||
},
|
||||
{
|
||||
text: 'Test text2',
|
||||
testString: 'assertions2'
|
||||
}
|
||||
],
|
||||
solutions: ['solution html string'],
|
||||
description: 'description html string',
|
||||
instructions: 'instructions html string',
|
||||
files: [
|
||||
{
|
||||
key: 'indexhtml',
|
||||
ext: 'html',
|
||||
name: 'index',
|
||||
contents: 'seed html string',
|
||||
head: 'head string',
|
||||
tail: 'tail string'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const ENGLISH_CHALLENGE_TWO_SOLUTIONS = {
|
||||
id: 'id',
|
||||
title: 'Title',
|
||||
challengeType: 0,
|
||||
videoUrl: 'https://scrimba.com/',
|
||||
forumTopicId: 12345,
|
||||
tests: [
|
||||
{
|
||||
text: 'Test text',
|
||||
testString: 'assertions'
|
||||
},
|
||||
{
|
||||
text: 'Test text2',
|
||||
testString: 'assertions2'
|
||||
}
|
||||
],
|
||||
solutions: ['solution html string', 'second solution html string'],
|
||||
description: 'description html string',
|
||||
instructions: 'instructions html string',
|
||||
files: [
|
||||
{
|
||||
key: 'indexhtml',
|
||||
ext: 'html',
|
||||
name: 'index',
|
||||
contents: 'seed html string',
|
||||
head: '',
|
||||
tail: ''
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const ENGLISH_CHALLENGE_NO_FILES = {
|
||||
id: 'id',
|
||||
title: 'Title',
|
||||
challengeType: 0,
|
||||
videoUrl: 'https://scrimba.com/',
|
||||
forumTopicId: 12345,
|
||||
tests: [
|
||||
{
|
||||
text: 'Test text',
|
||||
testString: 'assertions'
|
||||
},
|
||||
{
|
||||
text: 'Test text2',
|
||||
testString: 'assertions2'
|
||||
}
|
||||
],
|
||||
solutions: ['solution html string'],
|
||||
description: 'description html string',
|
||||
instructions: 'instructions html string',
|
||||
files: []
|
||||
};
|
||||
|
||||
const TRANSLATED_CHALLENGE = {
|
||||
id: 'id',
|
||||
title: 'Title',
|
||||
challengeType: 0,
|
||||
videoUrl: 'https://scrimba.com/',
|
||||
forumTopicId: 9876,
|
||||
localeTitle: 'Translated title',
|
||||
tests: [
|
||||
{
|
||||
text: 'Translated test text',
|
||||
testString: 'Translated assertions, should be ignored'
|
||||
},
|
||||
{
|
||||
text: 'Translated test text2',
|
||||
testString: 'Translated assertions, should be ignored2'
|
||||
}
|
||||
],
|
||||
solutions: ['Translated solution html string, should be ignored'],
|
||||
description: 'Translated description html string',
|
||||
instructions: 'Translated instructions html string',
|
||||
files: [
|
||||
{
|
||||
key: 'indexhtml',
|
||||
ext: 'html',
|
||||
name: 'index',
|
||||
contents: 'Translated seed html string, should be ignored',
|
||||
head: 'Translated head string, should be ignored',
|
||||
tail: 'Translated tail string, should be ignored'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const WRONG_NUM_TESTS_CHALLENGE = {
|
||||
id: 'id',
|
||||
title: 'Title',
|
||||
challengeType: 0,
|
||||
videoUrl: 'https://scrimba.com/',
|
||||
forumTopicId: 12345,
|
||||
localeTitle: 'Translated title',
|
||||
tests: [
|
||||
{
|
||||
text: 'Translated test text',
|
||||
testString: 'Translated assertions, should be ignored'
|
||||
}
|
||||
],
|
||||
solutions: ['Translated solution html string, should be ignored'],
|
||||
description: 'Translated description html string',
|
||||
instructions: 'Translated instructions html string',
|
||||
files: [
|
||||
{
|
||||
key: 'indexhtml',
|
||||
ext: 'html',
|
||||
name: 'index',
|
||||
contents: 'Translated seed html string, should be ignored',
|
||||
head: '',
|
||||
tail: ''
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
exports.ENGLISH_CHALLENGE = ENGLISH_CHALLENGE;
|
||||
exports.ENGLISH_CHALLENGE_TWO_SOLUTIONS = ENGLISH_CHALLENGE_TWO_SOLUTIONS;
|
||||
exports.ENGLISH_CHALLENGE_NO_FILES = ENGLISH_CHALLENGE_NO_FILES;
|
||||
exports.TRANSLATED_CHALLENGE = TRANSLATED_CHALLENGE;
|
||||
exports.WRONG_NUM_TESTS_CHALLENGE = WRONG_NUM_TESTS_CHALLENGE;
|
@@ -0,0 +1,16 @@
|
||||
const SIMPLE_TRANSLATION = {
|
||||
'Add your code below this line': {
|
||||
chinese: '(Chinese) Add your code below this line (Chinese)'
|
||||
},
|
||||
'Add your code above this line': {
|
||||
chinese: '(Chinese) Add your code above this line (Chinese)'
|
||||
},
|
||||
'change code below this line': {
|
||||
chinese: '(Chinese) change code below this line (Chinese)'
|
||||
},
|
||||
'change code above this line': {
|
||||
chinese: '(Chinese) change code above this line (Chinese)'
|
||||
}
|
||||
};
|
||||
|
||||
exports.SIMPLE_TRANSLATION = SIMPLE_TRANSLATION;
|
@@ -0,0 +1,337 @@
|
||||
/* global expect jest */
|
||||
const {
|
||||
mergeChallenges,
|
||||
translateComments,
|
||||
translateCommentsInChallenge
|
||||
} = require('./translation-parser');
|
||||
const {
|
||||
ENGLISH_CHALLENGE,
|
||||
ENGLISH_CHALLENGE_NO_FILES,
|
||||
ENGLISH_CHALLENGE_TWO_SOLUTIONS,
|
||||
TRANSLATED_CHALLENGE,
|
||||
WRONG_NUM_TESTS_CHALLENGE
|
||||
} = require('./__fixtures__/challenge-objects');
|
||||
const { SIMPLE_TRANSLATION } = require('./__mocks__/mock-comments');
|
||||
|
||||
const COMBINED_CHALLENGE = mergeChallenges(
|
||||
ENGLISH_CHALLENGE,
|
||||
TRANSLATED_CHALLENGE
|
||||
);
|
||||
|
||||
const COMBINED_CHALLENGE_TWO_SOLUTIONS = mergeChallenges(
|
||||
ENGLISH_CHALLENGE_TWO_SOLUTIONS,
|
||||
TRANSLATED_CHALLENGE
|
||||
);
|
||||
let logSpy;
|
||||
|
||||
describe('translation parser', () => {
|
||||
beforeEach(() => {
|
||||
logSpy = jest.spyOn(console, 'warn').mockImplementation();
|
||||
});
|
||||
afterEach(() => {
|
||||
logSpy.mockRestore();
|
||||
});
|
||||
describe('mergeChallenges', () => {
|
||||
it('takes the description from the second challenge', () => {
|
||||
expect(COMBINED_CHALLENGE.description).toBe(
|
||||
TRANSLATED_CHALLENGE.description
|
||||
);
|
||||
});
|
||||
it('takes the head and tail from the first challenge', () => {
|
||||
expect(COMBINED_CHALLENGE.files[0].head).toBe(
|
||||
ENGLISH_CHALLENGE.files[0].head
|
||||
);
|
||||
expect(COMBINED_CHALLENGE.files[0].tail).toBe(
|
||||
ENGLISH_CHALLENGE.files[0].tail
|
||||
);
|
||||
});
|
||||
it('takes the instructions from the second challenge', () => {
|
||||
expect(COMBINED_CHALLENGE.instructions).toBe(
|
||||
TRANSLATED_CHALLENGE.instructions
|
||||
);
|
||||
});
|
||||
it('takes the seed from the first challenge', () => {
|
||||
expect(COMBINED_CHALLENGE.files[0].contents).toBe(
|
||||
ENGLISH_CHALLENGE.files[0].contents
|
||||
);
|
||||
});
|
||||
it('takes the solution from the first challenge', () => {
|
||||
expect(COMBINED_CHALLENGE.solutions[0]).toBe(
|
||||
ENGLISH_CHALLENGE.solutions[0]
|
||||
);
|
||||
});
|
||||
it('takes multiple solutions', () => {
|
||||
expect(COMBINED_CHALLENGE_TWO_SOLUTIONS.solutions).toEqual(
|
||||
ENGLISH_CHALLENGE_TWO_SOLUTIONS.solutions
|
||||
);
|
||||
});
|
||||
it('takes the testStrings from the first challenge', () => {
|
||||
const actualStrings = COMBINED_CHALLENGE.tests.map(
|
||||
({ testString }) => testString
|
||||
);
|
||||
const expectedStrings = ENGLISH_CHALLENGE.tests.map(
|
||||
({ testString }) => testString
|
||||
);
|
||||
for (let i = 0; i < actualStrings.length; i++) {
|
||||
expect(actualStrings[i]).toBe(expectedStrings[i]);
|
||||
}
|
||||
});
|
||||
it('takes the test text from the second challenge', () => {
|
||||
const actualStrings = COMBINED_CHALLENGE.tests.map(({ text }) => text);
|
||||
const expectedStrings = TRANSLATED_CHALLENGE.tests.map(
|
||||
({ text }) => text
|
||||
);
|
||||
for (let i = 0; i < actualStrings.length; i++) {
|
||||
expect(actualStrings[i]).toBe(expectedStrings[i]);
|
||||
}
|
||||
});
|
||||
it('takes the localTitle from the second challenge', () => {
|
||||
expect(COMBINED_CHALLENGE.localeTitle).toBe(
|
||||
TRANSLATED_CHALLENGE.localeTitle
|
||||
);
|
||||
});
|
||||
it('throws an error if the numbers of tests do not match', () => {
|
||||
expect(() =>
|
||||
mergeChallenges(ENGLISH_CHALLENGE, WRONG_NUM_TESTS_CHALLENGE)
|
||||
).toThrow();
|
||||
});
|
||||
it('takes the forum id from the second challenge', () => {
|
||||
expect(COMBINED_CHALLENGE.forumTopicId).toBe(
|
||||
TRANSLATED_CHALLENGE.forumTopicId
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('translateCommentsInChallenge', () => {
|
||||
it('returns a clone of the challenge if there are no comments', () => {
|
||||
expect(
|
||||
translateCommentsInChallenge(
|
||||
ENGLISH_CHALLENGE_NO_FILES,
|
||||
'chinese',
|
||||
SIMPLE_TRANSLATION
|
||||
)
|
||||
).toEqual(ENGLISH_CHALLENGE_NO_FILES);
|
||||
});
|
||||
});
|
||||
describe('translateComments', () => {
|
||||
it('replaces single line English comments with their translations', () => {
|
||||
const seed = `// Add your code below this line
|
||||
Add your code above this line `;
|
||||
const transSeed = `// (Chinese) Add your code below this line (Chinese)
|
||||
Add your code above this line `;
|
||||
expect(translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'js')).toBe(
|
||||
transSeed
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces inline English comments with their translations', () => {
|
||||
const seed = `inline comment // Add your code below this line
|
||||
Add your code above this line `;
|
||||
const transSeed = `inline comment // (Chinese) Add your code below this line (Chinese)
|
||||
Add your code above this line `;
|
||||
expect(translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'js')).toBe(
|
||||
transSeed
|
||||
);
|
||||
});
|
||||
|
||||
// If a comment follows '"` it could be inside a string, so we should
|
||||
// not try and translate it - erring on the side of caution.
|
||||
it('should ignore comments if they follow an open quote', () => {
|
||||
const seed = `var str = '// Add your code below this line'
|
||||
var str2 = '// Add your code above this line`;
|
||||
expect(translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'js')).toBe(
|
||||
seed
|
||||
);
|
||||
});
|
||||
it('replaces multiple English comments with their translations', () => {
|
||||
const seed = `inline comment // Add your code below this line
|
||||
// Add your code below this line `;
|
||||
const transSeed = `inline comment // (Chinese) Add your code below this line (Chinese)
|
||||
// (Chinese) Add your code below this line (Chinese) `;
|
||||
expect(translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'js')).toBe(
|
||||
transSeed
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces multiline English comments with their translations', () => {
|
||||
const seed = `multiline comment /* Add your code below this line */
|
||||
/* Add your code above this line */ change code below this line `;
|
||||
const transSeed = `multiline comment /* (Chinese) Add your code below this line (Chinese) */
|
||||
/* (Chinese) Add your code above this line (Chinese) */ change code below this line `;
|
||||
expect(translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'js')).toBe(
|
||||
transSeed
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces repeated multiline comments with their translations', () => {
|
||||
const seed = `multiline comment /* Add your code below this line */
|
||||
/* Add your code below this line */ change code below this line `;
|
||||
const transSeed = `multiline comment /* (Chinese) Add your code below this line (Chinese) */
|
||||
/* (Chinese) Add your code below this line (Chinese) */ change code below this line `;
|
||||
expect(translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'js')).toBe(
|
||||
transSeed
|
||||
);
|
||||
});
|
||||
|
||||
it('only replaces text inside comments, not between them', () => {
|
||||
const seed = `multiline comment /* Add your code below this line */
|
||||
/* Add your code above this line */ Add your code below this line /* */ `;
|
||||
const transSeed = `multiline comment /* (Chinese) Add your code below this line (Chinese) */
|
||||
/* (Chinese) Add your code above this line (Chinese) */ Add your code below this line /* */ `;
|
||||
expect(translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'js')).toBe(
|
||||
transSeed
|
||||
);
|
||||
|
||||
const seedTwo = `multiline /* */ Add your code below this line /* */ `;
|
||||
expect(
|
||||
translateComments(seedTwo, 'chinese', SIMPLE_TRANSLATION, 'js')
|
||||
).toBe(seedTwo);
|
||||
});
|
||||
|
||||
it('replaces English html comments with their translations', () => {
|
||||
const seed = `<div> <!-- Add your code below this line -->
|
||||
<!-- Add your code above this line --> <span>change code below this line</span> `;
|
||||
const transSeed = `<div> <!-- (Chinese) Add your code below this line (Chinese) -->
|
||||
<!-- (Chinese) Add your code above this line (Chinese) --> <span>change code below this line</span> `;
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'html')
|
||||
).toBe(transSeed);
|
||||
});
|
||||
|
||||
it('replaces css comments with their translations', () => {
|
||||
const seed = `<style>
|
||||
/* Add your code below this line */
|
||||
</style>`;
|
||||
const transSeed = `<style>
|
||||
/* (Chinese) Add your code below this line (Chinese) */
|
||||
</style>`;
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'html')
|
||||
).toBe(transSeed);
|
||||
});
|
||||
|
||||
it('replaces multiple css comments with their translations', () => {
|
||||
const seed = `<style>
|
||||
/* Add your code below this line */
|
||||
/* Add your code below this line */
|
||||
</style>`;
|
||||
const transSeed = `<style>
|
||||
/* (Chinese) Add your code below this line (Chinese) */
|
||||
/* (Chinese) Add your code below this line (Chinese) */
|
||||
</style>`;
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'html')
|
||||
).toBe(transSeed);
|
||||
});
|
||||
|
||||
it('ignores css comments outside style tags', () => {
|
||||
const seed = `/* Add your code below this line */`;
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'html')
|
||||
).toBe(seed);
|
||||
});
|
||||
|
||||
it('ignores css comments between style tags', () => {
|
||||
const seed = `<style>
|
||||
</style>
|
||||
/* Add your code below this line */
|
||||
<style>
|
||||
</style>`;
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'html')
|
||||
).toBe(seed);
|
||||
});
|
||||
|
||||
it('only replaces inside English html comments', () => {
|
||||
const seed = `<div> <!-- --> Add your code below this line <!-- -->`;
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'html')
|
||||
).toBe(seed);
|
||||
});
|
||||
|
||||
it('replaces English JSX comments with their translations', () => {
|
||||
const seed = `{ /* Add your code below this line */ }
|
||||
{ /* Add your code above this line */ } <span>change code below this line</span> `;
|
||||
const transSeed = `{ /* (Chinese) Add your code below this line (Chinese) */ }
|
||||
{ /* (Chinese) Add your code above this line (Chinese) */ } <span>change code below this line</span> `;
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'jsx')
|
||||
).toBe(transSeed);
|
||||
});
|
||||
|
||||
it('ignores html comments inside JavaScript', () => {
|
||||
const seed = `<div> <!-- Add your code below this line
|
||||
Add your code above this line --> <span>change code below this line</span> `;
|
||||
expect(translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'js')).toBe(
|
||||
seed
|
||||
);
|
||||
});
|
||||
|
||||
it('ignores html comments inside jsx', () => {
|
||||
const seed = `<div> <!-- Add your code below this line
|
||||
Add your code above this line --> <span>change code below this line</span> `;
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'jsx')
|
||||
).toBe(seed);
|
||||
});
|
||||
|
||||
it('only replaces exact matches (js)', () => {
|
||||
const seedMulti = `/* Add your code below this line
|
||||
Add your code above this line */ <span>change code below this line</span> `;
|
||||
const seedInline = `// Add your code below this line, please`;
|
||||
expect(
|
||||
translateComments(seedMulti, 'chinese', SIMPLE_TRANSLATION, 'js')
|
||||
).toBe(seedMulti);
|
||||
expect(
|
||||
translateComments(seedInline, 'chinese', SIMPLE_TRANSLATION, 'js')
|
||||
).toBe(seedInline);
|
||||
});
|
||||
|
||||
it('only replaces exact matches (jsx)', () => {
|
||||
const seedMulti = `{ /* Add your code below this line
|
||||
Add your code above this line */ } <span>change code below this line</span> `;
|
||||
expect(
|
||||
translateComments(seedMulti, 'chinese', SIMPLE_TRANSLATION, 'jsx')
|
||||
).toBe(seedMulti);
|
||||
});
|
||||
|
||||
it('only replaces exact matches (html)', () => {
|
||||
const seed = `<div> <!-- Add your code below this line
|
||||
Add your code above this line --> <span>change code below this line</span> `;
|
||||
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'html')
|
||||
).toBe(seed);
|
||||
});
|
||||
|
||||
it('only translates jsx comments once', () => {
|
||||
const seed = `{ /* Add your code below this line */ }`;
|
||||
const transSeed = `{ /* (Chinese) Add your code below this line (Chinese) */ }`;
|
||||
expect(
|
||||
translateComments(seed, 'chinese', SIMPLE_TRANSLATION, 'jsx')
|
||||
).toBe(transSeed);
|
||||
});
|
||||
|
||||
it('warns if the comment is not in the dictionary', () => {
|
||||
const seedJSX = `{ /* this is not a comment */ }`;
|
||||
const seedInline = `// this is not a comment `;
|
||||
const seedMulti = `/* this is not a comment */`;
|
||||
const seedCSS = `<style>
|
||||
/* this is not a comment */
|
||||
</style>`;
|
||||
const seedHTML = `<div> <!-- this is not a comment --> `;
|
||||
|
||||
translateComments(seedJSX, 'chinese', SIMPLE_TRANSLATION, 'jsx');
|
||||
expect(logSpy).toBeCalledTimes(1);
|
||||
translateComments(seedInline, 'chinese', SIMPLE_TRANSLATION, 'js');
|
||||
expect(logSpy).toBeCalledTimes(2);
|
||||
translateComments(seedMulti, 'chinese', SIMPLE_TRANSLATION, 'js');
|
||||
expect(logSpy).toBeCalledTimes(3);
|
||||
translateComments(seedCSS, 'chinese', SIMPLE_TRANSLATION, 'html');
|
||||
expect(logSpy).toBeCalledTimes(4);
|
||||
translateComments(seedHTML, 'chinese', SIMPLE_TRANSLATION, 'html');
|
||||
expect(logSpy).toBeCalledTimes(5);
|
||||
logSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user