/* 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 = `