sproutcore 1.6.0.rc.2-x86-mingw32 → 1.6.0.1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +12 -0
- data/VERSION.yml +1 -1
- data/bin/sc-docs +6 -1
- data/lib/buildtasks/target.rake +1 -1
- data/lib/frameworks/sproutcore/Buildfile +5 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +175 -1
- data/lib/frameworks/sproutcore/apps/test_controls/controllers/select.js +12 -0
- data/lib/frameworks/sproutcore/apps/test_controls/resources/select_page.js +19 -5
- data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +28 -31
- data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +9 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/controller.js +21 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/responder_context.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/checkbox_support.js +6 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/template_helpers/text_field_support.js +26 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/keyboard.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +12 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/template.js +25 -9
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js +157 -5
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +7 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +9 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/sparse_array.js +8 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/string.js +104 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/theme.js +3 -56
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/utils.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/content_destroyed.js +59 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/string.js +41 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/template_helpers/text_field_support.js +10 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/panes/template.js +16 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template/handlebars.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/clippingFrame.js +11 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/didAppendToDocument.js +18 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/insertBefore.js +10 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/keyboard.js +18 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template_collection.js +9 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +9 -4
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/keyboard.js +15 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +14 -8
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +8 -18
- data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/fixtures.js +12 -2
- data/lib/frameworks/sproutcore/frameworks/datastore/mixins/relationship_support.js +296 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/models/child_record.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +330 -326
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +22 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +614 -614
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/data_sources/data_source.js +14 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +3 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_array_complex.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record_complex.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/core_methods.js +20 -13
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +61 -46
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +30 -30
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitChangesFromNestedStore.js +24 -24
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/connectDataSource.js +31 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/pushRelationships.js +1177 -0
- data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/localized/system/datetime.js +4 -63
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/border.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/alert.js +7 -8
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +18 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +9 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drag_data_source.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/drop_target.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/button.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/checkbox.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/collection.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/disclosure.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/image_button.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/master_detail.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/menu.js +12 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/panel.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/picker.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/progress.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/radio.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/radio_group.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segment.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/segmented.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/slider.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/toolbar.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/well.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/render_delegates/workspace.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/segmented.css +1 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/alert/ui.js +33 -22
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/methods.js +20 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/methods.js +10 -3
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/methods.js +34 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +14 -15
- data/lib/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +40 -14
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +699 -700
- data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/master_detail.js +11 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +16 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/views/progress.js +0 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +49 -7
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select_button.js +9 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +6 -2
- data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +4 -26
- data/lib/frameworks/sproutcore/frameworks/desktop/views/web.js +20 -19
- data/lib/frameworks/sproutcore/frameworks/experimental/Buildfile +2 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/designer/designers/view_designer.js +249 -249
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/mixins/edit_mode.js +13 -5
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/mixins/emptiness.js +53 -37
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/render_delegates/form.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/render_delegates/form_row.js +3 -11
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/mixins/edit_mode.js +53 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/mixins/emptiness.js +114 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form.js +174 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_row.js +86 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form.js +80 -110
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/views/form_row.js +96 -97
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/README.md +2 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/polymorphism/models/record.js +20 -36
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu.js +121 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/ext/menu_item.js +90 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/mixins/select_view_menu.js +139 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/render_delegates/select_button.js +14 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/ext/menu_resizing.js +25 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/mixins/select_view_menu/bindings.js +43 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/mixins/select_view_menu/check_selected.js +32 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/popup_button/menu_setup.js +40 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/popup_button/show_menu.js +45 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/select/menu_width.js +49 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/tests/views/select/selected_item.js +191 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/popup_button.js +264 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/select.js +450 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_child.js +14 -6
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/mixins/split_thumb.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/render_delegates/split.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/render_delegates/split_divider.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/views/split.js +9 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/split_view/views/thumb.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +7 -17
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/flowed_layout.js +35 -8
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editor.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_editor_delegate.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inner_frame.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/helpers/sizing.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/image.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/label.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/render_delegate.js +6 -6
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/images/favicon.ico +0 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +0 -5
- data/lib/frameworks/sproutcore/frameworks/foundation/system/exception_handler.js +4 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/system/math.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +13 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_measurement.js +6 -9
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/flowed_layout/tests.js +912 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/methods.js +36 -7
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +58 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/validators/validator.js +1 -3
- data/lib/frameworks/sproutcore/frameworks/foundation/views/field.js +0 -15
- data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +25 -14
- data/lib/frameworks/sproutcore/frameworks/handlebars/handlebars.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +15 -9
- data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array/flatten.js +24 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/ext/array.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/ext/function.js +5 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/array.js +19 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/copyable.js +3 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/freezable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +14 -14
- data/lib/frameworks/sproutcore/frameworks/runtime/system/error.js +3 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/system/logger.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/system/range_observer.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/runtime/system/set.js +15 -16
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +6 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/object/enhance.js +30 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/range_observer/create.js +17 -0
- data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +9 -2
- data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +3 -1
- data/lib/frameworks/sproutcore/frameworks/testing/resources/runner.css +0 -1
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/base.css +80 -0
- data/lib/frameworks/sproutcore/frameworks/yuireset/resources/core.css +0 -4
- data/lib/frameworks/sproutcore/lib/index.rhtml +2 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list.css +3 -3
- data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list_item.css +2 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/form/form.css +9 -0
- data/lib/frameworks/sproutcore/themes/ace/resources/menu/menu.css +3 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/picker.js +1 -1
- data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/workspace.js +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/button.js +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/panel.js +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/progress.js +2 -0
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/slider.js +1 -1
- data/lib/frameworks/sproutcore/themes/legacy_theme/render_delegates/well.js +1 -1
- data/lib/sproutcore/builders/base.rb +5 -1
- data/lib/sproutcore/builders/handlebars.rb +12 -1
- data/lib/sproutcore/models/target.rb +1 -9
- data/lib/sproutcore/rack/proxy.rb +238 -92
- data/lib/sproutcore/tools/docs.rb +1 -7
- data/spec/fixtures/builder_tests/apps/handlebars_test/Buildfile +1 -0
- data/spec/fixtures/builder_tests/apps/handlebars_test/{template.handlebars → templates/template.handlebars} +2 -0
- data/spec/lib/builders/handlebars_spec.rb +10 -4
- data/sproutcore.gemspec +3 -1
- metadata +73 -44
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/english.lproj/default_styles.css +0 -5
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/english.lproj/strings.js +0 -15
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_checkbox_field.js +0 -17
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_field.js +0 -17
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_label.js +0 -17
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_radio_field.js +0 -17
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/forms/tests/views/form_text_field.js +0 -17
@@ -11,13 +11,13 @@ module("SC.Store#commitChangesFromNestedStore", {
|
|
11
11
|
SC.RunLoop.begin();
|
12
12
|
|
13
13
|
store = SC.Store.create();
|
14
|
-
|
14
|
+
|
15
15
|
json = {
|
16
16
|
string: "string",
|
17
17
|
number: 23,
|
18
18
|
bool: YES
|
19
19
|
};
|
20
|
-
|
20
|
+
|
21
21
|
storeKey = SC.Store.generateStoreKey();
|
22
22
|
|
23
23
|
child = store.chain(); // test multiple levels deep
|
@@ -33,46 +33,46 @@ module("SC.Store#commitChangesFromNestedStore", {
|
|
33
33
|
});
|
34
34
|
|
35
35
|
test("copies changed data hashes, statuses, and revisions", function() {
|
36
|
-
|
36
|
+
|
37
37
|
SC.RunLoop.begin();
|
38
|
-
|
38
|
+
|
39
39
|
// verify preconditions
|
40
40
|
equals(store.readDataHash(storeKey), null, 'precond - should not have data yet');
|
41
41
|
ok(child.chainedChanges.contains(storeKey), 'precond - child changes should include storeKey');
|
42
|
-
|
42
|
+
|
43
43
|
// perform action
|
44
44
|
equals(store.commitChangesFromNestedStore(child, child.chainedChanges, NO), store, 'should return receiver');
|
45
|
-
|
45
|
+
|
46
46
|
// verify new status
|
47
47
|
equals(store.readDataHash(storeKey), json, 'now should have json');
|
48
48
|
equals(store.readStatus(storeKey), SC.Record.READY_DIRTY, 'now should have status');
|
49
|
-
equals(store.revisions[storeKey], child.revisions[storeKey], 'now shoulave have revision from child');
|
50
|
-
|
49
|
+
equals(store.revisions[storeKey], child.revisions[storeKey], 'now shoulave have revision from child');
|
50
|
+
|
51
51
|
SC.RunLoop.end();
|
52
52
|
});
|
53
53
|
|
54
|
-
test("adds items in changelog to
|
54
|
+
test("adds items in changelog to receiver changelog", function() {
|
55
55
|
|
56
56
|
var key1 = SC.Store.generateStoreKey();
|
57
57
|
|
58
58
|
SC.RunLoop.begin();
|
59
|
-
|
59
|
+
|
60
60
|
store.changelog = SC.Set.create();
|
61
61
|
store.changelog.add(key1);
|
62
|
-
|
62
|
+
|
63
63
|
ok(child.changelog.contains(storeKey), 'precond - child.changelog should contain store key');
|
64
|
-
|
64
|
+
|
65
65
|
equals(store.commitChangesFromNestedStore(child, child.chainedChanges, NO), store, 'should return receiver');
|
66
66
|
|
67
67
|
// changelog should merge nested store & existing
|
68
68
|
ok(store.changelog.contains(key1), 'changelog should still contain key1');
|
69
69
|
ok(store.changelog.contains(storeKey), 'changelog should also contain storeKey');
|
70
|
-
|
70
|
+
|
71
71
|
SC.RunLoop.end();
|
72
72
|
});
|
73
73
|
|
74
74
|
test("ignores changed data hashes not passed in changes set", function() {
|
75
|
-
|
75
|
+
|
76
76
|
// preconditions
|
77
77
|
equals(store.readDataHash(storeKey), null, 'precond - should not have data yet');
|
78
78
|
|
@@ -81,25 +81,25 @@ test("ignores changed data hashes not passed in changes set", function() {
|
|
81
81
|
|
82
82
|
// verify results
|
83
83
|
equals(store.readDataHash(storeKey), null, 'should not copy data hash for storeKey');
|
84
|
-
|
84
|
+
|
85
85
|
});
|
86
86
|
|
87
87
|
function createConflict(force) {
|
88
88
|
var json2 = { kind: "json2" };
|
89
89
|
var json3 = { kind: "json3" };
|
90
|
-
|
90
|
+
|
91
91
|
// create a lock conflict. use a new storeKey since the old one has been
|
92
92
|
// setup in a way that won't work for this.
|
93
93
|
storeKey = SC.Store.generateStoreKey();
|
94
|
-
|
94
|
+
|
95
95
|
// step 1: add data to root store
|
96
96
|
store.writeDataHash(storeKey, json, SC.Record.READY_CLEAN);
|
97
97
|
store.dataHashDidChange(storeKey);
|
98
|
-
|
98
|
+
|
99
99
|
// step 2: read data in chained store. this will create lock
|
100
100
|
child.readDataHash(storeKey);
|
101
101
|
ok(child.locks[storeKey], 'child store should now have lock');
|
102
|
-
|
102
|
+
|
103
103
|
// step 3: modify root store again
|
104
104
|
store.writeDataHash(storeKey, json2, SC.Record.READY_CLEAN);
|
105
105
|
store.dataHashDidChange(storeKey);
|
@@ -107,11 +107,11 @@ function createConflict(force) {
|
|
107
107
|
// step 4: modify data in chained store so we have something to commit.
|
108
108
|
child.writeDataHash(storeKey, json3, SC.Record.READY_DIRTY);
|
109
109
|
child.dataHashDidChange(storeKey);
|
110
|
-
|
111
|
-
// just to make sure verify that the lock and revision in parent do not
|
110
|
+
|
111
|
+
// just to make sure verify that the lock and revision in parent do not
|
112
112
|
// match
|
113
113
|
ok(child.locks[storeKey] !== store.revisions[storeKey], 'child.lock (%@) should !== store.revision (%@)'.fmt(child.locks[storeKey], store.revisions[storeKey]));
|
114
|
-
|
114
|
+
|
115
115
|
// step 5: now try to commit changes from child store. This should throw
|
116
116
|
// an exception.
|
117
117
|
var errorCount = 0;
|
@@ -120,8 +120,8 @@ function createConflict(force) {
|
|
120
120
|
} catch(e) {
|
121
121
|
equals(e, SC.Store.CHAIN_CONFLICT_ERROR, 'should throw CHAIN_CONFLICT_ERROR');
|
122
122
|
errorCount++;
|
123
|
-
}
|
124
|
-
|
123
|
+
}
|
124
|
+
|
125
125
|
return errorCount ;
|
126
126
|
}
|
127
127
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: SproutCore - JavaScript Application Framework
|
3
|
+
// Copyright: ©2006-2011 Apple Inc. and contributors.
|
4
|
+
// License: Licensed under MIT license (see license.js)
|
5
|
+
// ==========================================================================
|
6
|
+
|
7
|
+
module("connecting DataSource to a store");
|
8
|
+
|
9
|
+
test("data source passed as string should be available as after running _getDataSource", function() {
|
10
|
+
window.MyTestDataSource = SC.DataSource.extend({
|
11
|
+
foo: 'bar'
|
12
|
+
});
|
13
|
+
|
14
|
+
var store = SC.Store.create().from("MyTestDataSource");
|
15
|
+
same(store.get("dataSource"), "MyTestDataSource");
|
16
|
+
|
17
|
+
var dataSource = store._getDataSource();
|
18
|
+
same(dataSource.foo, 'bar');
|
19
|
+
|
20
|
+
same(store.get('dataSource').foo, 'bar');
|
21
|
+
});
|
22
|
+
|
23
|
+
test("data source is required, if it can't be found, error should be thrown", function() {
|
24
|
+
expect(1);
|
25
|
+
|
26
|
+
try {
|
27
|
+
SC.Store.create().from("SC.YourTestDataSource")._getDataSource();
|
28
|
+
} catch (x) {
|
29
|
+
same(x, 'SC.YourTestDataSource could not be found');
|
30
|
+
}
|
31
|
+
});
|
@@ -0,0 +1,1177 @@
|
|
1
|
+
/*globals MyApp module test ok equals same stop start */
|
2
|
+
|
3
|
+
module("Propogating relationships with Store#pushRetrieve and Store#pushDestroy", {
|
4
|
+
setup: function () {
|
5
|
+
var MyApp = window.MyApp = SC.Object.create({
|
6
|
+
store: SC.Store.create(SC.RelationshipSupport)
|
7
|
+
});
|
8
|
+
}
|
9
|
+
});
|
10
|
+
|
11
|
+
// ..........................................................
|
12
|
+
// pushRetrieve BEHAVIOR
|
13
|
+
//
|
14
|
+
|
15
|
+
/**
|
16
|
+
[master] --> [slave]
|
17
|
+
|
18
|
+
precond - master has a slave
|
19
|
+
test - slave has a master
|
20
|
+
*/
|
21
|
+
test("Master updates a slave [one(master) to one(slave)].", function () {
|
22
|
+
MyApp.Master = SC.Record.extend({
|
23
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
24
|
+
inverse: 'master',
|
25
|
+
isMaster: YES
|
26
|
+
})
|
27
|
+
});
|
28
|
+
|
29
|
+
MyApp.Slave = SC.Record.extend({
|
30
|
+
master: SC.Record.toOne('MyApp.Master', {
|
31
|
+
inverse: 'slave',
|
32
|
+
isMaster: NO
|
33
|
+
})
|
34
|
+
});
|
35
|
+
|
36
|
+
SC.RunLoop.begin();
|
37
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
38
|
+
{ guid: 's1' }
|
39
|
+
]);
|
40
|
+
|
41
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
42
|
+
{ guid: 'm1', slave: 's1' }
|
43
|
+
]);
|
44
|
+
SC.RunLoop.end();
|
45
|
+
|
46
|
+
var s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
47
|
+
m1 = MyApp.store.find(MyApp.Master, 'm1');
|
48
|
+
|
49
|
+
equals(m1.get('slave'), s1, 'precond - m1 should have a slave');
|
50
|
+
equals(s1.get('master'), m1, 's1 should have a master');
|
51
|
+
});
|
52
|
+
|
53
|
+
/**
|
54
|
+
[master]
|
55
|
+
v
|
56
|
+
|
|
57
|
+
+--> [slave1]
|
58
|
+
|
|
59
|
+
...
|
60
|
+
|
|
61
|
+
+--> [slaveN]
|
62
|
+
|
63
|
+
precond - master has slaves
|
64
|
+
test - slaves have a master
|
65
|
+
*/
|
66
|
+
test("A master updates many slave [one(master) to many(slave)].", function () {
|
67
|
+
MyApp.Slave = SC.Record.extend({
|
68
|
+
master: SC.Record.toOne('MyApp.Master', {
|
69
|
+
inverse: 'slaves',
|
70
|
+
isMaster: NO
|
71
|
+
})
|
72
|
+
});
|
73
|
+
|
74
|
+
MyApp.Master = SC.Record.extend({
|
75
|
+
slaves: SC.Record.toMany('MyApp.Slave', {
|
76
|
+
inverse: 'master',
|
77
|
+
isMaster: YES
|
78
|
+
})
|
79
|
+
});
|
80
|
+
|
81
|
+
SC.RunLoop.begin();
|
82
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
83
|
+
{ guid: 's1' },
|
84
|
+
{ guid: 's2' }
|
85
|
+
]);
|
86
|
+
|
87
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
88
|
+
{ guid: 'm1', slaves: ['s1', 's2'] }
|
89
|
+
]);
|
90
|
+
SC.RunLoop.end();
|
91
|
+
|
92
|
+
var s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
93
|
+
s2 = MyApp.store.find(MyApp.Slave, 's2'),
|
94
|
+
m1 = MyApp.store.find(MyApp.Master, 'm1');
|
95
|
+
|
96
|
+
equals(m1.get('slaves').length(), 2, 'precond - m1 has 2 slaves');
|
97
|
+
equals(s1.get('master'), m1, 's1 should have master m1');
|
98
|
+
equals(s2.get('master'), m1, 's2 should have master m1');
|
99
|
+
});
|
100
|
+
|
101
|
+
/**
|
102
|
+
[slave]
|
103
|
+
^
|
104
|
+
|
|
105
|
+
+--< [master1]
|
106
|
+
|
|
107
|
+
...
|
108
|
+
|
|
109
|
+
+--< [masterN]
|
110
|
+
|
111
|
+
precond - master has a slave
|
112
|
+
test - slave has many masters
|
113
|
+
*/
|
114
|
+
test("Many parent master updates a slave [many(master) to one(slave)]", function () {
|
115
|
+
MyApp.Slave = SC.Record.extend({
|
116
|
+
masters: SC.Record.toMany('MyApp.Master', {
|
117
|
+
inverse: 'slave',
|
118
|
+
isMaster: NO
|
119
|
+
})
|
120
|
+
});
|
121
|
+
|
122
|
+
MyApp.Master = SC.Record.extend({
|
123
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
124
|
+
inverse: 'masters',
|
125
|
+
isMaster: YES
|
126
|
+
})
|
127
|
+
});
|
128
|
+
|
129
|
+
SC.RunLoop.begin();
|
130
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
131
|
+
{ guid: 's1' }
|
132
|
+
]);
|
133
|
+
|
134
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
135
|
+
{ guid: 'm1', slave: 's1' },
|
136
|
+
{ guid: 'm2', slave: 's1' }
|
137
|
+
]);
|
138
|
+
SC.RunLoop.end();
|
139
|
+
|
140
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
141
|
+
m2 = MyApp.store.find(MyApp.Master, 'm2'),
|
142
|
+
s1 = MyApp.store.find(MyApp.Slave, 's1');
|
143
|
+
|
144
|
+
equals(m1.get('slave'), s1, 'precond - m1 should have slave s1');
|
145
|
+
equals(m2.get('slave'), s1, 'precond - m2 should have slave s1');
|
146
|
+
|
147
|
+
equals(s1.get('masters').length(), 2, 'slave has 2 masters');
|
148
|
+
ok(s1.get('masters').indexOf(m1) !== -1, 'slave has master m1');
|
149
|
+
ok(s1.get('masters').indexOf(m2) !== -1, 'slave has master m2');
|
150
|
+
});
|
151
|
+
|
152
|
+
/**
|
153
|
+
[master1] ... [masterN]
|
154
|
+
v v
|
155
|
+
| |
|
156
|
+
>------- ... -> [slave1]
|
157
|
+
| |
|
158
|
+
... ...
|
159
|
+
| |
|
160
|
+
>------- ... -> [slaveN]
|
161
|
+
|
162
|
+
precond - masters have many slaves
|
163
|
+
test - slaves have many masters
|
164
|
+
*/
|
165
|
+
test("Many masters update many slaves [many(master) to many(slave)]", function () {
|
166
|
+
MyApp.Master = SC.Record.extend({
|
167
|
+
slaves: SC.Record.toMany('MyApp.Slave', {
|
168
|
+
inverse: 'masters',
|
169
|
+
isMaster: YES
|
170
|
+
})
|
171
|
+
});
|
172
|
+
|
173
|
+
MyApp.Slave = SC.Record.extend({
|
174
|
+
masters: SC.Record.toMany('MyApp.Master', {
|
175
|
+
inverse: 'slaves',
|
176
|
+
isMaster: NO
|
177
|
+
})
|
178
|
+
});
|
179
|
+
|
180
|
+
SC.RunLoop.begin();
|
181
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
182
|
+
{ guid: 's1' },
|
183
|
+
{ guid: 's2' }
|
184
|
+
]);
|
185
|
+
|
186
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
187
|
+
{ guid: 'm1', slaves: ['s1', 's2'] },
|
188
|
+
{ guid: 'm2', slaves: ['s1', 's2'] }
|
189
|
+
]);
|
190
|
+
SC.RunLoop.end();
|
191
|
+
|
192
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
193
|
+
m2 = MyApp.store.find(MyApp.Master, 'm2'),
|
194
|
+
s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
195
|
+
s2 = MyApp.store.find(MyApp.Slave, 's2');
|
196
|
+
|
197
|
+
equals(m1.get('slaves').length(), 2, 'precond - m1 should have 2 slaves');
|
198
|
+
equals(m2.get('slaves').length(), 2, 'precond - m2 should have 2 slaves');
|
199
|
+
|
200
|
+
equals(s1.get('masters').length(), 2, 's1 should have 2 masters');
|
201
|
+
ok(s1.get('masters').indexOf(m1) !== -1, 's1 should have m1 as a master');
|
202
|
+
ok(s1.get('masters').indexOf(m2) !== -1, 's1 should have m2 as a master');
|
203
|
+
|
204
|
+
equals(s2.get('masters').length(), 2, 's2 should have 2 masters');
|
205
|
+
ok(s2.get('masters').indexOf(m1) !== -1, 's2 should have m1 as a master');
|
206
|
+
ok(s2.get('masters').indexOf(m2) !== -1, 's2 should have m2 as a master');
|
207
|
+
});
|
208
|
+
|
209
|
+
/**
|
210
|
+
[slave] >--- X ---> [*]
|
211
|
+
|
212
|
+
precond - * is related to slave
|
213
|
+
test - after update to slave, * is related to slave
|
214
|
+
*/
|
215
|
+
test("A slave does NOT update a relationship [one(slave) to *]", function () {
|
216
|
+
MyApp.Slave = SC.Record.extend({
|
217
|
+
relative: SC.Record.toOne('MyApp.Relative', {
|
218
|
+
inverse: 'slave',
|
219
|
+
isMaster: NO
|
220
|
+
})
|
221
|
+
});
|
222
|
+
|
223
|
+
MyApp.Relative = SC.Record.extend({
|
224
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
225
|
+
inverse: 'relative',
|
226
|
+
isMaster: YES
|
227
|
+
})
|
228
|
+
});
|
229
|
+
|
230
|
+
// case create slave WITHOUT relationship
|
231
|
+
SC.RunLoop.begin();
|
232
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
233
|
+
{ guid: 's1' }
|
234
|
+
]);
|
235
|
+
|
236
|
+
MyApp.store.loadRecords(MyApp.Relative, [
|
237
|
+
{ guid: 'r1', slave: 's1' }
|
238
|
+
]);
|
239
|
+
SC.RunLoop.end();
|
240
|
+
|
241
|
+
var s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
242
|
+
r1 = MyApp.store.find(MyApp.Relative, 'r1');
|
243
|
+
|
244
|
+
equals(s1.get('relative'), r1, 'precond1 - s1 has relative r1');
|
245
|
+
|
246
|
+
SC.RunLoop.begin();
|
247
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
248
|
+
{ guid: 's1' }
|
249
|
+
]);
|
250
|
+
SC.RunLoop.end();
|
251
|
+
|
252
|
+
ok(SC.none(s1.get('relative')), 'precond2 - s1 has no relative');
|
253
|
+
equals(r1.get('slave'), s1, 'test1- r1 is related to s1');
|
254
|
+
|
255
|
+
// case - create slave WITH releationship
|
256
|
+
SC.RunLoop.begin();
|
257
|
+
MyApp.store.loadRecords(MyApp.Relative, [
|
258
|
+
{ guid: 'r2'}
|
259
|
+
]);
|
260
|
+
|
261
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
262
|
+
{ guid: 's2', relative: 'r2' }
|
263
|
+
]);
|
264
|
+
SC.RunLoop.end();
|
265
|
+
|
266
|
+
var s2 = MyApp.store.find(MyApp.Slave, 's2'),
|
267
|
+
r2 = MyApp.store.find(MyApp.Relative, 'r2');
|
268
|
+
|
269
|
+
equals(s2.get('relative'), r2, 'precond3 - s2 is related to r2');
|
270
|
+
ok(SC.none(r2.get('slave')), 'test2 - r2 should NOT have a slave');
|
271
|
+
});
|
272
|
+
|
273
|
+
/**
|
274
|
+
[master1] <----> [master2]
|
275
|
+
|
276
|
+
precond - master1 has master2
|
277
|
+
test - master2 has master1
|
278
|
+
*/
|
279
|
+
test("A master will mutually update a master [one(master) to one(master)].", function () {
|
280
|
+
MyApp.Master = SC.Record.extend({
|
281
|
+
relative: SC.Record.toOne('MyApp.Master', {
|
282
|
+
inverse: 'relative',
|
283
|
+
isMaster: YES
|
284
|
+
})
|
285
|
+
});
|
286
|
+
|
287
|
+
SC.RunLoop.begin();
|
288
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
289
|
+
{ guid: 'm1' }
|
290
|
+
]);
|
291
|
+
|
292
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
293
|
+
{ guid: 'm2', relative: 'm1' }
|
294
|
+
]);
|
295
|
+
SC.RunLoop.end();
|
296
|
+
|
297
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
298
|
+
m2 = MyApp.store.find(MyApp.Master, 'm2');
|
299
|
+
|
300
|
+
equals(m1.get('relative'), m2, 'precond - m1 should have a relative "m2"');
|
301
|
+
equals(m2.get('relative'), m1, 'm2 should have a relative "m1"');
|
302
|
+
});
|
303
|
+
|
304
|
+
// ..........................................................
|
305
|
+
// REPLACING RELATIONSHIPS
|
306
|
+
//
|
307
|
+
|
308
|
+
/**
|
309
|
+
[master1] <--> [slave]
|
310
|
+
|
311
|
+
precond - master1 has slave
|
312
|
+
precond - slave has master1
|
313
|
+
|
314
|
+
...relate master2 to slave...
|
315
|
+
|
316
|
+
[master1] --> [slave]
|
317
|
+
^
|
318
|
+
|
|
319
|
+
[master2] <----+
|
320
|
+
|
321
|
+
precond - master2 has slave
|
322
|
+
precond - slave has master2
|
323
|
+
test - master1 has slave
|
324
|
+
*/
|
325
|
+
test("Stealing relationship does NOT propagate to other masters [one(master) to one(slave)]", function () {
|
326
|
+
MyApp.Slave = SC.Record.extend({
|
327
|
+
master: SC.Record.toOne('MyApp.Master', {
|
328
|
+
inverse: 'slave',
|
329
|
+
isMaster: NO
|
330
|
+
})
|
331
|
+
});
|
332
|
+
|
333
|
+
MyApp.Master = SC.Record.extend({
|
334
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
335
|
+
inverse: 'master',
|
336
|
+
isMaster: YES
|
337
|
+
})
|
338
|
+
});
|
339
|
+
|
340
|
+
SC.RunLoop.begin();
|
341
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
342
|
+
{ guid: 's1' }
|
343
|
+
]);
|
344
|
+
|
345
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
346
|
+
{ guid: 'm1', slave: 's1' }
|
347
|
+
]);
|
348
|
+
SC.RunLoop.end();
|
349
|
+
|
350
|
+
var s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
351
|
+
m1 = MyApp.store.find(MyApp.Master, 'm1');
|
352
|
+
|
353
|
+
equals(m1.get('slave'), s1, 'precond - m1 should have s1');
|
354
|
+
equals(s1.get('master'), m1, 'precond - s1 should relate to m1');
|
355
|
+
|
356
|
+
SC.RunLoop.begin();
|
357
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
358
|
+
{ guid: 'm2', slave: 's1' }
|
359
|
+
]);
|
360
|
+
SC.RunLoop.end();
|
361
|
+
|
362
|
+
var m2 = MyApp.store.find(MyApp.Master, 'm2');
|
363
|
+
|
364
|
+
equals(m2.get('slave'), s1, 'precond - m2 should have s1');
|
365
|
+
equals(s1.get('master'), m2, 'precond - s1 should relate to m2');
|
366
|
+
|
367
|
+
equals(m1.get('slave'), s1, 'm1 should have child s1');
|
368
|
+
});
|
369
|
+
|
370
|
+
|
371
|
+
// ..........................................................
|
372
|
+
// RELINQUISHING RELATIONSHIPS
|
373
|
+
//
|
374
|
+
|
375
|
+
/**
|
376
|
+
[master] <----> [slave1]
|
377
|
+
|
378
|
+
precond - master has slave1
|
379
|
+
precond - slave1 has master
|
380
|
+
|
381
|
+
[master] <----> [slave2]
|
382
|
+
|
383
|
+
X--- [slave1]
|
384
|
+
|
385
|
+
precond - master has slave2
|
386
|
+
precond - slave2 has master
|
387
|
+
|
388
|
+
test - slave1 does NOT have master
|
389
|
+
*/
|
390
|
+
test("Relinquishing relationship on master<->* does propagate [one(master) to one(*)]", function () {
|
391
|
+
MyApp.Slave = SC.Record.extend({
|
392
|
+
master: SC.Record.toOne('MyApp.Master', {
|
393
|
+
inverse: 'slave',
|
394
|
+
isMaster: NO
|
395
|
+
})
|
396
|
+
});
|
397
|
+
|
398
|
+
MyApp.Master = SC.Record.extend({
|
399
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
400
|
+
inverse: 'master',
|
401
|
+
isMaster: YES
|
402
|
+
})
|
403
|
+
});
|
404
|
+
|
405
|
+
SC.RunLoop.begin();
|
406
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
407
|
+
{ guid: 's1' },
|
408
|
+
{ guid: 's2' }
|
409
|
+
]);
|
410
|
+
|
411
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
412
|
+
{ guid: 'm1', slave: 's1' }
|
413
|
+
]);
|
414
|
+
SC.RunLoop.end();
|
415
|
+
|
416
|
+
var s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
417
|
+
s2 = MyApp.store.find(MyApp.Slave, 's2'),
|
418
|
+
m1 = MyApp.store.find(MyApp.Master, 'm1');
|
419
|
+
|
420
|
+
equals(m1.get('slave'), s1, 'precond - m1 should have s1');
|
421
|
+
equals(s1.get('master'), m1, 'precond - s1 should relate to m1');
|
422
|
+
ok(SC.none(s2.get('master')), 'precond - s2 has NO master');
|
423
|
+
|
424
|
+
SC.RunLoop.begin();
|
425
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
426
|
+
{ guid: 'm1', slave: 's2' }
|
427
|
+
]);
|
428
|
+
SC.RunLoop.end();
|
429
|
+
|
430
|
+
equals(m1.get('slave'), s2, 'precond - m1 should have s2');
|
431
|
+
equals(s2.get('master'), m1, 'precond - s2 should relate to m1');
|
432
|
+
|
433
|
+
ok(SC.none(s1.get('master')), 'test1 - s1 should have NO master');
|
434
|
+
});
|
435
|
+
|
436
|
+
/**
|
437
|
+
[master] <----> [slave1, ..., slaveN]
|
438
|
+
|
439
|
+
precond - master has slaves
|
440
|
+
precond - slaves have master
|
441
|
+
|
442
|
+
[master] ---X [slave1]
|
443
|
+
|
444
|
+
precond - master does NOT have slave1
|
445
|
+
test - slave1 does NOT have master
|
446
|
+
*/
|
447
|
+
test("Relinquishing a toMany relationship does propagate from master [one(master) to many(*)]", function () {
|
448
|
+
MyApp.Slave = SC.Record.extend({
|
449
|
+
master: SC.Record.toOne('MyApp.Master', {
|
450
|
+
inverse: 'slaves',
|
451
|
+
isMaster: NO
|
452
|
+
})
|
453
|
+
});
|
454
|
+
|
455
|
+
MyApp.Master = SC.Record.extend({
|
456
|
+
slaves: SC.Record.toMany('MyApp.Slave', {
|
457
|
+
inverse: 'master',
|
458
|
+
isMaster: YES
|
459
|
+
})
|
460
|
+
});
|
461
|
+
|
462
|
+
SC.RunLoop.begin();
|
463
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
464
|
+
{ guid: 's1' },
|
465
|
+
{ guid: 's2' }
|
466
|
+
]);
|
467
|
+
|
468
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
469
|
+
{ guid: 'm1', slaves: ['s1', 's2'] }
|
470
|
+
]);
|
471
|
+
SC.RunLoop.end();
|
472
|
+
|
473
|
+
var s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
474
|
+
s2 = MyApp.store.find(MyApp.Slave, 's2'),
|
475
|
+
m1 = MyApp.store.find(MyApp.Master, 'm1');
|
476
|
+
|
477
|
+
equals(m1.get('slaves').length(), 2, 'precond1 - m1 should have 2 slaves');
|
478
|
+
equals(s1.get('master'), m1, 'precond2 - s1 should relate to m1');
|
479
|
+
equals(s2.get('master'), m1, 'precond3 - s2 should relate to m1');
|
480
|
+
|
481
|
+
SC.RunLoop.begin();
|
482
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
483
|
+
{ guid: 'm1', slaves: ['s1'] }
|
484
|
+
]);
|
485
|
+
SC.RunLoop.end();
|
486
|
+
|
487
|
+
equals(m1.get('slaves').length(), 1, 'precond4 - m1 should have 1 slave');
|
488
|
+
equals(m1.get('slaves').objectAt(0), s1, 'precond5 - m1 should have slave s1');
|
489
|
+
equals(s1.get('master'), m1, 'precond6 - s1 should relate to m1');
|
490
|
+
|
491
|
+
ok(SC.none(s2.get('master')), 's2 should NOT have master');
|
492
|
+
});
|
493
|
+
|
494
|
+
/**
|
495
|
+
[slave]
|
496
|
+
^
|
497
|
+
|
|
498
|
+
+--< [master1]
|
499
|
+
|
|
500
|
+
...
|
501
|
+
|
|
502
|
+
+--< [masterN]
|
503
|
+
|
504
|
+
precond - master1 has relationship to slave
|
505
|
+
precond - slave has relationship many masters
|
506
|
+
precond - slave has relationship to master1
|
507
|
+
|
508
|
+
...master1 relinquishes relationship to slave...
|
509
|
+
|
510
|
+
[slave]
|
511
|
+
^
|
512
|
+
|
|
513
|
+
...
|
514
|
+
|
|
515
|
+
+--< [masterN]
|
516
|
+
|
517
|
+
precond - master1 has no slave
|
518
|
+
test - slave has many masters, none of which is master1
|
519
|
+
|
520
|
+
*/
|
521
|
+
test("Relinquish propagates from many master to one slave [many(master) to one(slave)]", function () {
|
522
|
+
MyApp.Master = SC.Record.extend({
|
523
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
524
|
+
inverse: 'masters',
|
525
|
+
isMaster: YES
|
526
|
+
})
|
527
|
+
});
|
528
|
+
|
529
|
+
MyApp.Slave = SC.Record.extend({
|
530
|
+
masters: SC.Record.toMany('MyApp.Master', {
|
531
|
+
inverse: 'slave',
|
532
|
+
isMaster: NO
|
533
|
+
})
|
534
|
+
});
|
535
|
+
|
536
|
+
SC.RunLoop.begin();
|
537
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
538
|
+
{ guid: 's1' }
|
539
|
+
]);
|
540
|
+
|
541
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
542
|
+
{ guid: 'm1', slave: 's1' },
|
543
|
+
{ guid: 'm2', slave: 's1' }
|
544
|
+
]);
|
545
|
+
SC.RunLoop.end();
|
546
|
+
|
547
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
548
|
+
m2 = MyApp.store.find(MyApp.Master, 'm2'),
|
549
|
+
s1 = MyApp.store.find(MyApp.Slave, 's1');
|
550
|
+
|
551
|
+
equals(s1.get('masters').length(), 2, 'precond - s1 should have 2 masters');
|
552
|
+
equals(m1.get('slave'), s1, 'precond - m1 should have slave s1');
|
553
|
+
equals(m2.get('slave'), s1, 'precond - m2 should have slave s1');
|
554
|
+
|
555
|
+
SC.RunLoop.begin();
|
556
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
557
|
+
{ guid: 'm1' }
|
558
|
+
]);
|
559
|
+
SC.RunLoop.end();
|
560
|
+
|
561
|
+
ok(SC.none(m1.get('slave')), 'precond - m1 should NOT have relationship with s1');
|
562
|
+
equals(s1.get('masters').length(), 1, 's1 should have 1 master');
|
563
|
+
equals(s1.get('masters').indexOf(m1), -1, 'm1 should NOT be that master');
|
564
|
+
});
|
565
|
+
|
566
|
+
/**
|
567
|
+
[master1] ... [masterN]
|
568
|
+
v v
|
569
|
+
| |
|
570
|
+
>------- ... -> [slave1]
|
571
|
+
| |
|
572
|
+
... ...
|
573
|
+
| |
|
574
|
+
>------- ... -> [slaveN]
|
575
|
+
|
576
|
+
precond - masters have many slaves
|
577
|
+
precond - slaves have many masters
|
578
|
+
|
579
|
+
... master1 relinquishes relationship to slave1 ...
|
580
|
+
|
581
|
+
[master1] ... [masterN]
|
582
|
+
v v
|
583
|
+
| |
|
584
|
+
>-- X > [slave1]
|
585
|
+
| |
|
586
|
+
... ...
|
587
|
+
| |
|
588
|
+
>------- ... -> [slaveM]
|
589
|
+
|
590
|
+
precond - master1 has M-1 slaves (& not slave 1)
|
591
|
+
|
592
|
+
test - slave1 has N-1 masters
|
593
|
+
test - slave does NOT have relationship to master1
|
594
|
+
*/
|
595
|
+
test("Removing a relationship propagates from many master to many slave [many(master) to many(slave)]", function () {
|
596
|
+
MyApp.Master = SC.Record.extend({
|
597
|
+
slaves: SC.Record.toMany('MyApp.Slave', {
|
598
|
+
inverse: 'masters',
|
599
|
+
isMaster: YES
|
600
|
+
})
|
601
|
+
});
|
602
|
+
|
603
|
+
MyApp.Slave = SC.Record.extend({
|
604
|
+
masters: SC.Record.toMany('MyApp.Master', {
|
605
|
+
inverse: 'slaves',
|
606
|
+
isMaster: NO
|
607
|
+
})
|
608
|
+
});
|
609
|
+
|
610
|
+
SC.RunLoop.begin();
|
611
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
612
|
+
{ guid: 's1' },
|
613
|
+
{ guid: 's2' }
|
614
|
+
]);
|
615
|
+
|
616
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
617
|
+
{ guid: 'm1', slaves: ['s1', 's2'] },
|
618
|
+
{ guid: 'm2', slaves: ['s1', 's2'] }
|
619
|
+
]);
|
620
|
+
SC.RunLoop.end();
|
621
|
+
|
622
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
623
|
+
m2 = MyApp.store.find(MyApp.Master, 'm2'),
|
624
|
+
s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
625
|
+
s2 = MyApp.store.find(MyApp.Slave, 's2');
|
626
|
+
|
627
|
+
equals(m1.get('slaves').length(), 2, 'precond - m1 should have 2 slaves');
|
628
|
+
equals(m2.get('slaves').length(), 2, 'precond - m2 should have 2 slaves');
|
629
|
+
ok(s1.get('masters').indexOf(m1) !== -1, 'precond - s1 should have m1 as a master');
|
630
|
+
ok(s1.get('masters').indexOf(m2) !== -1, 'precond - s1 should have m2 as a master');
|
631
|
+
ok(s2.get('masters').indexOf(m1) !== -1, 'precond - s2 should have m1 as a master');
|
632
|
+
ok(s2.get('masters').indexOf(m2) !== -1, 'precond - s2 should have m2 as a master');
|
633
|
+
|
634
|
+
SC.RunLoop.begin();
|
635
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
636
|
+
{ guid: 'm1', slaves: ['s2'] }
|
637
|
+
]);
|
638
|
+
SC.RunLoop.end();
|
639
|
+
|
640
|
+
equals(m1.get('slaves').length(), 1, 'precond - m1 should have 1 slave');
|
641
|
+
equals(m1.get('slaves').objectAt(0), s2, 'precond - m1 should have relationship to s2');
|
642
|
+
|
643
|
+
ok(s1.get('masters').indexOf(m1) === -1, 's1 should NOT have m1 as a master');
|
644
|
+
ok(s1.get('masters').indexOf(m2) !== -1, 's1 should have m2 as a master');
|
645
|
+
});
|
646
|
+
|
647
|
+
// ..........................................................
|
648
|
+
// pushDestroy BEHAVIOR
|
649
|
+
//
|
650
|
+
|
651
|
+
/**
|
652
|
+
[master] --> [slave]
|
653
|
+
|
654
|
+
precond - master has slave
|
655
|
+
precond - slave has master
|
656
|
+
|
657
|
+
... pushDestroy master ...
|
658
|
+
|
659
|
+
test - slave has NO master
|
660
|
+
*/
|
661
|
+
test("pushDestroy record propagates from master to slave [*(master) to one(slave)]", function () {
|
662
|
+
MyApp.Master = SC.Record.extend({
|
663
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
664
|
+
inverse: 'master',
|
665
|
+
isMaster: YES
|
666
|
+
})
|
667
|
+
});
|
668
|
+
|
669
|
+
MyApp.Slave = SC.Record.extend({
|
670
|
+
master: SC.Record.toOne('MyApp.Master', {
|
671
|
+
inverse: 'slave',
|
672
|
+
isMaster: NO
|
673
|
+
})
|
674
|
+
});
|
675
|
+
|
676
|
+
SC.RunLoop.begin();
|
677
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
678
|
+
{ guid: 's1' }
|
679
|
+
]);
|
680
|
+
|
681
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
682
|
+
{ guid: 'm1', slave: 's1' }
|
683
|
+
]);
|
684
|
+
SC.RunLoop.end();
|
685
|
+
|
686
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
687
|
+
s1 = MyApp.store.find(MyApp.Slave, 's1');
|
688
|
+
|
689
|
+
equals(m1.get('slave'), s1, 'precond - m1 should have s1 as slave');
|
690
|
+
equals(s1.get('master'), m1, 'precond - s1 should have m1 as slave');
|
691
|
+
|
692
|
+
SC.RunLoop.begin();
|
693
|
+
MyApp.store.pushDestroy(MyApp.Master, 'm1');
|
694
|
+
SC.RunLoop.end();
|
695
|
+
|
696
|
+
equals(m1.get('status'), SC.Record.DESTROYED_CLEAN, 'precond - m1 was destroyed');
|
697
|
+
ok(SC.none(s1.get('master')), 's1 should NOT have a master');
|
698
|
+
});
|
699
|
+
|
700
|
+
/**
|
701
|
+
[master] --> [slave]
|
702
|
+
|
703
|
+
precond - master has slave
|
704
|
+
precond - slave has master
|
705
|
+
|
706
|
+
... pushDestroy master ...
|
707
|
+
|
708
|
+
test - slave has NO master
|
709
|
+
*/
|
710
|
+
test("pushDestroy record propagates from master to many slaves [*(master) to many(slave)]", function () {
|
711
|
+
MyApp.Master = SC.Record.extend({
|
712
|
+
slaves: SC.Record.toMany('MyApp.Slave', {
|
713
|
+
inverse: 'masters',
|
714
|
+
isMaster: YES
|
715
|
+
})
|
716
|
+
});
|
717
|
+
|
718
|
+
MyApp.Slave = SC.Record.extend({
|
719
|
+
masters: SC.Record.toMany('MyApp.Master', {
|
720
|
+
inverse: 'slaves',
|
721
|
+
isMaster: NO
|
722
|
+
})
|
723
|
+
});
|
724
|
+
|
725
|
+
SC.RunLoop.begin();
|
726
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
727
|
+
{ guid: 's1' },
|
728
|
+
{ guid: 's2' }
|
729
|
+
]);
|
730
|
+
|
731
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
732
|
+
{ guid: 'm1', slaves: ['s1', 's2'] }
|
733
|
+
]);
|
734
|
+
SC.RunLoop.end();
|
735
|
+
|
736
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
737
|
+
s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
738
|
+
s2 = MyApp.store.find(MyApp.Slave, 's2');
|
739
|
+
|
740
|
+
equals(m1.get('slaves').length(), 2, 'precond - m1 should have 2 slaves');
|
741
|
+
ok(s1.get('masters').indexOf(m1) !== -1, 'precond - s1 should have m1 as a master');
|
742
|
+
ok(s2.get('masters').indexOf(m1) !== -1, 'precond - s2 should have m1 as a master');
|
743
|
+
|
744
|
+
SC.RunLoop.begin();
|
745
|
+
MyApp.store.pushDestroy(MyApp.Master, 'm1');
|
746
|
+
SC.RunLoop.end();
|
747
|
+
|
748
|
+
equals(m1.get('status'), SC.Record.DESTROYED_CLEAN, 'precond - m1 was destroyed');
|
749
|
+
equals(s1.get('masters').length(), 0, 's1 should NOT have a master');
|
750
|
+
equals(s2.get('masters').length(), 0, 's2 should NOT have a master');
|
751
|
+
});
|
752
|
+
|
753
|
+
/**
|
754
|
+
[master] --> [slave]
|
755
|
+
|
756
|
+
precond - slave has a master
|
757
|
+
precond - master has a slave
|
758
|
+
|
759
|
+
slave.destroy();
|
760
|
+
|
761
|
+
precond - slave is destroyed
|
762
|
+
|
763
|
+
... pushDestroy master ...
|
764
|
+
|
765
|
+
test - slave does NOT exist
|
766
|
+
test - master does NOT exist
|
767
|
+
*/
|
768
|
+
test("pushDestroy record doesn't create a slave when it's been destroyed [*(master) to one(slave)]", function () {
|
769
|
+
MyApp.Master = SC.Record.extend({
|
770
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
771
|
+
inverse: 'master',
|
772
|
+
isMaster: YES
|
773
|
+
})
|
774
|
+
});
|
775
|
+
|
776
|
+
MyApp.Slave = SC.Record.extend({
|
777
|
+
master: SC.Record.toOne('MyApp.Master', {
|
778
|
+
inverse: 'slave',
|
779
|
+
isMaster: NO
|
780
|
+
})
|
781
|
+
});
|
782
|
+
|
783
|
+
SC.RunLoop.begin();
|
784
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
785
|
+
{ guid: 's1' }
|
786
|
+
]);
|
787
|
+
|
788
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
789
|
+
{ guid: 'm1', slave: 's1' }
|
790
|
+
]);
|
791
|
+
SC.RunLoop.end();
|
792
|
+
|
793
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
794
|
+
s1 = MyApp.store.find(MyApp.Slave, 's1');
|
795
|
+
|
796
|
+
equals(m1.get('slave'), s1, 'precond - m1 should have 2 slaves');
|
797
|
+
equals(s1.get('master'), m1, 'precond - s1 should have m1 as a master');
|
798
|
+
|
799
|
+
SC.RunLoop.begin();
|
800
|
+
s1.destroy();
|
801
|
+
MyApp.store.commitRecords();
|
802
|
+
MyApp.store.dataSourceDidDestroy(s1.storeKey);
|
803
|
+
SC.RunLoop.end();
|
804
|
+
|
805
|
+
ok(s1.isDestroyed(), 'precond - s1 should be destroyed');
|
806
|
+
|
807
|
+
SC.RunLoop.begin();
|
808
|
+
MyApp.store.pushDestroy(MyApp.Master, 'm1');
|
809
|
+
SC.RunLoop.end();
|
810
|
+
|
811
|
+
ok(s1.isDestroyed(), 'test - s1 should be destroyed');
|
812
|
+
ok(m1.isDestroyed(), 'test - m1 should be destroyed');
|
813
|
+
});
|
814
|
+
|
815
|
+
/**
|
816
|
+
Standard Sproutcore Behaviors
|
817
|
+
|
818
|
+
This is data showing up from the server- after pushing in changes,
|
819
|
+
all records should have status READY_CLEAN.
|
820
|
+
*/
|
821
|
+
test("Record status for master and slave should be READY_CLEAN", function () {
|
822
|
+
MyApp.Master = SC.Record.extend({
|
823
|
+
master: SC.Record.toOne('MyApp.Slave', {
|
824
|
+
inverse: 'slave',
|
825
|
+
isMaster: YES
|
826
|
+
})
|
827
|
+
});
|
828
|
+
|
829
|
+
MyApp.Slave = SC.Record.extend({
|
830
|
+
slave: SC.Record.toOne('MyApp.Master', {
|
831
|
+
inverse: 'master',
|
832
|
+
isMaster: NO
|
833
|
+
})
|
834
|
+
});
|
835
|
+
|
836
|
+
// link one -> one
|
837
|
+
SC.RunLoop.begin();
|
838
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
839
|
+
{ guid: 's1' }
|
840
|
+
]);
|
841
|
+
SC.RunLoop.end();
|
842
|
+
|
843
|
+
var s1 = MyApp.store.find(MyApp.Slave, 's1');
|
844
|
+
ok(s1.get('status') & SC.Record.READY_CLEAN, 'precond - s1 should be ready clean');
|
845
|
+
|
846
|
+
SC.RunLoop.begin();
|
847
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
848
|
+
{ guid: 'm1', slave: 's1' }
|
849
|
+
]);
|
850
|
+
SC.RunLoop.end();
|
851
|
+
|
852
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1');
|
853
|
+
|
854
|
+
ok(m1.get('status') & SC.Record.READY_CLEAN, 'm1 should be ready clean after linkage');
|
855
|
+
ok(s1.get('status') & SC.Record.READY_CLEAN, 's1 should be ready clean after linkage');
|
856
|
+
|
857
|
+
// unlink
|
858
|
+
SC.RunLoop.begin();
|
859
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
860
|
+
{ guid: 'm1' }
|
861
|
+
]);
|
862
|
+
SC.RunLoop.end();
|
863
|
+
|
864
|
+
ok(m1.get('status') & SC.Record.READY_CLEAN, 'm1 should be ready clean after unlink');
|
865
|
+
ok(s1.get('status') & SC.Record.READY_CLEAN, 's1 should be ready clean after unlink');
|
866
|
+
});
|
867
|
+
|
868
|
+
test("Record relationships are NOT propagated if related store item does NOT exist at load time", function () {
|
869
|
+
MyApp.Generic = SC.Record.extend({
|
870
|
+
relative: SC.Record.toOne('MyApp.Generic', {
|
871
|
+
inverse: 'relative',
|
872
|
+
isMaster: YES
|
873
|
+
})
|
874
|
+
});
|
875
|
+
|
876
|
+
SC.RunLoop.begin();
|
877
|
+
MyApp.store.loadRecords(MyApp.Generic, [
|
878
|
+
{ guid: 'g2', relative: 'g1' },
|
879
|
+
{ guid: 'g1' }
|
880
|
+
]);
|
881
|
+
SC.RunLoop.end();
|
882
|
+
|
883
|
+
var g1 = MyApp.store.find(MyApp.Generic, 'g1'),
|
884
|
+
g2 = MyApp.store.find(MyApp.Generic, 'g2');
|
885
|
+
|
886
|
+
equals(g2.get('relative'), g1, 'precond - g2 should be relative of g1');
|
887
|
+
ok(SC.none(g1.get('relative')), 'g1 should not be related to g2');
|
888
|
+
});
|
889
|
+
|
890
|
+
test("Record Attribute can reference renamed attribute key", function () {
|
891
|
+
MyApp.Master = SC.Record.extend({
|
892
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
893
|
+
inverse: 'master',
|
894
|
+
isMaster: YES,
|
895
|
+
key: 'alice'
|
896
|
+
})
|
897
|
+
});
|
898
|
+
|
899
|
+
MyApp.Slave = SC.Record.extend({
|
900
|
+
master: SC.Record.toOne('MyApp.Master', {
|
901
|
+
inverse: 'slave',
|
902
|
+
isMaster: NO
|
903
|
+
})
|
904
|
+
});
|
905
|
+
|
906
|
+
// link one -> one
|
907
|
+
SC.RunLoop.begin();
|
908
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
909
|
+
{ guid: 's1' }
|
910
|
+
]);
|
911
|
+
SC.RunLoop.end();
|
912
|
+
|
913
|
+
|
914
|
+
var s1 = MyApp.store.find(MyApp.Slave, 's1');
|
915
|
+
ok(s1.get('status') & SC.Record.READY_CLEAN, 'precond - s1 should be ready clean');
|
916
|
+
|
917
|
+
SC.RunLoop.begin();
|
918
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
919
|
+
{ guid: 'm1', alice: 's1' }
|
920
|
+
]);
|
921
|
+
SC.RunLoop.end();
|
922
|
+
|
923
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1');
|
924
|
+
|
925
|
+
equals(m1.get('slave'), s1, 'm1 should be master of s1');
|
926
|
+
equals(s1.get('master'), m1, 's1 should have master of m1');
|
927
|
+
});
|
928
|
+
|
929
|
+
|
930
|
+
test("Record Attribute can reference renamed attribute key (on remote side)", function () {
|
931
|
+
MyApp.Master = SC.Record.extend({
|
932
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
933
|
+
inverse: 'master',
|
934
|
+
isMaster: YES
|
935
|
+
})
|
936
|
+
});
|
937
|
+
|
938
|
+
MyApp.Slave = SC.Record.extend({
|
939
|
+
master: SC.Record.toOne('MyApp.Master', {
|
940
|
+
inverse: 'slave',
|
941
|
+
isMaster: NO,
|
942
|
+
key: 'bob'
|
943
|
+
})
|
944
|
+
});
|
945
|
+
|
946
|
+
// link one -> one
|
947
|
+
SC.RunLoop.begin();
|
948
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
949
|
+
{ guid: 's1' }
|
950
|
+
]);
|
951
|
+
SC.RunLoop.end();
|
952
|
+
|
953
|
+
|
954
|
+
var s1 = MyApp.store.find(MyApp.Slave, 's1');
|
955
|
+
ok(s1.get('status') & SC.Record.READY_CLEAN, 'precond - s1 should be ready clean');
|
956
|
+
|
957
|
+
SC.RunLoop.begin();
|
958
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
959
|
+
{ guid: 'm1', slave: 's1' }
|
960
|
+
]);
|
961
|
+
SC.RunLoop.end();
|
962
|
+
|
963
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1');
|
964
|
+
|
965
|
+
equals(m1.get('slave'), s1, 'm1 should be master of s1');
|
966
|
+
equals(s1.get('master'), m1, 's1 should have master of m1');
|
967
|
+
});
|
968
|
+
|
969
|
+
test("Record property does change on linkage", function () {
|
970
|
+
MyApp.Generic = SC.Record.extend({
|
971
|
+
relative: SC.Record.toOne('MyApp.Generic', {
|
972
|
+
inverse: 'relative',
|
973
|
+
isMaster: YES
|
974
|
+
}),
|
975
|
+
|
976
|
+
callCount: 0,
|
977
|
+
|
978
|
+
_relativeObserver: function () {
|
979
|
+
this.incrementProperty('callCount');
|
980
|
+
}.observes('relative')
|
981
|
+
});
|
982
|
+
|
983
|
+
SC.RunLoop.begin();
|
984
|
+
MyApp.store.loadRecords(MyApp.Generic, [
|
985
|
+
{ guid: 'g1' },
|
986
|
+
{ guid: 'g2' }
|
987
|
+
]);
|
988
|
+
SC.RunLoop.end();
|
989
|
+
|
990
|
+
var g1 = MyApp.store.find(MyApp.Generic, 'g1'),
|
991
|
+
g2 = MyApp.store.find(MyApp.Generic, 'g2');
|
992
|
+
|
993
|
+
equals(g1.get('callCount'), 0, 'precond - g1._relativeObserver should NOT have fired yet');
|
994
|
+
equals(g2.get('callCount'), 0, 'precond - g2._relativeObserver should NOT have fired yet');
|
995
|
+
|
996
|
+
SC.RunLoop.begin();
|
997
|
+
MyApp.store.loadRecords(MyApp.Generic, [
|
998
|
+
{ guid: 'g2', relative: 'g1' }
|
999
|
+
]);
|
1000
|
+
SC.RunLoop.end();
|
1001
|
+
|
1002
|
+
equals(g1.get('relative'), g2, 'precond - g1 should be relative of g2');
|
1003
|
+
equals(g2.get('relative'), g1, 'precond - g2 should be relative of g1');
|
1004
|
+
|
1005
|
+
equals(g1.get('callCount'), 1, 'g1._relativeObserver should fire once');
|
1006
|
+
equals(g2.get('callCount'), 1, 'g2._relativeObserver should fire once');
|
1007
|
+
});
|
1008
|
+
|
1009
|
+
// ..........................................................
|
1010
|
+
// RECORD ATTRIBUTE
|
1011
|
+
//
|
1012
|
+
|
1013
|
+
/**
|
1014
|
+
lazilyInstantiate RecordAttribute flag tests.
|
1015
|
+
*/
|
1016
|
+
test("RecordAttribute flag 'lazilyInstantiate' tests", function () {
|
1017
|
+
MyApp.Master = SC.Record.extend({
|
1018
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
1019
|
+
inverse: 'master',
|
1020
|
+
isMaster: YES,
|
1021
|
+
lazilyInstantiate: YES
|
1022
|
+
})
|
1023
|
+
});
|
1024
|
+
|
1025
|
+
MyApp.Slave = SC.Record.extend({
|
1026
|
+
master: SC.Record.toOne('MyApp.Master', {
|
1027
|
+
inverse: 'slave',
|
1028
|
+
isMaster: NO,
|
1029
|
+
lazilyInstantiate: YES // should be a noop
|
1030
|
+
})
|
1031
|
+
});
|
1032
|
+
|
1033
|
+
SC.RunLoop.begin();
|
1034
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
1035
|
+
{ guid: 'm1', slave: 's1' }
|
1036
|
+
]);
|
1037
|
+
|
1038
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
1039
|
+
{ guid: 's2', master: 'm2' }
|
1040
|
+
]);
|
1041
|
+
SC.RunLoop.end();
|
1042
|
+
|
1043
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
1044
|
+
m2 = MyApp.store.find(MyApp.Master, 'm2'),
|
1045
|
+
s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
1046
|
+
s2 = MyApp.store.find(MyApp.Slave, 's2');
|
1047
|
+
|
1048
|
+
// test lazy creation on isMaster => YES
|
1049
|
+
ok(s1, 's1 should be created lazily');
|
1050
|
+
equals(m1.get('slave'), s1, 'm1 should be master of s1');
|
1051
|
+
|
1052
|
+
// test lazy creation fails on isMaster => NO
|
1053
|
+
ok(SC.none(m2), 'm2 should NOT have been creaetd');
|
1054
|
+
ok(!s2.get('master') ||
|
1055
|
+
s2.get('master').get('status') & SC.Record.ERROR, 's2 should have no master record');
|
1056
|
+
});
|
1057
|
+
|
1058
|
+
/**
|
1059
|
+
lazilyInstantiate RecordAttribute flag can be a function.
|
1060
|
+
*/
|
1061
|
+
test("RecordAttribute flag 'lazilyInstantiate' can be a function", function () {
|
1062
|
+
MyApp.Master = SC.Record.extend({
|
1063
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
1064
|
+
inverse: 'master',
|
1065
|
+
isMaster: YES,
|
1066
|
+
lazilyInstantiate: function () {
|
1067
|
+
return NO;
|
1068
|
+
}
|
1069
|
+
})
|
1070
|
+
});
|
1071
|
+
|
1072
|
+
MyApp.Slave = SC.Record.extend({
|
1073
|
+
master: SC.Record.toOne('MyApp.Master', {
|
1074
|
+
inverse: 'slave',
|
1075
|
+
isMaster: NO,
|
1076
|
+
lazilyInstantiate: YES // should be a noop
|
1077
|
+
})
|
1078
|
+
});
|
1079
|
+
|
1080
|
+
SC.RunLoop.begin();
|
1081
|
+
MyApp.store.loadRecords(MyApp.Master, [
|
1082
|
+
{ guid: 'm1', slave: 's1' }
|
1083
|
+
]);
|
1084
|
+
|
1085
|
+
MyApp.store.loadRecords(MyApp.Slave, [
|
1086
|
+
{ guid: 's2', master: 'm2' }
|
1087
|
+
]);
|
1088
|
+
SC.RunLoop.end();
|
1089
|
+
|
1090
|
+
var m1 = MyApp.store.find(MyApp.Master, 'm1'),
|
1091
|
+
m2 = MyApp.store.find(MyApp.Master, 'm2'),
|
1092
|
+
s1 = MyApp.store.find(MyApp.Slave, 's1'),
|
1093
|
+
s2 = MyApp.store.find(MyApp.Slave, 's2');
|
1094
|
+
|
1095
|
+
// test lazy creation on isMaster => NO
|
1096
|
+
ok(!s1, 's1 should NOT be created lazily');
|
1097
|
+
|
1098
|
+
// test lazy creation fails on isMaster => NO
|
1099
|
+
ok(SC.none(m2), 'm2 should NOT have been creaetd');
|
1100
|
+
ok(!s2.get('master') ||
|
1101
|
+
s2.get('master').get('status') & SC.Record.ERROR, 's2 should have no master record');
|
1102
|
+
});
|
1103
|
+
|
1104
|
+
|
1105
|
+
/**
|
1106
|
+
lazilyInstantiate should ride the chain all the way to the top.
|
1107
|
+
|
1108
|
+
That is, if a record's primaryKey is a record that has the
|
1109
|
+
flag 'lazilyInstantiate' on it, it should lazily create that one,
|
1110
|
+
and so on.
|
1111
|
+
*/
|
1112
|
+
test("RecordAttribute flag 'lazilyInstantiate' will create chains of records properly", function () {
|
1113
|
+
MyApp.SuperMaster = SC.Record.extend({
|
1114
|
+
master: SC.Record.toOne('MyApp.Master', {
|
1115
|
+
inverse: 'superMaster',
|
1116
|
+
isMaster: YES,
|
1117
|
+
lazilyInstantiate: YES
|
1118
|
+
})
|
1119
|
+
});
|
1120
|
+
|
1121
|
+
MyApp.Master = SC.Record.extend({
|
1122
|
+
primaryKey: 'slave',
|
1123
|
+
|
1124
|
+
superMaster: SC.Record.toOne('MyApp.SuperMaster', {
|
1125
|
+
inverse: 'master',
|
1126
|
+
isMaster: NO
|
1127
|
+
}),
|
1128
|
+
|
1129
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
1130
|
+
inverse: 'master',
|
1131
|
+
isMaster: YES,
|
1132
|
+
lazilyInstantiate: YES
|
1133
|
+
})
|
1134
|
+
});
|
1135
|
+
|
1136
|
+
MyApp.Slave = SC.Record.extend({
|
1137
|
+
primaryKey: 'subSlave',
|
1138
|
+
|
1139
|
+
master: SC.Record.toOne('MyApp.Master', {
|
1140
|
+
inverse: 'slave',
|
1141
|
+
isMaster: NO
|
1142
|
+
}),
|
1143
|
+
|
1144
|
+
subSlave: SC.Record.toOne('MyApp.SubSlave', {
|
1145
|
+
inverse: 'slave',
|
1146
|
+
isMaster: YES,
|
1147
|
+
lazilyInstantiate: YES
|
1148
|
+
})
|
1149
|
+
});
|
1150
|
+
|
1151
|
+
MyApp.SubSlave = SC.Record.extend({
|
1152
|
+
slave: SC.Record.toOne('MyApp.Slave', {
|
1153
|
+
inverse: 'subSlave',
|
1154
|
+
isMaster: NO
|
1155
|
+
})
|
1156
|
+
});
|
1157
|
+
|
1158
|
+
SC.RunLoop.begin();
|
1159
|
+
MyApp.store.loadRecords(MyApp.SuperMaster, [
|
1160
|
+
{ guid: 'sm', master: 's' }
|
1161
|
+
]);
|
1162
|
+
SC.RunLoop.end();
|
1163
|
+
|
1164
|
+
var sm = MyApp.store.find(MyApp.SuperMaster, 'sm'),
|
1165
|
+
m = MyApp.store.find(MyApp.Master, 's'),
|
1166
|
+
s = MyApp.store.find(MyApp.Slave, 's'),
|
1167
|
+
ss = MyApp.store.find(MyApp.SubSlave, 's');
|
1168
|
+
|
1169
|
+
ok(m, 'm should be created lazily');
|
1170
|
+
equals(m.get('superMaster'), sm, 'sm should be master of m');
|
1171
|
+
|
1172
|
+
ok(s, 's should be created lazily');
|
1173
|
+
equals(s.get('master'), m, 'm should be master of s');
|
1174
|
+
|
1175
|
+
ok(ss, 'ss should be created lazily');
|
1176
|
+
equals(ss.get('slave'), s, 's should be master of ss');
|
1177
|
+
});
|