Commit 3fdf7215 authored by Himanshu Kapoor's avatar Himanshu Kapoor

Add new utils: addFinalNewline, getPathParents

- Add a new util function getPathParents
- Modify existing function addFinalNewline to support eol type, and move
it to ide/utils instead of ide/stores/utils
parent a22347cc
...@@ -14,6 +14,7 @@ import Editor from '../lib/editor'; ...@@ -14,6 +14,7 @@ import Editor from '../lib/editor';
import FileTemplatesBar from './file_templates/bar.vue'; import FileTemplatesBar from './file_templates/bar.vue';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { extractMarkdownImagesFromEntries } from '../stores/utils'; import { extractMarkdownImagesFromEntries } from '../stores/utils';
import { addFinalNewline } from '../utils';
export default { export default {
components: { components: {
...@@ -31,6 +32,7 @@ export default { ...@@ -31,6 +32,7 @@ export default {
return { return {
content: '', content: '',
images: {}, images: {},
addFinalNewline: true,
}; };
}, },
computed: { computed: {
...@@ -247,13 +249,14 @@ export default { ...@@ -247,13 +249,14 @@ export default {
this.model.onChange(model => { this.model.onChange(model => {
const { file } = model; const { file } = model;
if (!file.active) return;
if (file.active) { const monacoModel = model.getModel();
this.changeFileContent({ const content = monacoModel.getValue();
path: file.path, this.changeFileContent({
content: model.getModel().getValue(), path: file.path,
}); content: this.addFinalNewline ? addFinalNewline(content, monacoModel.getEOL()) : content,
} });
}); });
// Handle Cursor Position // Handle Cursor Position
......
...@@ -4,7 +4,7 @@ import eventHub from '../../eventhub'; ...@@ -4,7 +4,7 @@ import eventHub from '../../eventhub';
import service from '../../services'; import service from '../../services';
import * as types from '../mutation_types'; import * as types from '../mutation_types';
import router from '../../ide_router'; import router from '../../ide_router';
import { addFinalNewlineIfNeeded, setPageTitleForFile } from '../utils'; import { setPageTitleForFile } from '../utils';
import { viewerTypes, stageKeys } from '../../constants'; import { viewerTypes, stageKeys } from '../../constants';
export const closeFile = ({ commit, state, dispatch }, file) => { export const closeFile = ({ commit, state, dispatch }, file) => {
...@@ -152,7 +152,7 @@ export const changeFileContent = ({ commit, state, getters }, { path, content }) ...@@ -152,7 +152,7 @@ export const changeFileContent = ({ commit, state, getters }, { path, content })
const file = state.entries[path]; const file = state.entries[path];
commit(types.UPDATE_FILE_CONTENT, { commit(types.UPDATE_FILE_CONTENT, {
path, path,
content: addFinalNewlineIfNeeded(content), content,
}); });
const indexOfChangedFile = state.changedFiles.findIndex(f => f.path === path); const indexOfChangedFile = state.changedFiles.findIndex(f => f.path === path);
......
...@@ -272,10 +272,6 @@ export const pathsAreEqual = (a, b) => { ...@@ -272,10 +272,6 @@ export const pathsAreEqual = (a, b) => {
return cleanA === cleanB; return cleanA === cleanB;
}; };
// if the contents of a file dont end with a newline, this function adds a newline
export const addFinalNewlineIfNeeded = content =>
content.charAt(content.length - 1) !== '\n' ? `${content}\n` : content;
export function extractMarkdownImagesFromEntries(mdFile, entries) { export function extractMarkdownImagesFromEntries(mdFile, entries) {
/** /**
* Regex to identify an image tag in markdown, like: * Regex to identify an image tag in markdown, like:
......
...@@ -76,3 +76,21 @@ export function registerLanguages(def, ...defs) { ...@@ -76,3 +76,21 @@ export function registerLanguages(def, ...defs) {
} }
export const otherSide = side => (side === SIDE_RIGHT ? SIDE_LEFT : SIDE_RIGHT); export const otherSide = side => (side === SIDE_RIGHT ? SIDE_LEFT : SIDE_RIGHT);
export function addFinalNewline(content, eol = '\n') {
return content.slice(-eol.length) !== eol ? `${content}${eol}` : content;
}
export function getPathParents(path) {
const pathComponents = path.split('/');
const paths = [];
while (pathComponents.length) {
pathComponents.pop();
let parentPath = pathComponents.join('/');
if (parentPath.startsWith('/')) parentPath = parentPath.slice(1);
if (parentPath) paths.push(parentPath);
}
return paths;
}
...@@ -283,15 +283,25 @@ describe('RepoEditor', () => { ...@@ -283,15 +283,25 @@ describe('RepoEditor', () => {
expect(vm.model.events.size).toBe(2); expect(vm.model.events.size).toBe(2);
}); });
it('updates state when model content changed', done => { it.each`
vm.model.setValue('testing 123\n'); insertFinalNewline | input | eol | output
${true} | ${'testing 123\n'} | ${'\n'} | ${'testing 123\n'}
setImmediate(() => { ${true} | ${'testing 123'} | ${'\n'} | ${'testing 123\n'}
expect(vm.file.content).toBe('testing 123\n'); ${false} | ${'testing 123'} | ${'\n'} | ${'testing 123'}
${true} | ${'testing 123'} | ${'\r\n'} | ${'testing 123\r\n'}
done(); ${false} | ${'testing 123'} | ${'\r\n'} | ${'testing 123'}
}); `(
}); 'updates state with "$output" if `this.insertFinalNewline` is $insertFinalNewline',
({ insertFinalNewline, input, eol, output }) => {
jest.spyOn(vm.model.getModel(), 'getEOL').mockReturnValue(eol);
vm.addFinalNewline = insertFinalNewline;
vm.model.setValue(input);
expect(vm.file.content).toBe(output);
},
);
it('sets head model as staged file', () => { it('sets head model as staged file', () => {
jest.spyOn(vm.editor, 'createModel'); jest.spyOn(vm.editor, 'createModel');
......
...@@ -661,31 +661,6 @@ describe('Multi-file store utils', () => { ...@@ -661,31 +661,6 @@ describe('Multi-file store utils', () => {
}); });
}); });
describe('addFinalNewlineIfNeeded', () => {
it('adds a newline if it doesnt already exist', () => {
[
{
input: 'some text',
output: 'some text\n',
},
{
input: 'some text\n',
output: 'some text\n',
},
{
input: 'some text\n\n',
output: 'some text\n\n',
},
{
input: 'some\n text',
output: 'some\n text\n',
},
].forEach(({ input, output }) => {
expect(utils.addFinalNewlineIfNeeded(input)).toEqual(output);
});
});
});
describe('extractMarkdownImagesFromEntries', () => { describe('extractMarkdownImagesFromEntries', () => {
let mdFile; let mdFile;
let entries; let entries;
......
import { isTextFile, registerLanguages, trimPathComponents } from '~/ide/utils'; import {
isTextFile,
registerLanguages,
trimPathComponents,
addFinalNewline,
getPathParents,
} from '~/ide/utils';
import { languages } from 'monaco-editor'; import { languages } from 'monaco-editor';
describe('WebIDE utils', () => { describe('WebIDE utils', () => {
...@@ -148,4 +154,39 @@ describe('WebIDE utils', () => { ...@@ -148,4 +154,39 @@ describe('WebIDE utils', () => {
]); ]);
}); });
}); });
describe('addFinalNewline', () => {
it.each`
input | output
${'some text'} | ${'some text\n'}
${'some text\n'} | ${'some text\n'}
${'some text\n\n'} | ${'some text\n\n'}
${'some\n text'} | ${'some\n text\n'}
`('adds a newline if it doesnt already exist for input: $input', ({ input, output }) => {
expect(addFinalNewline(input)).toEqual(output);
});
it.each`
input | output
${'some text'} | ${'some text\r\n'}
${'some text\r\n'} | ${'some text\r\n'}
${'some text\n'} | ${'some text\n\r\n'}
${'some text\r\n\r\n'} | ${'some text\r\n\r\n'}
${'some\r\n text'} | ${'some\r\n text\r\n'}
`('works with CRLF newline style; input: $input', ({ input, output }) => {
expect(addFinalNewline(input, '\r\n')).toEqual(output);
});
});
describe('getPathParents', () => {
it.each`
path | parents
${'foo/bar/baz/index.md'} | ${['foo/bar/baz', 'foo/bar', 'foo']}
${'foo/bar/baz'} | ${['foo/bar', 'foo']}
${'index.md'} | ${[]}
${'path with/spaces to/something.md'} | ${['path with/spaces to', 'path with']}
`('gets all parent directory names for path: $path', ({ path, parents }) => {
expect(getPathParents(path)).toEqual(parents);
});
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment