Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IE testing and guard proxies when they are not present #1315

Merged
merged 12 commits into from
Sep 2, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,20 @@ jobs:
run: yarn --frozen-lockfile --install
- name: try ${{matrix.try-scenario}}
run: yarn run ember try:one ${{matrix.try-scenario}}

browser-tests:
needs: [lint]
runs-on: windows-latest
name: test-ie
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '14.x' # preferred node version
- name: yarn install
run: yarn --frozen-lockfile --install
- name: test
env:
TESTEM_CI_LAUNCHER: IE
CI: true
run: yarn test
13 changes: 9 additions & 4 deletions addon/base-record-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import { CUSTOM_MODEL_CLASS } from 'ember-m3/-infra/features';
import { recordDataToRecordMap, recordToRecordArrayMap } from './utils/caches';
import { recordIdentifierFor } from '@ember-data/store';
import HAS_NATIVE_PROXY from './utils/has-native-proxy';

/**
* BaseRecordArray
Expand Down Expand Up @@ -79,10 +80,14 @@ if (CUSTOM_MODEL_CLASS) {
// public RecordArray API
static create(...args) {
let instance = super.create(...args);

let arr = [];
arr.__recordArray = instance;
return new Proxy(arr, baseRecordArrayProxyHandler);
if (HAS_NATIVE_PROXY) {
let arr = [];
arr.__recordArray = instance;
return new Proxy(arr, baseRecordArrayProxyHandler);
// IE11 support
} else {
return instance;
}
}

init() {
Expand Down
2 changes: 2 additions & 0 deletions addon/utils/has-native-proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const HAS_NATIVE_PROXY = typeof Proxy === 'function';
export default HAS_NATIVE_PROXY;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"ember-compatibility-helpers": "^1.2.5",
"ember-disable-prototype-extensions": "^1.1.2",
"ember-export-application-global": "^2.0.1",
"ember-fetch": "^8.1.1",
hjdivad marked this conversation as resolved.
Show resolved Hide resolved
"ember-inflector": "^4.0.2",
"ember-load-initializers": "^2.1.2",
"ember-lodash": "^4.17.5",
Expand Down
2 changes: 1 addition & 1 deletion testem.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
module.exports = {
test_page: 'tests/index.html?hidepassed',
disable_watching: true,
launch_in_ci: ['Chrome'],
launch_in_ci: [process.env.TESTEM_CI_LAUNCHER || 'Chrome'],
launch_in_dev: ['Chrome'],
browser_start_timeout: 120,
browser_args: {
Expand Down
1 change: 1 addition & 0 deletions tests/dummy/app/adapters/-json-api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import EmberObject from '@ember/object';
import fetch from 'fetch';
hjdivad marked this conversation as resolved.
Show resolved Hide resolved

export default class Adapter extends EmberObject {
async ajax(url) {
Expand Down
3 changes: 2 additions & 1 deletion tests/helpers/prop-get.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { gte } from 'ember-compatibility-helpers';
import HAS_NATIVE_PROXY from 'ember-m3/utils/has-native-proxy';

// If ember-data version is before 3.28 we want to do record.get('property')
// otherwise we want to use native property access in newer versions
export default function propGet(record, key) {
if (gte('@ember-data/model', '3.28.0') || gte('ember-data', '3.28.0')) {
if ((gte('@ember-data/model', '3.28.0') || gte('ember-data', '3.28.0')) && HAS_NATIVE_PROXY) {
return record[key];
} else {
return record.get(key);
Expand Down
24 changes: 10 additions & 14 deletions tests/helpers/schema-versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,17 @@ function computeAttributeCompat(v2Schema, key, value, modelName, schemaInterface
}
return array;
};
let compatSchemaInterface = new Proxy(schemaInterface, {
get(object, property) {
switch (property) {
case 'nested':
return isReference ? identity : addTarget;
case 'reference':
return isReference ? addTarget : identity;
case 'managedArray':
return managedArray;
default:
return object[property];
}
let compatSchemaInterface = {
get nested() {
return isReference ? identity : addTarget;
},
});

get reference() {
return isReference ? addTarget : identity;
},
get managedArray() {
return managedArray;
},
};
let result = v2Schema.computeAttribute(key, value, modelName, compatSchemaInterface);
if (result === arrayTarget) {
return arrayTarget;
Expand Down
49 changes: 26 additions & 23 deletions tests/integration/managed-array-tracked-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import hbs from 'htmlbars-inline-precompile';
import DefaultSchema from 'ember-m3/services/m3-schema';
import Component from '@ember/component';
import { CUSTOM_MODEL_CLASS } from 'ember-m3/-infra/features';
import HAS_NATIVE_PROXY from 'ember-m3/utils/has-native-proxy';

if (CUSTOM_MODEL_CLASS) {
module('integration/managed-array-tracked', function (hooks) {
Expand Down Expand Up @@ -138,36 +139,38 @@ if (CUSTOM_MODEL_CLASS) {
);
});

// We have run into scenarios like these with users stashing M3 Arrays on POJOs in services, and then accessing them and
// modifying during a render
test('Can modify a managed array after creation without triggering rerendering assertions', async function (assert) {
let bookstore = this.store.createRecord('com.example.Bookstore', {
books: [{ name: 'Igor' }, { name: 'David' }],
});
if (HAS_NATIVE_PROXY) {
// We have run into scenarios like these with users stashing M3 Arrays on POJOs in services, and then accessing them and
// modifying during a render
test('Can modify a managed array after creation without triggering rerendering assertions', async function (assert) {
let bookstore = this.store.createRecord('com.example.Bookstore', {
books: [{ name: 'Igor' }, { name: 'David' }],
});

let books = bookstore.books;
let books = bookstore.books;

this.owner.register(
'component:first-book',
class FirstBookComponent extends Component {
get firstBook() {
books.shift();
return books[0];
this.owner.register(
'component:first-book',
class FirstBookComponent extends Component {
get firstBook() {
books.shift();
return books[0];
}
}
}
);
this.owner.register(
'template:components/first-book',
hbs`<h1>{{this.firstBook.name}}</h1>
);
this.owner.register(
'template:components/first-book',
hbs`<h1>{{this.firstBook.name}}</h1>
`
);
);

await render(hbs`
await render(hbs`
{{first-book}}
`);
let text = this.element.textContent.trim();
assert.equal(text, 'David', 'Rendered the component');
});
let text = this.element.textContent.trim();
assert.equal(text, 'David', 'Rendered the component');
});
}

test('mutating arrays causes length tracked properties to recompute', async function (assert) {
this.store.pushPayload('com.example.Bookstore', {
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/model/native-access-arrays-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import DefaultSchema from 'ember-m3/services/m3-schema';
import { CUSTOM_MODEL_CLASS } from 'ember-m3/-infra/features';
import HAS_NATIVE_PROXY from 'ember-m3/utils/has-native-proxy';

function computeNestedModel(key, value /*, modelName, schemaInterface */) {
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
Expand Down Expand Up @@ -37,7 +38,7 @@ class TestSchema extends DefaultSchema {
}
}

