Skip to content

Commit

Permalink
Merge pull request #8320 from stopfstedt/ember-cli-string-helpers-rep…
Browse files Browse the repository at this point in the history
…lacement

Ember cli string helpers replacement
  • Loading branch information
dartajax authored Jan 21, 2025
2 parents 2da823a + c24bf60 commit 63ebfd1
Show file tree
Hide file tree
Showing 11 changed files with 222 additions and 17 deletions.
15 changes: 15 additions & 0 deletions packages/ilios-common/addon/helpers/capitalize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { helper } from '@ember/component/helper';
import { capitalize as _capitalize } from '@ember/string';
import { isHTMLSafe } from '@ember/template';

export function capitalize([string]) {
if (isHTMLSafe(string)) {
string = string.toString();
}

string = string || '';

return _capitalize(string);
}

export default helper(capitalize);
14 changes: 14 additions & 0 deletions packages/ilios-common/addon/helpers/html-safe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { helper } from '@ember/component/helper';
import { isHTMLSafe, htmlSafe as _htmlSafe } from '@ember/template';

export function htmlSafe([string]) {
if (isHTMLSafe(string)) {
string = string.toString();
}

string = string || '';

return _htmlSafe(string);
}

export default helper(htmlSafe);
18 changes: 18 additions & 0 deletions packages/ilios-common/addon/helpers/truncate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { helper } from '@ember/component/helper';
import { isHTMLSafe } from '@ember/template';

export function truncate([string, characterLimit = 140, useEllipsis = true]) {
let limit = useEllipsis ? characterLimit - 3 : characterLimit;

if (isHTMLSafe(string)) {
string = string.toString();
}

if (string && string.length > limit) {
return useEllipsis ? `${string.substring(0, limit)}...` : string.substring(0, limit);
} else {
return string;
}
}

export default helper(truncate);
1 change: 1 addition & 0 deletions packages/ilios-common/app/helpers/capitalize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'ilios-common/helpers/capitalize';
1 change: 1 addition & 0 deletions packages/ilios-common/app/helpers/html-safe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'ilios-common/helpers/html-safe';
1 change: 1 addition & 0 deletions packages/ilios-common/app/helpers/truncate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'ilios-common/helpers/truncate';
1 change: 0 additions & 1 deletion packages/ilios-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"ember-cli-flash": "^5.1.0",
"ember-cli-htmlbars": "^6.3.0",
"ember-cli-page-object": "^2.3.0",
"ember-cli-string-helpers": "^6.0.1",
"ember-click-outside": "^6.0.0",
"ember-concurrency": "^4.0.2",
"ember-event-helpers": "^0.1.0",
Expand Down
59 changes: 59 additions & 0 deletions packages/test-app/tests/integration/helpers/capitalize-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { htmlSafe } from '@ember/template';

module('Integration | Helper | {{capitalize}}', function (hooks) {
setupRenderingTest(hooks);

test('It capitalizes a single string', async function (assert) {
await render(hbs`{{capitalize 'hi'}}`);

let expected = 'Hi';

assert.dom().hasText(expected, 'capitalizes a single string');
});

test('It leaves the capitalization unchanged with correctly capitalized string', async function (assert) {
await render(hbs`{{capitalize 'Harry'}}`);

let expected = 'Harry';

assert.dom().hasText(expected, 'leaves capitalization when string is already capitalized');
});

test('It correctly capitalizes an uncapitalized sentence', async function (assert) {
await render(hbs`{{capitalize 'age is foolish and forgetful when it underestimates youth'}}`);

let expected = 'Age is foolish and forgetful when it underestimates youth';

assert.dom().hasText(expected, 'correctly capitalizes an uncapitalized sentence');
});

test('It correctly handles empty string input', async function (assert) {
await render(hbs`{{capitalize ''}}`);

let expected = '';

assert.dom().hasText(expected, 'renders empty string if input is empty string');
});

test('It correctly handles undefined input', async function (assert) {
await render(hbs`{{capitalize undefined}}`);

let expected = '';

assert.dom().hasText(expected, 'renders empty string if undefined input');
});

test('It handles a SafeString', async function (assert) {
this.set('greeting', htmlSafe('hi'));

await render(hbs`{{capitalize this.greeting}}`);

let expected = 'Hi';

assert.dom().hasText(expected, 'correctly capitalizes a SafeString');
});
});
35 changes: 35 additions & 0 deletions packages/test-app/tests/integration/helpers/html-safe-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { htmlSafe } from '@ember/template';
import { render, find } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Helper | {{html-safe}}', function (hooks) {
setupRenderingTest(hooks);

test('It html-safes the html string', async function (assert) {
await render(hbs`{{html-safe '<h1>Hello World</h1>'}}`);

assert.dom('h1').hasText('Hello World', 'html string is correctly rendered');
});

test('It safely renders CSS classes from a property', async function (assert) {
this.set('classes', 'error has-error');
this.set('text', 'Hello World');
await render(hbs`<h1 class={{html-safe this.classes}}>{{this.text}}</h1>`);

assert.dom('h1').hasText('Hello World', 'it renders');
assert.deepEqual(
find('h1').getAttribute('class').split(' ').sort(),
['error', 'has-error'].sort(),
'it has the correct CSS classes',
);
});

test('It renders safe-string input', async function (assert) {
const safeString = htmlSafe('<h1>Hello World</h1>');
this.set('text', safeString);
await render(hbs`{{html-safe this.text}}`);
assert.dom('h1').hasText('Hello World', 'html string is correctly rendered');
});
});
78 changes: 78 additions & 0 deletions packages/test-app/tests/integration/helpers/truncate-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { htmlSafe } from '@ember/template';

module('Integration | Helper | {{truncate}}', function (hooks) {
setupRenderingTest(hooks);

test('It truncates to 140 characters if no characterLimit is provided', async function (assert) {
await render(
hbs`{{truncate
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit quam enim, in suscipit est rutrum id. Etiam vitae blandit purus, sed semper sem.'
}}`,
);

let expected =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit quam enim, in suscipit est rutrum id. Etiam vitae blandit pur...';

assert.dom().hasText(expected, 'truncates to 140 characters');
});

test('It truncates to characterLimit provided', async function (assert) {
await render(
hbs`{{truncate
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit quam enim, in suscipit est rutrum id. Etiam vitae blandit purus, sed semper sem.'
20
}}`,
);

let expected = 'Lorem ipsum dolor...';

assert.dom().hasText(expected, 'truncates to characterLimit');
});

test('It does not truncate if string is not longer than characterLimit', async function (assert) {
await render(
hbs`{{truncate
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit quam enim, in suscipit est rutrum id.'
140
}}`,
);

let expected =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit quam enim, in suscipit est rutrum id.';

assert.dom().hasText(expected, 'does not truncate');
});

test('It truncates to characterLimit provided without an ellipsis if useEllipsis is false', async function (assert) {
await render(
hbs`{{truncate
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit quam enim, in suscipit est rutrum id. Etiam vitae blandit purus, sed semper sem.'
20
false
}}`,
);

let expected = 'Lorem ipsum dolor si';

assert.dom().hasText(expected, 'truncates to characterLimit without ellipsis');
});

test('It handles a SafeString', async function (assert) {
this.set(
'sentence',
htmlSafe(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas hendrerit quam enim, in suscipit est rutrum id. Etiam vitae blandit purus, sed semper sem.',
),
);

await render(hbs`{{truncate this.sentence 20}}`);

let expected = 'Lorem ipsum dolor...';

assert.dom().hasText(expected, 'correctly trims a SafeString');
});
});
16 changes: 0 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 63ebfd1

Please sign in to comment.