if (CUSTOM_MODEL_CLASS) {
if (CUSTOM_MODEL_CLASS && HAS_NATIVE_PROXY) {
module(`unit/model/native-access-arrays`, function (hooks) {
setupTest(hooks);

Expand Down
17 changes: 10 additions & 7 deletions tests/unit/model/state-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { gte } from 'ember-compatibility-helpers';
import propGet from '../../helpers/prop-get';
import DefaultSchema from 'ember-m3/services/m3-schema';
import { CUSTOM_MODEL_CLASS } from 'ember-m3/-infra/features';
import HAS_NATIVE_PROXY from 'ember-m3/utils/has-native-proxy';

let computeNestedModel = function computeNestedModel(key, value) {
if (value && typeof value === 'object' && !isArray(value)) {
Expand Down Expand Up @@ -42,9 +43,6 @@ let computeAttributeReference = function computeAttributeReference(
};

class TestSchema extends DefaultSchema {
useNativeProperties() {
return gte('@ember-data/model', '3.28.0') || gte('ember-data', '3.28.0');
}
includesModel() {
return true;
}
Expand Down Expand Up @@ -80,10 +78,6 @@ class TestSchema extends DefaultSchema {
}

class TestSchemaOldHooks extends DefaultSchema {
useNativeProperties() {
return gte('@ember-data/model', '3.28.0') || gte('ember-data', '3.28.0');
}

includesModel() {
return true;
}
Expand All @@ -96,6 +90,15 @@ class TestSchemaOldHooks extends DefaultSchema {
}
}

if ((gte('@ember-data/model', '3.28.0') || gte('ember-data', '3.28.0')) && HAS_NATIVE_PROXY) {
TestSchemaOldHooks.prototype.useNativeProperties = function () {
return true;
};
TestSchema.prototype.useNativeProperties = function () {
return true;
};
}

for (let testRun = 0; testRun < 2; testRun++) {
module(
`unit/model/state with ${testRun === 0 ? 'old hooks' : 'with computeAttribute'}`,
Expand Down
Loading