├── .gitignore
├── LICENSE
├── README.md
├── VERSION
├── doc
└── getting_started.md
├── example
├── Framework_Verify.css
├── Framework_Verify.dart
└── Framework_Verify.html
├── lib
├── puremvc.dart
└── src
│ ├── core
│ ├── Controller.dart
│ ├── Model.dart
│ └── View.dart
│ ├── interfaces
│ ├── ICommand.dart
│ ├── IController.dart
│ ├── IFacade.dart
│ ├── IMediator.dart
│ ├── IModel.dart
│ ├── INotification.dart
│ ├── INotifier.dart
│ ├── IObserver.dart
│ ├── IProxy.dart
│ └── IView.dart
│ └── patterns
│ ├── command
│ ├── MacroCommand.dart
│ └── SimpleCommand.dart
│ ├── facade
│ └── Facade.dart
│ ├── mediator
│ └── Mediator.dart
│ ├── observer
│ ├── Notification.dart
│ ├── Notifier.dart
│ └── Observer.dart
│ └── proxy
│ └── Proxy.dart
├── pubspec.yaml
└── test
├── Test_Controller.dart
├── Test_Facade.dart
├── Test_MacroCommand.dart
├── Test_Mediator.dart
├── Test_Model.dart
├── Test_Notification.dart
├── Test_Observer.dart
├── Test_Proxy.dart
├── Test_SimpleCommand.dart
├── Test_View.dart
├── Unit_Tests.css
├── Unit_Tests.dart
└── Unit_Tests.html
/.gitignore:
--------------------------------------------------------------------------------
1 | pubspec.lock
2 | *.dart.js*
3 | *.dart.js.deps*
4 | *.dart.precompiled.js
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PureMVC/puremvc-dart-multicore-framework/0fdeffe9ca34bcf11350e8bf815566d47c6fd06f/LICENSE
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PureMVC/puremvc-dart-multicore-framework/0fdeffe9ca34bcf11350e8bf815566d47c6fd06f/README.md
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | PureMVC MultiCore Framework for Dart
2 | --------------------------------------------------------------------------
3 | Release Date: 11/14/2013
4 | Platform: Google Dart
5 | Version: 2
6 | Revision: 0
7 | Minor: 6
8 | Authors: Cliff Hall
9 | --------------------------------------------------------------------------
10 | 2.0.6 Update pubspec.yaml
11 | - environment: sdk: '>=0.8.10+6 <2.0.0'
12 | - dependencies:
13 | analyzer: '>=0.10.1 <0.11.0'
14 | browser: '>=0.9.0 <0.10.0'
15 | - dev_dependencies:
16 | unittest: '>=0.9.0 <0.10.0'
17 | Replace query() with querySelector() in Framework Test Page.
18 | Remove Unit_Tests_Config.dart and use framework enhanceed config.
19 |
20 | 2.0.5 Update pubspec.yaml
21 | - Use browser:any
22 | - Make unitest:any a dev dependency.
23 | Replace Expect with expect() in unit test classes.
24 | Modify Framework_Verify.html / Unit_Tests.html to
25 | - Reference packages/browser/dart.js.
26 | - Use innerHtml instead of innerHTML
27 | Modify Unit_Tests.html / Unit_Tests.dart
28 | - Set unittestConfiguration with the config
29 | - Reference packages/browser/dart.js.
30 | - Use innerHtml instead of innerHTML
31 |
32 | 2.0.4 Replace interface keyword with abstract class for M2
33 | Add part keywords
34 | Change Dynamic to dynamic
35 |
36 | 2.0.3 Modify pubspec.yaml again to bump the version number. Doh!
37 |
38 | 2.0.2 Modify pubspec.yaml to pull in the unit test framework from pub
39 |
40 | 2.0.1 Code cleanup to keep up with changes in Dart SDK version 0.2.2.1_r14458.
41 | Includes:
42 | - Fixed missing 'part of' directives
43 | - New library and import syntax
44 | - new getter syntax
45 | - other minor things like whitespace cleanup
46 |
47 | 2.0 Refactor to meet standards for Dart PubSpec.
48 | - library layout changes.
49 | - inclusion of unit tests (was in a separate project)
50 | - added pubspec.yaml, README.md
51 | Also, in the spirit of Dart M1, made the backward incompatible
52 | change of dropping all the MVC prefixes from the classnames
53 | in favor of using package prefix in code.
54 |
55 | 1.3 Fixed string concatenation errors in the Framework Validation Page.
56 | No changes to the framework itself.
57 |
58 | 1.2 Included .project and .children so that Dart Editor can
59 | run the framework verification page (PureMVC_Dart.dart).
60 | The need for these files should be eliminated in a future
61 | version of the editor, but they are required now.
62 |
63 | 1.1 Lots of updates and corrections to the documentation.
64 |
65 | Moved classes and interfaces into the folder locations of the
66 | reference implementation.
67 |
68 | Updated the Framework Verification Page (PureMVC_Dart.dart/html)
69 | to detect errors and give a definitive statement about the
70 | framework's operational status.
71 |
72 | Also we made the decision to disallow null multiton keys. In the
73 | original ActionScript, this is never a problem, but in the final
74 | JavaScript Dart compiles to, contention could arise if multiple
75 | apps by different vendors appear in the same page and both call
76 | Facade.getInstance() without a multiton key.
77 |
78 | 1.0 Initial version of Dart MultiCore port on PureMVC.org.
79 |
--------------------------------------------------------------------------------
/doc/getting_started.md:
--------------------------------------------------------------------------------
1 | ## The PureMVC MultiCore Framework for Dart.
2 |
3 | PureMVC is a lightweight framework for creating applications based upon the classic Model-View-Controller design meta-pattern. It supports modular programming through the use of Multiton Core actors.
4 |
5 | ## General Overview
6 |
7 | * To separate coding concerns, an application (or a module in an application) is divided into three 'tiers': Model, View, and Controller.
8 | * PureMVC implements these tiers as Multiton classes which register and manage communications between the workhorse actors that operate within those tiers.
9 | * PureMVC also provides a handy frontend to the whole system called a Facade.
10 | * Since methods for message passing vary from platform to platform, PureMVC implements its own internal Observer Notification system for its actors to communicate with each other. These are not an alternative for Events. Your application's boundary classes will still interact with the DOM and services and PureMVC via Events.
11 |
12 | ## The Model Tier is handled by the Model Multiton
13 |
14 | * In the Model tier, you usually create some Value Object classes. These aren't tied to the framework and shouldn't know anything about the framework classes, they just hold data for the rest of the program to use.
15 | * The Model registers and holds instances of the Proxy class (or your subclasses)
16 | * Proxy instances are registered and retrieved from the Model by name.
17 | * Proxy classes provide access to data, local storage, and remote services. Usually a Proxy will manage a single Value Object instance or collection. For example, rather than return raw XML or JSON for the rest of the app to parse, the Proxy will convert raw data coming from sevices into typed Value Objects, easily consumed by the rest of the program.
18 | * Proxy classes do not respond to Notifications. They can be directly updated by Mediators and ICommands.
19 | * Proxy classes should not send Notification names defined elsewhere in the application. They should define their own notification names, so that the classes of the Model tier remain portable and may be unit tested or reused in other applications.
20 |
21 | ## The View Tier is handled by the View Multiton
22 |
23 | * Within the View Tier, you will usually create one or more view components, which you will write to interact directly with the Browser/DOM, listening for button presses, etc. These do not use any PureMVC framework classes and should only know about your Value Object classes in order to display, create, and modify data used by the rest of the app. They will hide the implementation of the DOM from the rest of the app, translating the button clicks and keystrokes into higher-level events that represent user intentions for initiating use-cases.
24 | * The View Multiton registers and holds instances of Mediator subclasses.
25 | * Mediators don't do heavy lifting. They are essentially switchboard operators that receive data from the rest of the app via Notification, and pass it to their view components, or receive events from their view components and in turn pass the user intention on to the rest of the app in the form of a Notification.
26 | * A Mediator will tend a particular view component, setting event listeners on it, which it handles usually by sending off Notifications to be dealt with by other Mediators and/or ICommands.
27 | * A Mediator also may assert an interest in certain Notification names, which it will be notified about if sent by other actors or itself.
28 | * A Mediator may also retrieve a Proxy and call a method on it, bypassing the Controller tier.
29 |
30 | ## The Controller Tier is handled by the Controller Multiton
31 |
32 | * Within the Controller tier, you will usually create any Notification name constants that are shared by the View and Controller tiers. Remember that Notification names sent from Proxys should be defined on the Proxys themselves for portability.
33 | * The Controller Multiton registers Notification name to ICommand mappings.
34 | * When a Notification with a registered name is sent by a Proxy, Mediator, or ICommand, the mapped ICommand is instantiated and its execute() method is called, passing in a reference to the Notification that triggered the ICommand.
35 | * The framework provides two types of ICommand implementors: MacroCommand and SimpleCommand, which you subclass to add SubCommands and business logic, respectively.
36 | * The MacroCommand executes a given set of ICommands in order, passing the Notification to each 'SubCommand' in turn. Note that a SubCommand may modify the Notification body and type and the next SubCommand will receive the modified Notification.
37 | * The SimpleCommand executes some business logic which you define. It only stays in memory until its code has been executed unless some other actor keeps a reference to it, which usually isn't desirable, but there is a formal request pattern that can be implemented that makes sense (See the O'Reilly book for info).
38 |
39 | ## The Facade Multiton provides one-stop access to Model, View, and Controller
40 |
41 | * This keeps the developer from needing to interact with all the Multitons separately.
42 | * The Facade Multiton implements all the methods of the the Model, View, and Controller Multitons and manages their creation.
43 | * Calling Facade.getInstance('someMultitonKey') for the first time, creates each of the Model, View, and Controller Multitons for that key automatically. After that, the same instance will always be returned for a given key.
44 | * All Proxy, Mediator, and ICommand instances already have a reference to their Facade instance when their onRegister() or execute() methods are called. Thus you never have to retrieve the Facade except when the Core is created.
45 | * Q: Why not just build all the MVC functionality into the Facade in the first place? A: Because it allows the developer to replace just part of the system with a custom version if they wish, leaving the other parts untouched.
46 |
47 | ## Bootstrapping your Application
48 |
49 | * Usually, your main application class will retrieve the Facade instance, register a StartupCommand, and trigger it by sending a STARTUP notification.
50 | * The StartupCommand may be a SimpleCommand or a MacroCommand that breaks the startup process into several SimpleCommands.
51 | * Regardless of implementation, the business of the StartupCommand is to prepare the Controller, Model, and View - in that order.
52 | * The Controller is prepared by registering all the Notification/ICommand mappings (or at least those needed initially).
53 | * The Model is prepared by registering all the Proxy instances needed. (Don't make service calls at this point).
54 | * The View is prepared by registering all the Mediator instances needed.
55 | * When the Mediators are registered, they usually retrieve the Proxy instances required to supply their view components with data and potentially make Proxy method calls that result in service calls. Those service calls, when they return will usually result in Notifications that trigger ICommands and/or one or more Mediators are interested in.
56 |
57 | ## MultiCore Functionality
58 |
59 | * Applications are composed of one or more 'Core's. A Core is a group of Multitons that share the same multiton key, an arbitrary, but unique name you provide (such as the name of your application).
60 | * Although most programs only need one 'Core', you can request more Facade instances using different multiton keys, in order to get multiple, isolated sets of Model, View, and Controller actors.
61 | * This allows you to do modular programming. Each 'Core' is like a separate program. It has its own group of Multitons, its own startup process, and all the workhorse classes communicate with each other through the set of Multitons they were registered with.
62 |
63 | ## Learn More About PureMVC
64 | * [Official Site](http://puremvc.org)
--------------------------------------------------------------------------------
/example/Framework_Verify.css:
--------------------------------------------------------------------------------
1 |
2 | body {
3 | background-color: #F8F8F8;
4 | font-family: 'Open Sans', sans-serif;
5 | font-size: 14px;
6 | font-weight: normal;
7 | line-height: 2.0em;
8 | margin: 50px;
9 | }
10 |
11 | p {
12 | color: #333;
13 | }
14 |
15 | #container {
16 | width: 100%;
17 | height: 400px;
18 | position: relative;
19 | border: 1px solid #ccc;
20 | background-color: #fff;
21 | }
22 |
23 | #text {
24 | font-size: 16pt;
25 | text-align: left;
26 | margin-top: 10px;
27 | margin-left:25px;
28 | }
29 |
--------------------------------------------------------------------------------
/example/Framework_Verify.dart:
--------------------------------------------------------------------------------
1 | import 'dart:html';
2 | import 'package:puremvc/puremvc.dart' as mvc;
3 |
4 | class Framework_Verify {
5 |
6 | Framework_Verify() {
7 | }
8 |
9 | void verify()
10 | {
11 | String multitonKey = "Test Core";
12 | String dataPoint1 = "Hello";
13 | String dataPoint2 = "World";
14 | String proxyName = "DataProxy";
15 | List retrievedObject;
16 | String badJuju = "";
17 |
18 | try {
19 | write ("
");
50 | // Prove errors will be reported
51 | // throw "Fungers! I've got jelly in my ears!";
52 |
53 | } on Error catch ( e ) {
54 | // Catch any error
55 | badJuju = e.toString();
56 |
57 | } finally {
58 | // Report final status
59 | if ( badJuju.length == 0 && retrievedObject != null
60 | && retrievedObject[0] == dataPoint1
61 | && retrievedObject[1] == dataPoint2 ){
62 | write( "Science! PureMVC is purring like a kitten. Take her out for a spin!");
63 | } else {
64 | write( "Claptrap! Someone's thrown a spanner in the works.");
65 | if( badJuju.length>0 ) write( "Bad juju reported: ${badJuju}");
66 | }
67 | }
68 |
69 | }
70 |
71 | void write(String message) {
72 | // the HTML library defines a global "document" variable
73 | document.querySelector('#text').innerHtml = "${document.querySelector('#text').innerHtml}${message}";
74 | }
75 | }
76 |
77 | void main() {
78 | new Framework_Verify().verify();
79 | }
80 |
--------------------------------------------------------------------------------
/example/Framework_Verify.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PureMVC - Framework Verification Page
6 |
7 |
8 |
9 |
PureMVC MultiCore Framework for Dart
10 |
Framework Verification Page
11 | This page just peforms few quick checks to see that the framework is working in your environment.
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/puremvc.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * The PureMVC MultiCore Framework for Dart.
3 | *
4 | * - PureMVC is a lightweight framework for creating applications based upon the classic [Model-View-Controller](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) design meta-pattern.
5 | * - It supports modular programming through the use of [Multiton](http://en.wikipedia.org/wiki/Multiton_pattern) Core actors.
6 | * - [PureMVC Dart on Github](https://github.com/PureMVC/puremvc-dart-multicore-framework/wiki)
7 | * - [PureMVC.org](http://puremvc.org)
8 | *
9 | * General Overview:
10 | *
11 | * - To separate coding concerns, an application (or a module in an application) is divided into three 'tiers': Model, View, and Controller.
12 | * - PureMVC implements these tiers as Multiton classes which register and manage communications between the workhorse actors that operate within those tiers.
13 | * - PureMVC also provides a handy frontend to the whole system called a [Facade](http://en.wikipedia.org/wiki/Facade_pattern).
14 | * - Since methods for message passing vary from platform to platform, PureMVC implements its own internal Observer Notification system for its actors to communicate with each other. These are not an alternative for Events. Your application's boundary classes will still interact with the DOM and services and PureMVC via Events.
15 | *
16 | * The Model Tier is handled by the [Model] Multiton.
17 | *
18 | * - In the Model tier, you usually create some [Value Object](http://en.wikipedia.org/wiki/Value_object) classes. These aren't tied to the framework and shouldn't know anything about the framework classes, they just hold data for the rest of the program to use.
19 | * - The [Model] registers and holds instances of the [Proxy] class (or your subclasses)
20 | * - [Proxy] instances are registered and retrieved from the [Model] by name.
21 | * - [Proxy] classes provide access to data, local storage, and remote services. Usually a [Proxy] will manage a single Value Object instance or collection. For example, rather than return raw XML or JSON for the rest of the app to parse, the [Proxy] will convert raw data coming from sevices into typed Value Objects, easily consumed by the rest of the program.
22 | * - [Proxy] classes do not respond to [Notifications]. They can be directly updated by [Mediator]s and [ICommand]s.
23 | * - [Proxy] classes should not send Notification names defined elsewhere in the application. They should define their own notification names, so that the classes of the Model tier remain portable and may be unit tested or reused in other applications.
24 | *
25 | * The View Tier is handled by the [View] Multiton.
26 | *
27 | * - Within the View Tier, you will usually create one or more view components, which you will write to interact directly with the Browser/DOM, listening for button presses, etc. These do not use any PureMVC framework classes and should only know about your Value Object classes in order to display, create, and modify data used by the rest of the app. They will hide the implementation of the DOM from the rest of the app, translating the button clicks and keystrokes into higher-level events that represent user intentions for initiating use-cases.
28 | * - The [View] Multiton registers and holds instances of [Mediator] subclasses.
29 | * - [Mediator]s don't do heavy lifting. They are essentially switchboard operators that receive data from the rest of the app via [Notification], and pass it to their view components, or receive events from their view components and in turn pass the user intention on to the rest of the app in the form of a [Notification].
30 | * - A [Mediator] will tend a particular view component, setting event listeners on it, which it handles usually by sending off [Notification]s to be dealt with by other [Mediator]s and/or [ICommand]s.
31 | * - A [Mediator] also may assert an interest in certain [Notification] names, which it will be notified about if sent by other actors or itself.
32 | * - A [Mediator] may also retrieve a [Proxy] and call a method on it, bypassing the Controller tier.
33 | *
34 | * The Controller Tier is handled by the [Controller] Multiton.
35 | *
36 | * - Within the Controller tier, you will usually create any Notification name constants that are shared by the View and Controller tiers. Remember that Notification names sent from [Proxy]s should be defined on the [Proxy]s themselves for portability.
37 | * - The [Controller] Multiton registers [Notification] name to [ICommand] mappings.
38 | * - When a [Notification] with a registered name is sent by a [Proxy], [Mediator], or [ICommand], the mapped [ICommand] is instantiated and its [execute()] method is called, passing in a reference to the [Notification] that triggered the [ICommand].
39 | * - The framework provides two types of [ICommand] implementors: [MacroCommand] and [SimpleCommand], which you subclass to add SubCommands and business logic, respectively.
40 | * - The [MacroCommand] executes a given set of [ICommand]s in order, passing the [Notification] to each 'SubCommand' in turn. Note that a SubCommand may modify the [Notification] body and type and the next SubCommand will receive the modified [Notification].
41 | * - The [SimpleCommand] executes some business logic which you define. It only stays in memory until its code has been executed unless some other actor keeps a reference to it, which usually isn't desirable, but there is a formal request pattern that can be implemented that makes sense ([See the O'Reilly book for info](http://oreil.ly/puremvc)).
42 | *
43 | * The [Facade] Multiton provides access to the [Model], [View], and [Controller] Multitons.
44 | *
45 | * - This keeps the developer from needing to interact with all the Multitons separately.
46 | * - The [Facade] Multiton implements all the methods of the the [Model], [View], and [Controller] Multitons and manages their creation.
47 | * - Calling [Facade.getInstance('someMultitonKey')] for the first time, creates each of the [Model], [View], and [Controller] Multitons for that key automatically. After that, the same instance will always be returned for a given key.
48 | * - All [Proxy], [Mediator], and [ICommand] instances already have a reference to their [Facade] instance when their [onRegister()] or [execute()] methods are called. Thus you never have to retrieve the [Facade] except when the Core is created.
49 | *
50 | * Bootstrapping your Application:
51 | *
52 | * - Usually, your main application class will retrieve the Facade instance, register a [StartupCommand], and trigger it by sending a [STARTUP] notification.
53 | * - The [StartupCommand] may be a [SimpleCommand] or a [MacroCommand] that breaks the startup process into several [SimpleCommands].
54 | * - Regardless of implementation, the business of the [StartupCommand] is to prepare the [Controller], [Model], and [View] - in that order.
55 | * - The [Controller] is prepared by registering all the [Notification]/[ICommand] mappings (or at least those needed initially).
56 | * - The [Model] is prepared by registering all the [Proxy] instances needed. (Don't make service calls at this point).
57 | * - The [View] is prepared by registering all the [Mediator] instances needed.
58 | * - When the [Mediator]s are registered, they usually retrieve the [Proxy] instances required to supply their view components with data and potentially make [Proxy] method calls that result in service calls. Those service calls, when they return will usually result in [Notification]s that trigger [ICommand]s and/or one or more [Mediator]s are interested in.
59 | *
60 | * MultiCore Functionality:
61 | *
62 | * - Applications are composed of one or more 'Core's. A Core is a group of Multitons that share the same multiton key, an arbitrary, but unique name you provide (such as the name of your application).
63 | * - Although most programs only need one 'Core', you can request more Facade instances using different multiton keys, in order to get multiple, isolated sets of [Model], [View], and [Controller] actors.
64 | * - This allows you to do modular programming. Each 'Core' is like a separate program. It has its own group of Multitons, its own startup process, and all the workhorse classes communicate with each other through the set of Multitons they were registered with.
65 | *
66 | */
67 | library puremvc;
68 | part 'src/interfaces/ICommand.dart';
69 | part 'src/interfaces/INotifier.dart';
70 | part 'src/interfaces/INotification.dart';
71 | part 'src/interfaces/IObserver.dart';
72 | part 'src/interfaces/IMediator.dart';
73 | part 'src/interfaces/IProxy.dart';
74 | part 'src/interfaces/IModel.dart';
75 | part 'src/interfaces/IView.dart';
76 | part 'src/interfaces/IController.dart';
77 | part 'src/interfaces/IFacade.dart';
78 | part 'src/patterns/observer/Observer.dart';
79 | part 'src/patterns/observer/Notification.dart';
80 | part 'src/patterns/observer/Notifier.dart';
81 | part 'src/patterns/proxy/Proxy.dart';
82 | part 'src/patterns/mediator/Mediator.dart';
83 | part 'src/patterns/command/SimpleCommand.dart';
84 | part 'src/patterns/command/MacroCommand.dart';
85 | part 'src/patterns/facade/Facade.dart';
86 | part 'src/core/Model.dart';
87 | part 'src/core/View.dart';
88 | part 'src/core/Controller.dart';
89 |
--------------------------------------------------------------------------------
/lib/src/core/Controller.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A PureMVC MultiCore [IController] implementation.
5 | *
6 | * In PureMVC, an [IController] implementor
7 | * follows the 'Command and Controller' strategy, and
8 | * assumes these responsibilities:
9 | *
10 | * - Remembering which [ICommand]s are intended to handle which [INotification]s.
11 | * - Registering itself as an [IObserver] with the [View] for each [INotification] that it has an [ICommand] mapping for.
12 | * - Creating a new instance of the proper [ICommand] to handle a given [INotification] when notified by the [IView].
13 | * - Calling the [ICommand]'s [execute] method, passing in the [INotification].
14 | *
15 | * See [INotification], [ICommand]
16 | */
17 | class Controller implements IController
18 | {
19 |
20 | /**
21 | * Constructor.
22 | *
23 | * This [IController] implementation is a Multiton, so you should not call the constructor directly,
24 | * but instead call the static [getInstance] method.
25 | *
26 | * - Throws [MultitonErrorControllerExists] if instance for this Multiton key has already been constructed
27 | */
28 | Controller( String key )
29 | {
30 | if ( instanceMap[ key ] != null ) throw new MultitonErrorControllerExists();
31 | multitonKey = key;
32 | instanceMap[ multitonKey ] = this;
33 | commandMap = new Map();
34 | initializeController();
35 | }
36 |
37 | /**
38 | * Initialize the [IController] Multiton instance.
39 | *
40 | * Called automatically by the constructor.
41 | *
42 | * Note that if you are using a custom [IView] implementor in your application,
43 | * you should also subclass [Controller] and override the [initializeController] method,
44 | * setting [view] equal to the return value of a call to [getInstance] on your [IView] implementor.
45 | */
46 | void initializeController( )
47 | {
48 | view = View.getInstance( multitonKey );
49 | }
50 |
51 | /**
52 | * [IController] Multiton Factory method.
53 | *
54 | * - Returns the [IController] Multiton instance for the specified key
55 | */
56 | static IController getInstance( String key )
57 | {
58 | if ( key == null || key == "" ) return null;
59 | if ( instanceMap == null ) instanceMap = new Map();
60 | if ( instanceMap[ key ] == null ) instanceMap[ key ] = new Controller( key );
61 | return instanceMap[ key ];
62 | }
63 |
64 | /**
65 | * Execute the [ICommand] previously registered as the
66 | * handler for [INotification]s with the given notification's name.
67 | *
68 | * - Param [note] - the [INotification] to execute the associated [ICommand] for
69 | */
70 | void executeCommand( INotification note )
71 | {
72 | Function commandFactory = commandMap[ note.getName() ];
73 | if ( commandFactory == null ) return;
74 |
75 | ICommand commandInstance = commandFactory();
76 | commandInstance.initializeNotifier( multitonKey );
77 | commandInstance.execute( note );
78 | }
79 |
80 | /**
81 | * Register an [INotification] to [ICommand] mapping with the [Controller].
82 | *
83 | * - Param [noteName] - the name of the [INotification] to associate the [ICommand] with.
84 | * - Param [commandFactory] - a function that creates a new instance of the [ICommand].
85 | */
86 | void registerCommand( String noteName, Function commandFactory )
87 | {
88 | if ( commandMap[ noteName ] == null ) {
89 | view.registerObserver( noteName, new Observer( executeCommand, this ) );
90 | }
91 | commandMap[ noteName ] = commandFactory;
92 | }
93 |
94 | /**
95 | * Check if an [ICommand] is registered for a given [INotification] name with the [IController].
96 | *
97 | * - Param [noteName] - the name of the [INotification].
98 | * - Returns [bool] - whether an [ICommand] is currently registered for the given [noteName].
99 | */
100 | bool hasCommand( String noteName )
101 | {
102 | return commandMap[ noteName ] != null;
103 | }
104 |
105 | /**
106 | * Remove a previously registered [INotification] to [ICommand] mapping from the [IController].
107 | *
108 | * - Param [noteName] - the name of the [INotification] to remove the [ICommand] mapping for.
109 | */
110 | void removeCommand( String noteName )
111 | {
112 | // if the Command is registered...
113 | if ( hasCommand( noteName ) )
114 | {
115 | // remove the observer
116 | view.removeObserver( noteName, this );
117 |
118 | // remove the command
119 | commandMap[ noteName ] = null;
120 | }
121 | }
122 |
123 | /**
124 | * Remove an [IController] instance.
125 | *
126 | * - Param [key] multitonKey of the [IController] instance to remove
127 | */
128 | static void removeController( String key )
129 | {
130 | instanceMap[ key ] = null;
131 | }
132 |
133 | // Local reference to this core's IView
134 | IView view;
135 |
136 | // Mapping of Notification names to Command Class references
137 | Map commandMap;
138 |
139 | // The Multiton Key for this Core
140 | String multitonKey;
141 |
142 | // Multiton instance map
143 | static Map instanceMap;
144 |
145 | }
146 |
147 | class MultitonErrorControllerExists {
148 | const MultitonErrorControllerExists();
149 |
150 | String toString() {
151 | return "IController Multiton instance already constructed for this key.";
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/lib/src/core/Model.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A PureMVC MultiCore [IModel] implementation.
5 | *
6 | * In PureMVC, [IModel] implementors provide
7 | * access to [IProxy] objects by named lookup.
8 | *
9 | * An [IModel] assumes these responsibilities:
10 | *
11 | * - Maintain a cache of [IProxy] instances.
12 | * - Provide methods for registering, retrieving, and removing [IProxy] instances.
13 | *
14 | * Your application must register [IProxy] instances
15 | * with the [IModel]. Typically, you use an
16 | * [ICommand] to create and register [IProxy]
17 | * instances once the [IFacade] has initialized the core
18 | * actors.
19 | *
20 | * See [IProxy], [IFacade]
21 | */
22 | class Model implements IModel
23 | {
24 | /**
25 | * Constructor.
26 | *
27 | * This [IModel] implementation is a Multiton, so you should not call the constructor directly,
28 | * but instead call the static [getInstance] method.
29 | *
30 | * - Throws [MultitonErrorModelExists] if instance for this Multiton key instance has already been constructed.
31 | */
32 | Model( String key )
33 | {
34 | if ( instanceMap[ key ] != null ) throw new MultitonErrorModelExists();
35 | multitonKey = key;
36 | instanceMap[ multitonKey ] = this;
37 | proxyMap = new Map();
38 | initializeModel();
39 | }
40 |
41 | /**
42 | * Initialize the [IModel] instance.
43 | *
44 | * Called automatically by the constructor, this is your opportunity to initialize the Singleton
45 | * instance in your subclass without overriding the constructor.
46 | */
47 | void initializeModel( ){ }
48 |
49 | /**
50 | * [IModel] Multiton Factory method.
51 | *
52 | * - Returns the [IModel] Multiton instance for the specified key.
53 | */
54 | static IModel getInstance( String key )
55 | {
56 | if ( key == null || key == "" ) return null;
57 | if ( instanceMap == null ) instanceMap = new Map();
58 | if ( instanceMap[ key ] == null ) instanceMap[ key ] = new Model( key );
59 | return instanceMap[ key ];
60 | }
61 |
62 | /**
63 | * Register an [IProxy] instance with the [IModel].
64 | *
65 | * - Param [proxy] - an object reference to be held by the [IModel].
66 | */
67 | void registerProxy( IProxy proxy )
68 | {
69 | proxy.initializeNotifier( multitonKey );
70 | proxyMap[ proxy.getName() ] = proxy;
71 | proxy.onRegister();
72 | }
73 |
74 | /**
75 | * Retrieve an [IProxy] instance from the [IModel].
76 | *
77 | * - Param [proxyName] - the name of the [IProxy] instance to retrieve.
78 | * - Returns the [IProxy] instance previously registered with the given [proxyName].
79 | */
80 | IProxy retrieveProxy( String proxyName )
81 | {
82 | return proxyMap[ proxyName ];
83 | }
84 |
85 | /**
86 | * Remove an [IProxy] instance from the [IModel].
87 | *
88 | * - Param [proxyName] - name of the [IProxy] instance to be removed.
89 | * - Returns [IProxy] - the [IProxy] that was removed from the [IModel].
90 | */
91 | IProxy removeProxy( String proxyName )
92 | {
93 | IProxy proxy = proxyMap[ proxyName ];
94 | if ( proxy != null )
95 | {
96 | proxyMap[ proxyName ] = null;
97 | proxy.onRemove();
98 | }
99 | return proxy;
100 | }
101 |
102 | /**
103 | * Check if an [IProxy] is registered with the [IModel].
104 | *
105 | * - Param [proxyName] - the name of the [IProxy] instance you're looking for.
106 | * - Returns [bool] - whether an [IProxy] is currently registered with the given [proxyName].
107 | */
108 | bool hasProxy( String proxyName )
109 | {
110 | return proxyMap[ proxyName ] != null;
111 | }
112 |
113 | /**
114 | * Remove an [IModel] instance.
115 | *
116 | * - Param [key] - the multitonKey of [IModel] instance to remove
117 | */
118 | static void removeModel( String key )
119 | {
120 | instanceMap[ key ] = null;
121 | }
122 |
123 | // Mapping of proxyNames to IProxy instances
124 | Map proxyMap;
125 |
126 | // Multiton instance map
127 | static Map instanceMap;
128 |
129 | // The Multiton Key for this Core
130 | String multitonKey;
131 | }
132 |
133 | class MultitonErrorModelExists {
134 | const MultitonErrorModelExists();
135 |
136 | String toString() {
137 | return "IModel Multiton instance already constructed for this key.";
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/lib/src/core/View.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A PureMVC MultiCore [IView] implementation.
5 | *
6 | * In PureMVC, [IView] implementors assume these responsibilities:
7 | *
8 | * - Maintain a cache of [IMediator] instances.
9 | * - Provide methods for registering, retrieving, and removing [IMediator]s.
10 | * - Managing the [IObserver] lists for each [INotification].
11 | * - Providing a method for attaching [IObserver]s to an [INotification]'s [IObserver] list.
12 | * - Providing a method for broadcasting an [INotification] to each of the [IObserver]s in a list.
13 | * - Notifying the [IObservers] of a given [INotification] when it broadcast.
14 | *
15 | * See [IMediator], [IObserver], [INotification]
16 | */
17 | class View implements IView
18 | {
19 |
20 | /**
21 | * Constructor.
22 | *
23 | * This [IView] implementation is a Multiton, so you should not call the constructor directly,
24 | * but instead call the static [getInstance] method.
25 | *
26 | * - Throws [MultitonErrorViewExists] if instance for this Multiton key has already been constructed
27 | */
28 | View( String key )
29 | {
30 | if (instanceMap[ key ] != null) throw new MultitonErrorViewExists();
31 | multitonKey = key;
32 | instanceMap[ multitonKey ] = this;
33 | mediatorMap = new Map();
34 | observerMap = new Map>();
35 | initializeView();
36 | }
37 |
38 | /**
39 | * Initialize the Multiton View instance.
40 | *
41 | * Called automatically by the constructor, this is your opportunity to initialize the Multiton
42 | * instance in your subclass without overriding the constructor.
43 | */
44 | void initializeView( ){}
45 |
46 | /**
47 | * [IView] Multiton Factory method.
48 | *
49 | * - Returns the [IView] Multiton instance for the specified key.
50 | */
51 | static IView getInstance( String key )
52 | {
53 | if ( key == null || key == "" ) return null;
54 | if ( instanceMap == null ) instanceMap = new Map();
55 | if ( instanceMap[ key ] == null ) instanceMap[ key ] = new View( key );
56 | return instanceMap[ key ];
57 | }
58 |
59 | /**
60 | * Register an [IObserver] to be notified of [INotification]s with a given name.
61 | *
62 | * - Param [noteName] - the name of the [INotification] to notify this [IObserver] of.
63 | * - Param [observer] - the [IObserver] to register.
64 | */
65 | void registerObserver( String noteName, IObserver observer )
66 | {
67 | if( observerMap[ noteName ] == null ) {
68 | observerMap[ noteName ] = new List();
69 | }
70 | observerMap[ noteName ].add( observer );
71 | }
72 |
73 | /**
74 | * Notify the [IObserver]s for a particular [INotification].
75 | *
76 | * All previously attached [IObserver]s for this [INotification]'s
77 | * list are notified and are passed a reference to the [INotification] in
78 | * the order in which they were registered.
79 | *
80 | * - Param [note] - the [INotification] to notify [IObservers] of.
81 | */
82 | void notifyObservers( INotification note )
83 | {
84 | // Get a reference to the observers list for this notification name
85 | List observers_ref = observerMap[ note.getName() ];
86 | if( observers_ref != null )
87 | {
88 | // Copy observers from reference array to working array,
89 | // since the reference array may change during the notification loop
90 | List observers = new List();
91 | IObserver observer;
92 | for (var i = 0; i < observers_ref.length; i++) {
93 | observer = observers_ref[ i ];
94 | observers.add( observer );
95 | }
96 |
97 | // Notify Observers from the working array
98 | for (var i = 0; i < observers.length; i++) {
99 | observer = observers[ i ];
100 | observer.notifyObserver( note );
101 | }
102 | }
103 | }
104 |
105 | /**
106 | * Remove an [IObserver] from the list for a given [INotification] name.
107 | *
108 | * - Param [noteName] - which [IObserver] list to remove from.
109 | * - Param [notifyContext] - remove [IObserver]s with this object as the [notifyContext].
110 | */
111 | void removeObserver( String noteName, Object notifyContext )
112 | {
113 | // the observer list for the notification under inspection
114 | List observers = observerMap[ noteName ];
115 |
116 | // find the observer for the notifyContext
117 | for ( var i=0; i interests = mediator.listNotificationInterests();
162 |
163 | // Register Mediator as an observer for each notification of interests
164 | if ( interests.length > 0 )
165 | {
166 | // Create Observer referencing this mediator's handlNotification method
167 | IObserver observer = new Observer( mediator.handleNotification, mediator );
168 |
169 | // Register Mediator as Observer for its list of Notification interests
170 | for ( var i=0; i interests = mediator.listNotificationInterests();
205 | for ( var i=0; i mediatorMap;
245 |
246 | // Mapping of INotification names to IObserver lists
247 | Map> observerMap;
248 |
249 | // Multiton IView instance map
250 | static Map instanceMap;
251 |
252 | // The Multiton key for this Core
253 | String multitonKey;
254 | }
255 |
256 | class MultitonErrorViewExists {
257 | const MultitonErrorViewExists();
258 |
259 | String toString() {
260 | return "IViewMultiton instance already constructed for this key.";
261 | }
262 | }
263 |
264 |
--------------------------------------------------------------------------------
/lib/src/interfaces/ICommand.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC MultiCore Command.
5 | *
6 | * See [IController], [INotification]
7 | */
8 | abstract class ICommand extends INotifier
9 | {
10 | /**
11 | * Execute the [ICommand]'s logic to handle a given [INotification].
12 | *
13 | * - Param [note] - an [INotification] to handle.
14 | */
15 | void execute( INotification note );
16 | }
17 |
--------------------------------------------------------------------------------
/lib/src/interfaces/IController.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC MultiCore Controller.
5 | *
6 | * In PureMVC, an [IController] implementor
7 | * follows the 'Command and Controller' strategy, and
8 | * assumes these responsibilities:
9 | *
10 | * - Remembering which [ICommand]s are intended to handle which [INotification]s.
11 | * - Registering itself as an [IObserver] with the [View] for each [INotification] that it has an [ICommand] mapping for.
12 | * - Creating a new instance of the proper [ICommand] to handle a given [INotification] when notified by the [IView].
13 | * - Calling the [ICommand]'s [execute] method, passing in the [INotification].
14 | *
15 | * See [INotification], [ICommand]
16 | */
17 | abstract class IController
18 | {
19 | /**
20 | * Register an [INotification] to [ICommand] mapping with the [IController].
21 | *
22 | * - Param [noteName] - the name of the [INotification] to associate the [ICommand] with.
23 | * - Param [commandFactory] - a function that creates a new instance of the [ICommand].
24 | */
25 | void registerCommand( String notificationName, Function commandFactory );
26 |
27 | /**
28 | * Execute the [ICommand] previously registered as the
29 | * handler for [INotification]s with the given notification's name.
30 | *
31 | * - Param [note] - the [INotification] to execute the associated [ICommand] for
32 | */
33 | void executeCommand( INotification note );
34 |
35 | /**
36 | * Remove a previously registered [INotification] to [ICommand] mapping from the [IController].
37 | *
38 | * - Param [noteName] - the name of the [INotification] to remove the [ICommand] mapping for.
39 | */
40 | void removeCommand( String noteName );
41 |
42 | /**
43 | * Check if an [ICommand] is registered for a given [INotification] name with the [IController].
44 | *
45 | * - Param [noteName] - the name of the [INotification].
46 | * - Returns [bool] - whether an [ICommand] is currently registered for the given [noteName].
47 | */
48 | bool hasCommand( String noteName );
49 |
50 | /**
51 | * This IController's Multiton Key
52 | */
53 | void set multitonKey( String key );
54 | String get multitonKey;
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/lib/src/interfaces/IFacade.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC MultiCore Facade.
5 | *
6 | * The Facade Pattern suggests providing a single
7 | * class to act as a central point of communication
8 | * for a subsystem.
9 | *
10 | * In PureMVC, the [IFacade] acts as an interface between
11 | * the core MVC actors [IModel], [IView], [IController], and
12 | * the rest of your application, which (aside from view components
13 | * and data objects) is mostly expressed with [ICommand]s,
14 | * [IMediator]s, and [IProxy]s.
15 | *
16 | * This means you don't need to communicate with the [IModel],
17 | * [IView], [IController] instances directly, you can just go through
18 | * the [IFacade]. And conveniently, [ICommand]s, [IMediator]s, and
19 | * [IProxy]s all have a built-in reference to their [IFacade] after
20 | * initialization, so they're all plugged in and ready to communicate
21 | * with each other.
22 | *
23 | * See [IModel], [IView], [IController], [IProxy], [IMediator], [ICommand], [INotification]
24 | */
25 | abstract class IFacade extends INotifier
26 | {
27 |
28 | /**
29 | * Register an [IProxy] instance with the [IModel].
30 | *
31 | * - Param [proxy] - an object reference to be held by the [IModel].
32 | */
33 | void registerProxy( IProxy proxy );
34 |
35 | /**
36 | * Retrieve an [IProxy] instance from the [IModel].
37 | *
38 | * - Param [proxyName] - the name of the [IProxy] instance to retrieve.
39 | * - Returns the [IProxy] instance previously registered with the given [proxyName].
40 | */
41 | IProxy retrieveProxy( String proxyName );
42 |
43 | /**
44 | * Remove an [IProxy] instance from the [IModel].
45 | *
46 | * - Param [proxyName] - name of the [IProxy] instance to be removed.
47 | * - Returns [IProxy] - the [IProxy] that was removed from the [IModel].
48 | */
49 | IProxy removeProxy( String proxyName );
50 |
51 | /**
52 | * Check if an [IProxy] is registered with the [IModel].
53 | *
54 | * - Param [proxyName] - the name of the [IProxy] instance you're looking for.
55 | * - Returns [bool] - whether an [IProxy] is currently registered with the given [proxyName].
56 | */
57 | bool hasProxy( String proxyName );
58 |
59 | /**
60 | * Register an [INotification] to [ICommand] mapping with the [IController].
61 | *
62 | * - Param [noteName] - the name of the [INotification] to associate the [ICommand] with.
63 | * - Param [commandFactory] - a function that creates a new instance of the [ICommand].
64 | */
65 | void registerCommand( String noteName, Function commandFactory );
66 |
67 | /**
68 | * Remove a previously registered [INotification] to [ICommand] mapping from the [IController].
69 | *
70 | * - Param [noteName] - the name of the [INotification] to remove the [ICommand] mapping for.
71 | */
72 | void removeCommand( String noteName );
73 |
74 | /**
75 | * Check if an [ICommand] is registered for a given [INotification] name with the [IController].
76 | *
77 | * - Param [noteName] - the name of the [INotification].
78 | * - Returns [bool] - whether an [ICommand] is currently registered for the given [noteName].
79 | */
80 | bool hasCommand( String noteName );
81 |
82 | /**
83 | * Register an [IMediator] instance with the [IView].
84 | *
85 | * Registers the [IMediator] so that it can be retrieved by name,
86 | * and interrogates the [IMediator] for its [INotification] interests.
87 | *
88 | * If the [IMediator] returns a list of [INotification]
89 | * names to be notified about, an [Observer] is created encapsulating
90 | * the [IMediator] instance's [handleNotification] method
91 | * and registering it as an [IObserver] for all [INotification]s the
92 | * [IMediator] is interested in.
93 | *
94 | * - Param [mediator] - a reference to the [IMediator] instance.
95 | */
96 | void registerMediator( IMediator mediator );
97 |
98 | /**
99 | * Retrieve an [IMediator] from the [IView].
100 | *
101 | * - Param [mediatorName] - the name of the [IMediator] instance to retrieve.
102 | * - Returns [IMediator] - the [IMediator] instance previously registered in this core with the given [mediatorName].
103 | */
104 | IMediator retrieveMediator( String mediatorName );
105 |
106 | /**
107 | * Remove an [IMediator] from the [IView].
108 | *
109 | * - Param [mediatorName] - name of the [IMediator] instance to be removed.
110 | * - Returns [IMediator] - the [IMediator] that was removed from this core's [IView].
111 | */
112 | IMediator removeMediator( String mediatorName );
113 |
114 | /**
115 | * Check if an [IMediator] is registered with the [IView].
116 | *
117 | * - Param [mediatorName] - the name of the [IMediator] you're looking for.
118 | * - Returns [bool] - whether an [IMediator] is registered in this core with the given [mediatorName].
119 | */
120 | bool hasMediator( String mediatorName );
121 |
122 | /**
123 | * Register an [IObserver] to be notified of [INotification]s with a given name.
124 | *
125 | * - Param [noteName] - the name of the [INotification] to notify this [IObserver] of.
126 | * - Param [observer] - the [IObserver] to register.
127 | */
128 | void registerObserver( String noteName, IObserver observer );
129 |
130 | /**
131 | * Remove an [IObserver] from the list for a given [INotification] name.
132 | *
133 | * - Param [noteName] - which [IObserver] list to remove from.
134 | * - Param [notifyContext] - remove [IObserver]s with this object as the [notifyContext].
135 | */
136 | void removeObserver( String noteName, Object notifyContext );
137 |
138 | /**
139 | * Notify [IObserver]s.
140 | *
141 | * This method allows you to send custom [INotification] classes using the [IFacade].
142 | *
143 | * Usually you should just call [sendNotification] and pass the parameters,
144 | * never having to construct an [INotification] yourself.
145 | *
146 | * - Param [note] the [INotification] to have the [View] notify [Observers] of.
147 | */
148 | void notifyObservers( INotification notification );
149 |
150 | /**
151 | * This [IFacade]'s Multiton key
152 | */
153 | void set multitonKey( String key );
154 | String get multitonKey;
155 |
156 | /**
157 | * This [IFacade]'s [IModel]
158 | */
159 | void set model( IModel modelInstance );
160 | IModel get model;
161 |
162 | /**
163 | * This [IFacade]'s [IView]
164 | */
165 | void set view( IView viewInstance );
166 | IView get view;
167 |
168 | /**
169 | * This [IFacade]'s [IController]
170 | */
171 | void set controller( IController controllerInstance );
172 | IController get controller;
173 |
174 | }
175 |
--------------------------------------------------------------------------------
/lib/src/interfaces/IMediator.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC MultiCore Mediator.
5 | *
6 | * In PureMVC, [IMediator] implementors assume these responsibilities:
7 | *
8 | * - Implement a common method which returns a list of all [INotification]s the [IMediator] has interest in.
9 | * - Implement a notification (callback) method for handling [INotification]s.
10 | * - Implement methods that are called when the [IMediator] is registered or removed from an [IView].
11 | *
12 | * Additionally, [IMediator]s typically:
13 | *
14 | * - Act as an intermediary between one or more view components and the rest of the application.
15 | * - Place [Event] listeners on view components, and implement handlers which often send [INotification]s or interact with [IProxy]s to post or retrieve data.
16 | * - Receive [INotification]s, (typically containing data) and updating view components in response.
17 | *
18 | * When an [IMediator] is registered with the [IView], the [IMediator]'s [listNotificationInterests] method is called
19 | * The [IMediator] will return a [List] of [INotification] names which it wishes to be notified about.
20 | *
21 | * The [IView] will then create an [IObserver] object encapsulating that [IMediator]'s and its [handleNotification] method
22 | * and register the [IObserver] for each [INotification] name returned by the [IMediator]'s [listNotificationInterests] method.
23 | *
24 | * See [INotification], [IView]
25 | */
26 | abstract class IMediator extends INotifier
27 | {
28 |
29 | /**
30 | * Get the [IMediator] instance's [name].
31 | *
32 | * - Returns [String] - the [IMediator] instance's [name].
33 | */
34 | String getName();
35 |
36 | /**
37 | * Get the [IMediator]'s [viewComponent].
38 | *
39 | * - Returns [Dynamic] - the View Component
40 | */
41 | dynamic getViewComponent();
42 |
43 | /**
44 | * Set the [IMediator]'s [viewComponent].
45 | *
46 | * - Param [Dynamic] - the [viewComponent].
47 | */
48 | void setViewComponent( dynamic viewComponent );
49 |
50 | /**
51 | * List [INotification] interests.
52 | *
53 | * - Returns [List] - a [List] of the [INotification] names this [IMediator] has an interest in.
54 | */
55 | List listNotificationInterests( );
56 |
57 | /**
58 | * Handle an [INotification].
59 | *
60 | * - Param [note] - the [INotification] to be handled.
61 | */
62 | void handleNotification( INotification note );
63 |
64 | /**
65 | * Called by the [IView] when the [IMediator] is registered.
66 | */
67 | void onRegister( );
68 |
69 | /**
70 | * Called by the [IView] when the [IMediator] is removed.
71 | */
72 | void onRemove( );
73 |
74 |
75 | /**
76 | * This [IMediator]'s [viewComponent].
77 | */
78 | void set viewComponent( dynamic viewComponent );
79 | dynamic get viewComponent;
80 |
81 | /**
82 | * This [IMediator]'s [name].
83 | */
84 | void set name( String mediatorName );
85 | String get name;
86 |
87 | }
--------------------------------------------------------------------------------
/lib/src/interfaces/IModel.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC MultiCore Model.
5 | *
6 | * In PureMVC, [IModel] implementors provide access to [IProxy] objects by named lookup.
7 | *
8 | * An [IModel] assumes these responsibilities:
9 | *
10 | * - Maintain a cache of [IProxy] instances.
11 | * - Provide methods for registering, retrieving, and removing [IProxy] instances.
12 | *
13 | * Your application must register [IProxy] instances
14 | * with the [IModel]. Typically, you use an
15 | * [ICommand] to create and register [IProxy]
16 | * instances once the [IFacade] has initialized the core
17 | * actors.
18 | *
19 | * See [IProxy], [IFacade]
20 | */
21 | abstract class IModel
22 | {
23 | /**
24 | * Register an [IProxy] instance with the [IModel].
25 | *
26 | * - Param [proxy] - an object reference to be held by the [IModel].
27 | */
28 | void registerProxy( IProxy proxy );
29 |
30 | /**
31 | * Retrieve an [IProxy] instance from the [IModel].
32 | *
33 | * - Param [proxyName] - the name of the [IProxy] instance to retrieve.
34 | * - Returns the [IProxy] instance previously registered with the given [proxyName].
35 | */
36 | IProxy retrieveProxy( String proxyName );
37 |
38 | /**
39 | * Remove an [IProxy] instance from the [IModel].
40 | *
41 | * - Param [proxyName] - name of the [IProxy] instance to be removed.
42 | * - Returns [IProxy] - the [IProxy] that was removed from the [IModel].
43 | */
44 | IProxy removeProxy( String proxyName );
45 |
46 | /**
47 | * Check if an [IProxy] is registered with the [IModel].
48 | *
49 | * - Param [proxyName] - the name of the [IProxy] instance you're looking for.
50 | * - Returns [bool] - whether an [IProxy] is currently registered with the given [proxyName].
51 | */
52 | bool hasProxy( String proxyName );
53 |
54 | /**
55 | * This [IModel]'s Multiton Key
56 | */
57 | void set multitonKey( String key );
58 | String get multitonKey;
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/lib/src/interfaces/INotification.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC MultiCore Notification.
5 | *
6 | * The Observer Pattern as implemented within PureMVC exists
7 | * to support publish/subscribe communication between actors.
8 | *
9 | * [INotification]s are not meant to be a replacement for [Event]s,
10 | * but rather an internal communication mechanism that ensures
11 | * PureMVC is portable regardless of what type of Event mechanism
12 | * is supported (or not) on a given platform.
13 | *
14 | * Generally, [IMediator] implementors place [Event] listeners on
15 | * their view components, and [IProxy] implementors place [Event]
16 | * listeners on service components. Those [Event]s are then handled in
17 | * the usual way, and may lead to the broadcast of [INotification]s
18 | * that trigger [ICommand]s or notify [IMediator]s.
19 | *
20 | * See [IView], [IObserver]
21 | */
22 | abstract class INotification
23 | {
24 |
25 | /**
26 | * Get the [name] of the [INotification].
27 | *
28 | * - Returns [String] - the name of the [INotification].
29 | */
30 | String getName();
31 |
32 | /**
33 | * Set the [body] of the [INotification].
34 | *
35 | * - Param [body] - the body of the [INotification].
36 | */
37 | void setBody( Object body );
38 |
39 | /**
40 | * Get the [body] of the [INotification].
41 | *
42 | * - Returns [Dynamic] - the body of the [INotification].
43 | */
44 | dynamic getBody();
45 |
46 | /**
47 | * Set the [type] of the [INotification].
48 | *
49 | * - Param [type] - the type of the [INotification].
50 | */
51 | void setType( String type );
52 |
53 | /**
54 | * Get the [type] of the [INotification].
55 | *
56 | * - Returns [String] - the type of the [INotification].
57 | */
58 | String getType();
59 |
60 | /**
61 | * This [INotifications]'s [body]
62 | */
63 | void set body( dynamic bodyObject );
64 | dynamic get body;
65 |
66 | /**
67 | * This [INotifications]'s [name]
68 | */
69 | void set name( String noteName );
70 | String get name;
71 |
72 | /**
73 | * This [INotifications]'s [type]
74 | */
75 | void set type( String noteType );
76 | String get type;
77 |
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/lib/src/interfaces/INotifier.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC [Notifier].
5 | *
6 | * [MacroCommand], [SimpleCommand], [Mediator] and [Proxy]
7 | * all have a need to send [Notification]s.
8 | *
9 | * The [INotifier] interface provides a common method called
10 | * [sendNotification] that relieves implementation code of
11 | * the necessity to actually construct [INotification]s.
12 | *
13 | * The [Notifier] class, which all of the above mentioned classes
14 | * extend, also provides an initialized reference to the [Facade]
15 | * Multiton, which is required for the convienience method
16 | * for sending [Notification]s, but also eases implementation as these
17 | * classes have frequent [IFacade] interactions and usually require
18 | * access to the facade anyway.
19 | *
20 | * See [IFacade], [INotification]
21 | */
22 | abstract class INotifier {
23 |
24 | /**
25 | * Send an [INotification].
26 | *
27 | * Convenience method to prevent having to construct new
28 | * [INotification] instances in our implementation code.
29 | *
30 | * - Param [noteName] the name of the note to send
31 | * - Param [body] - the body of the note (optional)
32 | * - Param [type] - the type of the note (optional)
33 | */
34 | void sendNotification( String noteName, [dynamic body, String type] );
35 |
36 | /**
37 | * Initialize this [INotifier] instance.
38 | *
39 | * This is how a [INotifier] gets its [multitonKey].
40 | * Calls to [sendNotification] or access to the
41 | * [facade] will fail until after this method
42 | * has been called.
43 | *
44 | * - Param [key] - the Multiton key for this [INotifier].
45 | */
46 | void initializeNotifier( String key );
47 |
48 | /**
49 | * This INotifier's Multiton Key
50 | */
51 | void set multitonKey( String key );
52 | String get multitonKey;
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/lib/src/interfaces/IObserver.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC MultiCore Observer.
5 | *
6 | * In PureMVC, [IObserver] implementors assume these responsibilities:
7 | *
8 | * - Encapsulate the notification (callback) method of the interested object.
9 | * - Encapsulate the notification context (this) of the interested object.
10 | * - Provide methods for setting the interested object's notification method and context.
11 | * - Provide a method for notifying the interested object.
12 | *
13 | * The Observer Pattern as implemented within PureMVC exists
14 | * to support publish/subscribe communication between actors.
15 | *
16 | * An [IObserver] is an object that encapsulates information
17 | * about an interested object with a notification (callback)
18 | * method that should be called when an [INotification] is
19 | * broadcast. The [IObserver] then acts as a conduit for
20 | * notifying the interested object.
21 | *
22 | * [IObserver]s can receive [Notification]s by having their
23 | * [notifyObserver] method invoked, passing in an object
24 | * implementing the [INotification] interface.
25 | *
26 | * See [IView], [INotification]
27 | */
28 | abstract class IObserver
29 | {
30 | /**
31 | * Set the notification method.
32 | *
33 | * The notification method should take one parameter of type [INotification].
34 | *
35 | * - Param [notifyMethod] - the notification (callback) method of the interested object.
36 | */
37 | void setNotifyMethod( Function callback );
38 |
39 | /**
40 | * Set the notification context.
41 | *
42 | * - Param [caller] - a reference to the object to be notified.
43 | */
44 | void setNotifyContext( Object caller );
45 |
46 | /**
47 | * Get the notification method.
48 | *
49 | * - Returns [Function] - the notification (callback) method of the interested object.
50 | */
51 | Function getNotifyMethod();
52 |
53 | /**
54 | * Get the notification context.
55 | *
56 | * - Returns [Object] - the caller.
57 | */
58 | Object getNotifyContext();
59 |
60 | /**
61 | * Compare a given object to the [notifyContext] (caller) object.
62 | *
63 | * - Param [Object] - the object to compare.
64 | * - Returns [bool] - whether the given object and the [notifyContext] (caller) are the same.
65 | */
66 | bool compareNotifyContext( Object object );
67 |
68 | /**
69 | * Notify the interested object.
70 | *
71 | * - Param [note] - the [INotification] to pass to the caller's [notifyMethod].
72 | */
73 | void notifyObserver( INotification note );
74 |
75 | /**
76 | * This [IObserver]'s [notifyMethod] (i.e., callback)
77 | */
78 | void set notifyMethod( Function callback );
79 | Function get notifyMethod;
80 |
81 | /**
82 | * This [IObserver]'s [notifyContext] (i.e., caller)
83 | */
84 | void set notifyContext( Object caller );
85 | Object get notifyContext;
86 |
87 | }
88 |
89 |
--------------------------------------------------------------------------------
/lib/src/interfaces/IProxy.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC MultiCore Proxy.
5 | *
6 | * In PureMVC, [IProxy] implementors assume these responsibilities:
7 | *
8 | * - Implement a common method which returns the name of the [IProxy].
9 | * - Provide methods for setting and getting a Data Object.
10 | *
11 | * Additionally, [IProxy]s typically:
12 | *
13 | * - Provide methods for manipulating the Data Object and referencing it by type.
14 | * - Generate [INotification]s when their Data Object changes.
15 | * - Expose their name as a [static final String] called [NAME].
16 | * - Encapsulate interaction with local or remote services used to fetch and persist data.
17 | *
18 | * See [IModel]
19 | */
20 | abstract class IProxy extends INotifier
21 | {
22 | /**
23 | * Get the [IProxy] [name].
24 | *
25 | * - Returns [String] - the [IProxy] instance [name].
26 | */
27 | String getName();
28 |
29 | /**
30 | * Set the [dataObject].
31 | *
32 | * - Param [Dynamic] - the [dataObject] this [IProxy] will tend.
33 | */
34 | void setData( dynamic dataObject );
35 |
36 | /**
37 | * Get the [dataObject].
38 | *
39 | * - Returns [Dynamic] - the [dataObject].
40 | */
41 | dynamic getData();
42 |
43 | /**
44 | * Called by the [IModel] when the [IProxy] is registered.
45 | */
46 | void onRegister( );
47 |
48 | /**
49 | * Called by the [IModel] when the [IProxy] is removed.
50 | */
51 | void onRemove( );
52 |
53 | /**
54 | * This [IProxy]'s [dataObject].
55 | */
56 | void set data( dynamic dataObject );
57 | dynamic get data;
58 |
59 | /**
60 | * This [IProxy]'s [name].
61 | */
62 | void set name( String proxyName );
63 | String get name;
64 |
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/lib/src/interfaces/IView.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * The interface definition for a PureMVC MultiCore View.
5 | *
6 | * In PureMVC, [IView] implementors assume these responsibilities:
7 | *
8 | * - Maintain a cache of [IMediator] instances.
9 | * - Provide methods for registering, retrieving, and removing [IMediator]s.
10 | * - Managing the [IObserver] lists for each [INotification].
11 | * - Providing a method for attaching [IObserver]s to an [INotification]'s [IObserver] list.
12 | * - Providing a method for broadcasting an [INotification] to each of the [IObserver]s in a list.
13 | * - Notifying the [IObservers] of a given [INotification] when it broadcast.
14 | *
15 | * See [IMediator], [IObserver], [INotification]
16 | */
17 | abstract class IView
18 | {
19 | /**
20 | * Register an [IObserver] to be notified of [INotification]s with a given name.
21 | *
22 | * - Param [noteName] - the name of the [INotification] to notify this [IObserver] of.
23 | * - Param [observer] - the [IObserver] to register.
24 | */
25 | void registerObserver( String noteName, IObserver observer);
26 |
27 | /**
28 | * Remove an [IObserver] from the list for a given [INotification] name.
29 | *
30 | * - Param [noteName] - which [IObserver] list to remove from.
31 | * - Param [notifyContext] - remove [IObserver]s with this object as the [notifyContext].
32 | */
33 | void removeObserver( String noteName, Object notifyContext );
34 |
35 | /**
36 | * Notify the [IObserver]s for a particular [INotification].
37 | *
38 | * All previously attached [IObserver]s for this [INotification]'s
39 | * list are notified and are passed a reference to the [INotification] in
40 | * the order in which they were registered.
41 | *
42 | * - Param [note] - the [INotification] to notify [IObservers] of.
43 | */
44 | void notifyObservers( INotification note );
45 |
46 | /**
47 | * Register an [IMediator] instance with the [IView].
48 | *
49 | * Registers the [IMediator] so that it can be retrieved by name,
50 | * and interrogates the [IMediator] for its [INotification] interests.
51 | *
52 | * If the [IMediator] returns a list of [INotification]
53 | * names to be notified about, an [Observer] is created encapsulating
54 | * the [IMediator] instance's [handleNotification] method
55 | * and registering it as an [IObserver] for all [INotification]s the
56 | * [IMediator] is interested in.
57 | *
58 | * - Param [mediator] - a reference to the [IMediator] instance.
59 | */
60 | void registerMediator( IMediator mediator );
61 |
62 | /**
63 | * Retrieve an [IMediator] from the [IView].
64 | *
65 | * - Param [mediatorName] - the name of the [IMediator] instance to retrieve.
66 | * - Returns [IMediator] - the [IMediator] instance previously registered in this core with the given [mediatorName].
67 | */
68 | IMediator retrieveMediator( String mediatorName );
69 |
70 | /**
71 | * Remove an [IMediator] from the [IView].
72 | *
73 | * - Param [mediatorName] - name of the [IMediator] instance to be removed.
74 | * - Returns [IMediator] - the [IMediator] that was removed from this core's [IView].
75 | */
76 | IMediator removeMediator( String mediatorName );
77 |
78 | /**
79 | * Check if an [IMediator] is registered with the [IView].
80 | *
81 | * - Param [mediatorName] - the name of the [IMediator] you're looking for.
82 | * - Returns [bool] - whether an [IMediator] is registered in this core with the given [mediatorName].
83 | */
84 | bool hasMediator( String mediatorName );
85 |
86 | /**
87 | * This [IView]'s Multiton key
88 | */
89 | void set multitonKey( String key );
90 | String get multitonKey;
91 |
92 | }
93 |
94 |
--------------------------------------------------------------------------------
/lib/src/patterns/command/MacroCommand.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A base [ICommand] implementation that synchronously executes other [ICommand]s.
5 | *
6 | * An [MacroCommand] maintains an list of [ICommand] factories called 'SubCommands'.
7 | *
8 | * When [execute] is called, the [MacroCommand] instantiates and calls [execute] on each of its 'SubCommands' turn.
9 | * Each 'SubCommand' will be passed a reference to the original [INotification].
10 | *
11 | * Unlike [SimpleCommand], your subclass should not override [execute], but instead,
12 | * should override the [initializeMacroCommand] method, calling [addSubCommand] once for each 'SubCommand' to be executed.
13 | *
14 | * See [ICommand], [IController], [INotification], [SimpleCommand], [INotifier]
15 | */
16 | class MacroCommand extends Notifier implements ICommand
17 | {
18 | /**
19 | * Constructor.
20 | *
21 | * You should not need to define a constructor,
22 | * instead, override the [initializeMacroCommand]
23 | * method.
24 | */
25 | MacroCommand()
26 | {
27 | subCommands = new List();
28 | initializeMacroCommand();
29 | }
30 |
31 | /**
32 | * Initialize the [MacroCommand].
33 | *
34 | * In your subclass, override this method to initialize the [MacroCommand]'s 'SubCommand' list
35 | * with [ICommand] factories by calling [addSubCommand].
36 | *
37 | * Note that 'SubCommand's may be any [ICommand] implementor, [MacroCommand]s or [SimpleCommands] are both acceptable.
38 | */
39 | void initializeMacroCommand(){}
40 |
41 | /**
42 | * Add a 'SubCommand'.
43 | *
44 | * The 'SubCommand' will be called in First In/First Out (FIFO) order.
45 | *
46 | * - Param [commandFactory] - a Function that constructs an instance of an [ICommand].
47 | */
48 | void addSubCommand( Function commandFactory )
49 | {
50 | subCommands.add( commandFactory );
51 | }
52 |
53 | /**
54 | * Execute this [MacroCommand]'s 'SubCommands'.
55 | *
56 | * The 'SubCommands' will be called in First In/First Out (FIFO) order.
57 | *
58 | * - Param [note] - the [INotification] object to be passed to each 'SubCommand'.
59 | */
60 | void execute( INotification note )
61 | {
62 | for ( Function commandFactory in subCommands ) {
63 | ICommand commandInstance = commandFactory();
64 | commandInstance.initializeNotifier( multitonKey );
65 | commandInstance.execute( note );
66 | }
67 | }
68 |
69 | // This [MacroCommand]'s 'SubCommands'
70 | List subCommands;
71 | }
72 |
--------------------------------------------------------------------------------
/lib/src/patterns/command/SimpleCommand.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A base [ICommand] implementation for executing a block of business logic.
5 | *
6 | * Your subclass should override the [execute] method where your business logic will handle the [INotification].
7 | *
8 | * See [ICommand], [IController], [INotification], [MacroCommand], [INotifier]
9 | */
10 | class SimpleCommand extends Notifier implements ICommand
11 | {
12 |
13 | /**
14 | * Respond to the [INotification] that triggered this [SimpleCommand].
15 | *
16 | * Perform business logic e.g., complex validation, processing, model changes.
17 | *
18 | * - Param [note] - an [INotification] object that triggered the execution of this [SimpleCommand]
19 | */
20 | void execute( INotification note ){ }
21 |
22 | }
--------------------------------------------------------------------------------
/lib/src/patterns/facade/Facade.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A base Multiton [IFacade] implementation.
5 | *
6 | * The Facade Pattern suggests providing a single
7 | * class to act as a central point of communication
8 | * for a subsystem.
9 | *
10 | * In PureMVC, the [IFacade] acts as an interface between
11 | * the core MVC actors [IModel], [IView], [IController], and
12 | * the rest of your application, which (aside from view components
13 | * and data objects) is mostly expressed with [ICommand]s,
14 | * [IMediator]s, and [IProxy]s.
15 | *
16 | * This means you don't need to communicate with the [IModel],
17 | * [IView], [IController] instances directly, you can just go through
18 | * the [IFacade]. And conveniently, [ICommand]s, [IMediator]s, and
19 | * [IProxy]s all have a built-in reference to their [IFacade] after
20 | * initialization, so they're all plugged in and ready to communicate
21 | * with each other.
22 | *
23 | * See [Model], [View], [Controller], [INotification], [ICommand], [IMediator], [IProxy]
24 | */
25 | class Facade implements IFacade
26 | {
27 | /**
28 | * Constructor.
29 | *
30 | * This [IFacade] implementation is a Multiton, so you should not call the constructor directly,
31 | * but instead call the static [getInstance] method.
32 | *
33 | * - Throws [MultitonErrorFacadeExists] if instance for this Multiton key has already been constructed.
34 | */
35 | Facade( String key )
36 | {
37 | if ( instanceMap[ key ] != null ) throw new MultitonErrorFacadeExists();
38 | initializeNotifier( key );
39 | instanceMap[ multitonKey ] = this;
40 | initializeFacade();
41 | }
42 |
43 | /**
44 | * Initialize the Multiton [Facade] instance.
45 | *
46 | * Called automatically by the constructor. Override in your
47 | * subclass to do any subclass specific initializations. Be
48 | * sure to call [super.initializeFacade()], though.
49 | */
50 | void initializeFacade( )
51 | {
52 | initializeModel();
53 | initializeController();
54 | initializeView();
55 | }
56 |
57 | /**
58 | * [IFacade] Multiton Factory method
59 | *
60 | * - Returns the [IFacade] Multiton instance for the specified key.
61 | */
62 | static IFacade getInstance( String key )
63 | {
64 | if ( key == null || key == "" ) return null;
65 | if ( instanceMap == null ) instanceMap = new Map();
66 | if ( instanceMap[ key ] == null ) instanceMap[ key ] = new Facade( key );
67 | return instanceMap[ key ];
68 | }
69 |
70 | /**
71 | * Initialize the [IController].
72 | *
73 | * Called by the [initializeFacade] method.
74 | *
75 | * Override this method in a subclass of [Facade] if you want to provide a different [IController].
76 | */
77 | void initializeController( )
78 | {
79 | if ( controller != null ) return;
80 | controller = Controller.getInstance( multitonKey );
81 | }
82 |
83 | /**
84 | * Initialize the [IModel].
85 | *
86 | * Called by the [initializeFacade] method.
87 | *
88 | * Override this method in a subclass of [Facade] if you wish to initialize a different [IModel].
89 | */
90 | void initializeModel( )
91 | {
92 | if ( model != null ) return;
93 | model = Model.getInstance( multitonKey );
94 | }
95 |
96 |
97 | /**
98 | * Initialize the [IView].
99 | *
100 | * Called by the [initializeFacade] method.
101 | *
102 | * Override this method in a subclass of [Facade] if you wish to initialize a different [IView].
103 | */
104 | void initializeView( )
105 | {
106 | if ( view != null ) return;
107 | view = View.getInstance( multitonKey );
108 | }
109 |
110 | /**
111 | * Register an [INotification] to [ICommand] mapping with the [Controller].
112 | *
113 | * - Param [noteName] - the name of the [INotification] to associate the [ICommand] with.
114 | * - Param [commandFactory] - a function that creates a new instance of the [ICommand].
115 | */
116 | void registerCommand( String noteName, Function commandFactory )
117 | {
118 | controller.registerCommand( noteName, commandFactory );
119 | }
120 |
121 | /**
122 | * Remove a previously registered [INotification] to [ICommand] mapping from the [IController].
123 | *
124 | * - Param [noteName] - the name of the [INotification] to remove the [ICommand] mapping for
125 | */
126 | void removeCommand( String noteName )
127 | {
128 | controller.removeCommand( noteName );
129 | }
130 |
131 | /**
132 | * Check if an [ICommand] is registered for a given [INotification] name with the [IController].
133 | *
134 | * - Param [noteName] - the name of the [INotification].
135 | * - Returns [bool] - whether an [ICommand] is currently registered for the given [noteName].
136 | */
137 | bool hasCommand( String noteName )
138 | {
139 | return controller.hasCommand( noteName );
140 | }
141 |
142 | /**
143 | * Register an [IProxy] instance with the [IModel].
144 | *
145 | * - Param [proxy] - an object reference to be held by the [IModel].
146 | */
147 | void registerProxy( IProxy proxy )
148 | {
149 | model.registerProxy( proxy );
150 | }
151 |
152 | /**
153 | * Retrieve an [IProxy] instance from the [IModel].
154 | *
155 | * - Param [proxyName] - the name of the [IProxy] instance to retrieve.
156 | * - Returns the [IProxy] instance previously registered with the given [proxyName].
157 | */
158 | IProxy retrieveProxy( String proxyName )
159 | {
160 | return model.retrieveProxy( proxyName );
161 | }
162 |
163 | /**
164 | * Remove an [IProxy] instance from the [IModel].
165 | *
166 | * - Param [proxyName] - name of the [IProxy] instance to be removed.
167 | * - Returns [IProxy] - the [IProxy] that was removed from the [IModel].
168 | */
169 | IProxy removeProxy( String proxyName )
170 | {
171 | IProxy proxy;
172 | if ( model != null ) proxy = model.removeProxy ( proxyName );
173 | return proxy;
174 | }
175 |
176 | /**
177 | * Check if an [IProxy] is registered with the [IModel].
178 | *
179 | * - Param [proxyName] - the name of the [IProxy] instance you're looking for.
180 | * - Returns [bool] - whether an [IProxy] is currently registered with the given [proxyName].
181 | */
182 | bool hasProxy( String proxyName )
183 | {
184 | return model.hasProxy( proxyName );
185 | }
186 |
187 | /**
188 | * Register an [IMediator] instance with the [IView].
189 | *
190 | * Registers the [IMediator] so that it can be retrieved by name,
191 | * and interrogates the [IMediator] for its [INotification] interests.
192 | *
193 | * If the [IMediator] returns a list of [INotification]
194 | * names to be notified about, an [Observer] is created encapsulating
195 | * the [IMediator] instance's [handleNotification] method
196 | * and registering it as an [IObserver] for all [INotification]s the
197 | * [IMediator] is interested in.
198 | *
199 | * - Param [mediator] - a reference to the [IMediator] instance.
200 | */
201 | void registerMediator( IMediator mediator )
202 | {
203 | if ( view != null ) view.registerMediator( mediator );
204 | }
205 |
206 | /**
207 | * Retrieve an [IMediator] from the [IView].
208 | *
209 | * - Param [mediatorName] - the name of the [IMediator] instance to retrieve.
210 | * - Returns [IMediator] - the [IMediator] instance previously registered in this core with the given [mediatorName].
211 | */
212 | IMediator retrieveMediator( String mediatorName )
213 | {
214 | return view.retrieveMediator( mediatorName );
215 | }
216 |
217 | /**
218 | * Remove an [IMediator] from the [IView].
219 | *
220 | * - Param [mediatorName] - name of the [IMediator] instance to be removed.
221 | * - Returns [IMediator] - the [IMediator] that was removed from this core's [IView].
222 | */
223 | IMediator removeMediator( String mediatorName )
224 | {
225 | IMediator mediator;
226 | if ( view != null ) mediator = view.removeMediator( mediatorName );
227 | return mediator;
228 | }
229 |
230 | /**
231 | * Check if a Mediator is registered or not
232 | *
233 | * Param [mediatorName]
234 | * Returns [bool] - whether an [IMediator] is registered in this core with the given [mediatorName].
235 | */
236 | bool hasMediator( String mediatorName )
237 | {
238 | return view.hasMediator( mediatorName );
239 | }
240 |
241 | /**
242 | * Send an [INotification].
243 | *
244 | * Convenience method to prevent having to construct new
245 | * [INotification] instances in our implementation code.
246 | *
247 | * - Param [noteName] the name of the note to send
248 | * - Param [body] - the body of the note (optional)
249 | * - Param [type] - the type of the note (optional)
250 | */
251 | void sendNotification( String noteName, [dynamic body, String type] )
252 | {
253 | notifyObservers( new Notification( noteName, body, type ) );
254 | }
255 |
256 | /**
257 | * Register an [IObserver] to be notified of [INotification]s with a given name.
258 | *
259 | * - Param [noteName] - the name of the [INotification] to notify this [IObserver] of.
260 | * - Param [observer] - the [IObserver] to register.
261 | */
262 | void registerObserver( String noteName, IObserver observer )
263 | {
264 | view.registerObserver(noteName, observer);
265 | }
266 |
267 | /**
268 | * Remove an [IObserver] from the list for a given [INotification] name.
269 | *
270 | * - Param [noteName] - which [IObserver] list to remove from.
271 | * - Param [notifyContext] - remove [IObserver]s with this object as the [notifyContext].
272 | */
273 | void removeObserver( String noteName, Object notifyContext )
274 | {
275 | view.removeObserver( noteName, notifyContext );
276 | }
277 |
278 | /**
279 | * Notify [IObserver]s.
280 | *
281 | * This method allows you to send custom [INotification] classes using the [IFacade].
282 | *
283 | * Usually you should just call [sendNotification] and pass the parameters,
284 | * never having to construct an [INotification] yourself.
285 | *
286 | * - Param [note] the [INotification] to have the [View] notify [Observers] of.
287 | */
288 | void notifyObservers( INotification note )
289 | {
290 | if ( view != null ) view.notifyObservers( note );
291 | }
292 |
293 | /**
294 | * Initialize this [INotifier].
295 | *
296 | * This is how an [INotifier] gets its [multitonKey].
297 | * Calls to [sendNotification] or to access the
298 | * [facade] will fail until after this method
299 | * has been called.
300 | *
301 | * - Param [key] - the [multitonKey] for this [INotifier] to use.
302 | */
303 | void initializeNotifier( String key )
304 | {
305 | multitonKey = key;
306 | }
307 |
308 | /**
309 | * Check if a Core is registered or not.
310 | *
311 | * - Param [key] - the Multiton key for the Core.
312 | * - Returns [bool] - whether a Core is registered with the given [key].
313 | */
314 | static bool hasCore( String key )
315 | {
316 | return ( instanceMap[ key ] != null );
317 | }
318 |
319 | /**
320 | * Remove a Core.
321 | *
322 | * Remove the [IModel], [IView], [IController], and [IFacade]
323 | * instances for the given key.
324 | *
325 | * - Param [key] - the Multiton key of the Core to remove.
326 | */
327 | static void removeCore( String key )
328 | {
329 | if ( instanceMap[ key ] == null ) return;
330 | Model.removeModel( key );
331 | View.removeView( key );
332 | Controller.removeController( key );
333 | instanceMap[ key ] = null;
334 | }
335 |
336 | // References to [IModel], [IView], and [IController]
337 | IController controller;
338 | IModel model;
339 | IView view;
340 |
341 | // This [IFacade]'s Multiton key
342 | String multitonKey;
343 |
344 | // The [IFacade] Multiton instanceMap.
345 | static Map instanceMap;
346 | }
347 |
348 | class MultitonErrorFacadeExists {
349 | const MultitonErrorFacadeExists ();
350 |
351 | String toString() {
352 | return "IFacade Multiton instance already constructed for this key.";
353 | }
354 | }
355 |
356 |
--------------------------------------------------------------------------------
/lib/src/patterns/mediator/Mediator.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A base [IMediator] implementation.
5 | *
6 | * In PureMVC, [IMediator] implementors assume these responsibilities:
7 | *
8 | * - Implement a common method which returns a list of all [INotification]s the [IMediator] has interest in.
9 | * - Implement a notification (callback) method for handling [INotification]s.
10 | * - Implement methods that are called when the [IMediator] is registered or removed from an [IView].
11 | *
12 | * Additionally, [IMediator]s typically:
13 | *
14 | * - Act as an intermediary between one or more view components and the rest of the application.
15 | * - Place [Event] listeners on view components, and implement handlers which often send [INotification]s or interact with [IProxy]s to post or retrieve data.
16 | * - Receive [INotification]s, (typically containing data) and updating view components in response.
17 | *
18 | * When an [IMediator] is registered with the [IView], the [IMediator]'s [listNotificationInterests] method is called
19 | * The [IMediator] will return a [List] of [INotification] names which it wishes to be notified about.
20 | *
21 | * The [IView] will then create an [IObserver] object encapsulating that [IMediator]'s and its [handleNotification] method
22 | * and register the [IObserver] for each [INotification] name returned by the [IMediator]'s [listNotificationInterests] method.
23 | *
24 | * See [INotification], [IView]
25 | */
26 | class Mediator extends Notifier implements IMediator
27 | {
28 |
29 | /**
30 | * Constructor
31 | *
32 | * - Param [name] - the [name] this [IMediator] will be registered with.
33 | * - Param [viewComponent] - the View Component (optional)
34 | */
35 | Mediator( String this.name, [dynamic this.viewComponent] ){ }
36 |
37 | /**
38 | * Get the [IMediator] instance's [name].
39 | *
40 | * - Returns [String] - the [IMediator] instance's [name].
41 | */
42 | String getName()
43 | {
44 | return name;
45 | }
46 |
47 | /**
48 | * Set the [IMediator]'s [viewComponent].
49 | *
50 | * - Param [Dynamic] - the [viewComponent].
51 | */
52 | void setViewComponent( dynamic component )
53 | {
54 | viewComponent = component;
55 | }
56 |
57 | /**
58 | * Get the [IMediator]'s [viewComponent].
59 | *
60 | * - Returns [Dynamic] - the View Component
61 | */
62 | dynamic getViewComponent()
63 | {
64 | return viewComponent;
65 | }
66 |
67 | /**
68 | * List [INotification] interests.
69 | *
70 | * - Returns [List] - a [List] of the [INotification] names this [IMediator] has an interest in.
71 | */
72 | List listNotificationInterests( )
73 | {
74 | return new List();
75 | }
76 |
77 | /**
78 | * Handle an [INotification].
79 | *
80 | * - Param [note] - the [INotification] to be handled.
81 | */
82 | void handleNotification( INotification note ) {}
83 |
84 | /**
85 | * Called by the [IView] when the [IMediator] is registered.
86 | */
87 | void onRegister( ) {}
88 |
89 | /**
90 | * Called by the [IView] when the [IMediator] is removed.
91 | */
92 | void onRemove( ) {}
93 |
94 | /**
95 | * This [IMediator]'s [name].
96 | */
97 | String name;
98 |
99 | /**
100 | * This [IMediator]'s [viewComponent].
101 | */
102 | dynamic viewComponent;
103 | }
104 |
--------------------------------------------------------------------------------
/lib/src/patterns/observer/Notification.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A base [INotification] implementation.
5 | *
6 | * The Observer Pattern as implemented within PureMVC exists
7 | * to support publish/subscribe communication between actors.
8 | *
9 | * [INotification]s are not meant to be a replacement for [Event]s,
10 | * but rather an internal communication mechanism that ensures
11 | * PureMVC is portable regardless of what type of Event mechanism
12 | * is supported (or not) on a given platform.
13 | *
14 | * Generally, [IMediator] implementors place [Event] listeners on
15 | * their view components, and [IProxy] implementors place [Event]
16 | * listeners on service components. Those [Event]s are then handled in
17 | * the usual way, and may lead to the broadcast of [INotification]s
18 | * that trigger [ICommand]s or notify [IMediator]s.
19 | *
20 | * See [IView], [IObserver], [Notification]
21 | */
22 | class Notification implements INotification
23 | {
24 | /**
25 | * Constructor.
26 | *
27 | * - Param [name] - name of the [INotification].
28 | * - Param [body] - the [INotification] body. (optional)
29 | * - Param [type] - the type of the [INotification] (optional)
30 | */
31 | Notification( String this.name, [dynamic this.body, String this.type] ){}
32 |
33 | /**
34 | * Get the [name] of the [INotification].
35 | *
36 | * - Returns [String] - the name of the [INotification].
37 | */
38 | String getName()
39 | {
40 | return name;
41 | }
42 |
43 | /**
44 | * Set the [body] of the [INotification].
45 | *
46 | * - Param [body] - the body of the [INotification].
47 | */
48 | void setBody( dynamic bodyObject )
49 | {
50 | body = bodyObject;
51 | }
52 |
53 | /**
54 | * Get the [body] of the [INotification].
55 | *
56 | * - Returns [Dynamic] - the body of the [INotification].
57 | */
58 | dynamic getBody()
59 | {
60 | return body;
61 | }
62 |
63 | /**
64 | * Set the [type] of the [INotification].
65 | *
66 | * - Param [type] - the type of the [INotification].
67 | */
68 | void setType( String noteType )
69 | {
70 | type = noteType;
71 | }
72 |
73 | /**
74 | * Get the [type] of the [INotification].
75 | *
76 | * - Returns [String] - the type of the [INotification].
77 | */
78 | String getType()
79 | {
80 | return type;
81 | }
82 |
83 | /**
84 | * This [INotifications]'s [name]
85 | */
86 | String name;
87 |
88 | /**
89 | * This [INotifications]'s [type]
90 | */
91 | String type;
92 |
93 | /**
94 | * This [INotifications]'s [body]
95 | */
96 | dynamic body;
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/lib/src/patterns/observer/Notifier.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A Base [INotifier] implementation.
5 | *
6 | * [MacroCommand], [SimpleCommand], [Mediator], and [Proxy]
7 | * all have a need to send [Notifications].
8 | *
9 | * The [INotifier] interface provides a common method called
10 | * [sendNotification] that relieves implementation code of
11 | * the necessity to actually construct [INotification]s.
12 | *
13 | * The [Notifier] class, which all of the above mentioned classes
14 | * extend, provides an initialized reference to an [IFacade]
15 | * Multiton, which is required by the convienience method
16 | * for sending [INotification]s, but also eases implementation as these
17 | * classes have frequent [Facade] interactions and usually require
18 | * access to the facade anyway.
19 | *
20 | * NOTE: In the MultiCore version of the framework, there is one caveat to
21 | * [Notifier]s, they cannot send notifications or reach the facade until they
22 | * have a valid multitonKey.
23 | *
24 | * The multitonKey is set:
25 | * * on a [ICommand] when it is instantiated by the [Controller]
26 | * * on a [IMediator] when it is registered with the [IView]
27 | * * on a [IProxy] when it is registered with the [IModel]
28 | *
29 | * See [Proxy], [Facade], [Mediator], [MacroCommand], [SimpleCommand]
30 | */
31 | class Notifier implements INotifier
32 | {
33 |
34 | Notifier(){
35 |
36 | }
37 |
38 | /**
39 | * Send an [INotification].
40 | *
41 | * Convenience method to prevent having to construct new
42 | * [INotification] instances in our implementation code.
43 | *
44 | * - Param [noteName] the name of the note to send
45 | * - Param [body] - the body of the note (optional)
46 | * - Param [type] - the type of the note (optional)
47 | */
48 | void sendNotification( String noteName, [dynamic body, String type] )
49 | {
50 | if (facade != null) {
51 | facade.sendNotification( noteName, body, type );
52 | }
53 | }
54 |
55 | /**
56 | * Initialize this [INotifier] instance.
57 | *
58 | * This is how a [INotifier] gets its [multitonKey].
59 | * Calls to [sendNotification] or access to the
60 | * [facade] will fail until after this method
61 | * has been called.
62 | *
63 | * - Param [key] - the Multiton key for this [INotifier].
64 | */
65 | void initializeNotifier( String key )
66 | {
67 | multitonKey = key;
68 | }
69 |
70 | /**
71 | * Return the Multiton Facade instance
72 | * - Throws [MultitonErrorNotifierLacksKey] if no multitonKey is set. Usually means facade getter is being accessed before initializeNotifier has been called (i.e., from the constructor). Defer facade access until the onRegister method.
73 | */
74 | IFacade get facade
75 | {
76 | if ( multitonKey == null ) throw new MultitonErrorNotifierLacksKey( );
77 | return Facade.getInstance( multitonKey );
78 | }
79 |
80 | // The Multiton Key for this app
81 | String multitonKey;
82 | }
83 |
84 | class MultitonErrorNotifierLacksKey {
85 | const MultitonErrorNotifierLacksKey();
86 |
87 | String toString() {
88 | return "multitonKey for this Notifier not yet initialized!";
89 | }
90 | }
--------------------------------------------------------------------------------
/lib/src/patterns/observer/Observer.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A base [IObserver] implementation.
5 | *
6 | * In PureMVC, [IObserver] implementors assume these responsibilities:
7 | *
8 | * - Encapsulate the notification (callback) method of the interested object.
9 | * - Encapsulate the notification context (this) of the interested object.
10 | * - Provide methods for setting the interested object's notification method and context.
11 | * - Provide a method for notifying the interested object.
12 | *
13 | * The Observer Pattern as implemented within PureMVC exists
14 | * to support publish/subscribe communication between actors.
15 | *
16 | * An [IObserver] is an object that encapsulates information
17 | * about an interested object with a notification (callback)
18 | * method that should be called when an [INotification] is
19 | * broadcast. The [IObserver] then acts as a conduit for
20 | * notifying the interested object.
21 | *
22 | * [IObserver]s can receive [Notification]s by having their
23 | * [notifyObserver] method invoked, passing in an object
24 | * implementing the [INotification] interface.
25 | *
26 | * See [IView], [INotification]
27 | */
28 | class Observer implements IObserver
29 | {
30 |
31 | /**
32 | * This [IObserver]'s [notifyMethod] (i.e., callback)
33 | */
34 | Function notifyMethod;
35 |
36 | /**
37 | * This [IObserver]'s [notifyContext] (i.e., caller)
38 | */
39 | Object notifyContext;
40 |
41 | /**
42 | * Constructor.
43 | *
44 | * The notifyMethod method on the interested object should take
45 | * one parameter of type [INotification]
46 | *
47 | * Param [notifyMethod] the callback method
48 | * Param [notifyContext] the caller object
49 | */
50 | Observer( Function this.notifyMethod, [Object this.notifyContext] ){}
51 |
52 | /**
53 | * Set the notification method.
54 | *
55 | * The notification method should take one parameter of type [INotification].
56 | *
57 | * - Param [notifyMethod] - the notification (callback) method of the interested object.
58 | */
59 | void setNotifyMethod( Function callback )
60 | {
61 | notifyMethod = callback;
62 | }
63 |
64 | /**
65 | * Set the notification context.
66 | *
67 | * - Param [caller] - a reference to the object to be notified.
68 | */
69 | void setNotifyContext( Object caller )
70 | {
71 | notifyContext = caller;
72 | }
73 |
74 | /**
75 | * Get the notification method.
76 | *
77 | * - Returns [Function] - the notification (callback) method of the interested object.
78 | */
79 | Function getNotifyMethod()
80 | {
81 | return notifyMethod;
82 | }
83 |
84 | /**
85 | * Get the notification context.
86 | *
87 | * - Returns [Object] - the caller.
88 | */
89 | Object getNotifyContext()
90 | {
91 | return notifyContext;
92 | }
93 |
94 | /**
95 | * Notify the interested object.
96 | *
97 | * - Param [note] - the [INotification] to pass to the caller's [notifyMethod].
98 | */
99 | void notifyObserver( INotification notification )
100 | {
101 | if ( notifyContext != null ) getNotifyMethod()( notification );
102 | }
103 |
104 | /**
105 | * Compare a given object to the [notifyContext] (caller) object.
106 | *
107 | * - Param [Object] - the object to compare.
108 | * - Returns [bool] - whether the given object and the [notifyContext] (caller) are the same.
109 | */
110 | bool compareNotifyContext( Object object )
111 | {
112 | return identical(object, notifyContext);
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/lib/src/patterns/proxy/Proxy.dart:
--------------------------------------------------------------------------------
1 | part of puremvc;
2 |
3 | /**
4 | * A base [IProxy] implementation.
5 | *
6 | * In PureMVC, [IProxy] implementors assume these responsibilities:
7 | *
8 | * - Implement a common method which returns the name of the [IProxy].
9 | * - Provide methods for setting and getting a Data Object.
10 | *
11 | * Additionally, [IProxy]s typically:
12 | *
13 | * - Provide methods for manipulating the Data Object and referencing it by type.
14 | * - Generate [INotification]s when their Data Object changes.
15 | * - Expose their name as a [static final String] called [NAME].
16 | * - Encapsulate interaction with local or remote services used to fetch and persist data.
17 | *
18 | * See [IModel]
19 | */
20 | class Proxy extends Notifier implements IProxy
21 | {
22 | /**
23 | * Constructor
24 | *
25 | * - Param [name] - the [name] this [IProxy] will be registered with.
26 | * - Param [data] - the Data Object (optional)
27 | */
28 | Proxy( String this.name, [dynamic this.data] ){ }
29 |
30 | /**
31 | * Get the [IProxy] [name].
32 | *
33 | * - Returns [String] - the [IProxy] instance [name].
34 | */
35 | String getName()
36 | {
37 | return name;
38 | }
39 |
40 | /**
41 | * Set the [dataObject].
42 | *
43 | * - Param [Dynamic] - the [dataObject] this [IProxy] will tend.
44 | */
45 | void setData( dynamic dataObject )
46 | {
47 | data = dataObject;
48 | }
49 |
50 | /**
51 | * Get the [dataObject].
52 | *
53 | * - Returns [Dynamic] - the [dataObject].
54 | */
55 | dynamic getData()
56 | {
57 | return data;
58 | }
59 |
60 | /**
61 | * Called by the [IModel] when the [IProxy] is registered.
62 | *
63 | * Override in your subclass and add code to be run at registration time.
64 | */
65 | void onRegister(){}
66 |
67 | /**
68 | * Called by the [IModel] when the [IProxy] is removed
69 | */
70 | void onRemove(){}
71 |
72 | /**
73 | * This [IProxy]'s [name].
74 | */
75 | String name;
76 |
77 | /**
78 | * This [IProxy]'s [dataObject].
79 | */
80 | dynamic data;
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: puremvc
2 | version: 2.0.6
3 | author: Cliff Hall
4 | description: PureMVC is a lightweight framework for creating applications based upon the classic Model-View-Controller design meta-pattern. It supports modular programming through the use of Multiton Core actors.
5 | homepage: http://www.puremvc.org
6 | environment:
7 | sdk: '>=0.8.10+6 <2.0.0'
8 | dependencies:
9 | analyzer: '>=0.10.1 <0.11.0'
10 | browser: '>=0.9.0 <0.10.0'
11 | dev_dependencies:
12 | unittest: '>=0.9.0 <0.10.0'
13 |
--------------------------------------------------------------------------------
/test/Test_Controller.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_Controller
4 | {
5 | _tests()
6 | {
7 | group('Controller', ()
8 | {
9 | test('getInstance()', () {
10 | // Get a unique multiton instance of Controller
11 | String multitonKey = "ControllerTest1";
12 | mvc.IController controller = mvc.Controller.getInstance( multitonKey );
13 |
14 | // Make sure a Controller instance was returned
15 | expect( controller, isNotNull );
16 |
17 | // Call getInstance() again
18 | mvc.IController again = mvc.Controller.getInstance( multitonKey );
19 |
20 | // Make sure the same Controller instance was returned
21 | expect( controller, same(again) );
22 | });
23 |
24 | test('registerCommand(), hasCommand()', () {
25 | // Get a unique multiton instance of Controller
26 | String multitonKey = "ControllerTest2";
27 | mvc.IController controller = mvc.Controller.getInstance( multitonKey );
28 |
29 | // Register a Command
30 | String noteName = "ControllerTest2Note";
31 | controller.registerCommand( noteName, () => new ControllerTestMacroCommand() );
32 |
33 | // Make sure it's registered
34 | expect( controller.hasCommand( noteName ), isTrue );
35 | });
36 |
37 | test('executeCommand() +SimpleCommand', () {
38 | // Get a unique multiton instance of Controller
39 | String multitonKey = "ControllerTest3";
40 | mvc.IController controller = mvc.Controller.getInstance( multitonKey );
41 |
42 | // Register a Command
43 | String noteName = "ControllerTest3Note";
44 | controller.registerCommand( noteName, () => new ControllerTestDoubleInputCommand() );
45 |
46 | // Create a Notification
47 | ControllerTestVO vo = new ControllerTestVO( 5 );
48 | mvc.INotification note = new mvc.Notification( noteName, vo );
49 |
50 | // Have the Controller execute the Command
51 | controller.executeCommand( note );
52 |
53 | // Make sure the Command executed
54 | expect( vo.doubled, equals(10) );
55 | expect( vo.squared, equals(null) );
56 |
57 | });
58 |
59 | test('executeCommand() +MacroCommand', () {
60 | // Get a unique multiton instance of Controller
61 | String multitonKey = "ControllerTest4";
62 | mvc.IController controller = mvc.Controller.getInstance( multitonKey );
63 |
64 | // Register a Command
65 | String noteName = "ControllerTest4Note";
66 | controller.registerCommand( noteName, () => new ControllerTestMacroCommand() );
67 |
68 | // Create a Notification
69 | ControllerTestVO vo = new ControllerTestVO( 5 );
70 | mvc.INotification note = new mvc.Notification( noteName, vo );
71 |
72 | // Have the Controller execute the Command
73 | controller.executeCommand( note );
74 |
75 | // Make sure the Command executed
76 | expect( vo.doubled, equals(10) );
77 | expect( vo.squared, equals(25) );
78 |
79 | });
80 |
81 | test('removeCommand()', () {
82 | // Get a unique multiton instance of Controller
83 | String multitonKey = "ControllerTest5";
84 | mvc.IController controller = mvc.Controller.getInstance( multitonKey );
85 |
86 | // Register a Command
87 | String noteName = "ControllerTest5Note";
88 | controller.registerCommand( noteName, () => new ControllerTestMacroCommand() );
89 |
90 | // Make sure it's registered
91 | expect( controller.hasCommand( noteName ), isTrue );
92 |
93 | // Remove the Command
94 | controller.removeCommand( noteName );
95 |
96 | // Make sur the Controller doesn't know about it any more
97 | expect( controller.hasCommand( noteName ), isFalse );
98 | });
99 | });
100 | }
101 |
102 | run() {
103 | _tests();
104 | }
105 | }
106 |
107 | class ControllerTestVO
108 | {
109 | int input;
110 | int doubled;
111 | int squared;
112 |
113 | ControllerTestVO( int this.input ){}
114 | }
115 |
116 | class ControllerTestMacroCommand extends mvc.MacroCommand
117 | {
118 | void initializeMacroCommand()
119 | {
120 | // add the subcommands
121 | addSubCommand( () => new ControllerTestDoubleInputCommand() );
122 | addSubCommand( () => new ControllerTestSquareInputCommand() );
123 | }
124 | }
125 |
126 | class ControllerTestDoubleInputCommand extends mvc.SimpleCommand
127 | {
128 | void execute( mvc.INotification note )
129 | {
130 | // Get the VO from the note body
131 | ControllerTestVO vo = note.getBody();
132 |
133 | // compute the input doubled
134 | vo.doubled = vo.input * 2;
135 | }
136 | }
137 |
138 | class ControllerTestSquareInputCommand extends mvc.SimpleCommand
139 | {
140 | void execute( mvc.INotification note )
141 | {
142 | // Get the VO from the note body
143 | ControllerTestVO vo = note.getBody();
144 |
145 | // Compute the input squared
146 | vo.squared = vo.input * vo.input;
147 | }
148 | }
--------------------------------------------------------------------------------
/test/Test_Facade.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_Facade
4 | {
5 | _tests()
6 | {
7 | // Test the Facade specific functionality
8 | group('Facade::IFacade', ()
9 | {
10 | test('getInstance()', () {
11 | // Get a unique multiton instance of Facade
12 | String multitonKey = "FacadeTest";
13 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
14 |
15 | // Make sure a Facade instance was returned
16 | expect( facade, isNotNull );
17 |
18 | // Call getInstance() again
19 | mvc.IFacade again = mvc.Facade.getInstance( multitonKey );
20 |
21 | // Make sure the same Facade instance was returned
22 | expect( facade, same(again) );
23 |
24 | // Make sure the Facade's multitonKey was set
25 | expect( facade.multitonKey, equals(multitonKey) );
26 |
27 | // Make sure the Model was created
28 | expect( facade.model, isNotNull );
29 |
30 | // Make sure the Model's multitonKey was set
31 | expect( facade.model.multitonKey, equals(multitonKey) );
32 |
33 | // Make sure the View was created
34 | expect( facade.view, isNotNull );
35 |
36 | // Make sure the View's multitonKey was set
37 | expect( facade.view.multitonKey, equals(multitonKey) );
38 |
39 | // Make sure the Controller was created
40 | expect( facade.controller, isNotNull );
41 |
42 | // Make sure the Controller's multitonKey was set
43 | expect( facade.controller.multitonKey, equals(multitonKey) );
44 | });
45 |
46 | test('getInstance(), hasCore()', () {
47 |
48 | // Make sure it's not reported as registered first
49 | String multitonKey = "FacadeTest0";
50 | expect( mvc.Facade.hasCore( multitonKey ), isFalse );
51 |
52 | // Get a unique multiton instance of Facade
53 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
54 |
55 | // Make sure it's registered
56 | expect( mvc.Facade.hasCore( multitonKey ), isTrue );
57 | });
58 |
59 | test('removeCore(), hasCore()', () {
60 |
61 | // Get a unique multiton instance of Facade
62 | String multitonKey = "FacadeTest1";
63 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
64 |
65 | // Make sure it's registered
66 | expect( mvc.Facade.hasCore( multitonKey ), isTrue );
67 |
68 | // Remove the core
69 | mvc.Facade.removeCore(multitonKey);
70 |
71 | // Make sure the core is no longer registered
72 | expect( mvc.Facade.hasCore( multitonKey ), isFalse );
73 | });
74 | });
75 |
76 | // Test the Facade's IController interface functionality
77 | group('Facade::IController', ()
78 | {
79 | test('registerCommand(), hasCommand()', () {
80 | // Get a unique multiton instance of Facade
81 | String multitonKey = "FacadeTest2";
82 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
83 |
84 | // Register a Command
85 | String noteName = "FacadeTest2Note";
86 | facade.registerCommand( noteName, () => new FacadeTestMacroCommand() );
87 |
88 | // Make sure it's registered
89 | expect( facade.hasCommand( noteName ), isTrue );
90 | });
91 |
92 | test('sendNotification() ->SimpleCommand', () {
93 | // Get a unique multiton instance of Facade
94 | String multitonKey = "FacadeTest3";
95 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
96 |
97 | // Register a Command
98 | String noteName = "FacadeTest3Note";
99 | facade.registerCommand( noteName, () => new FacadeTestDoubleInputCommand() );
100 |
101 | // Create a value object
102 | FacadeTestVO vo = new FacadeTestVO( 5 );
103 |
104 | // Have the Facade send the note, triggering the Command
105 | facade.sendNotification( noteName, vo );
106 |
107 | // Make sure the Command executed
108 | expect( vo.doubled, equals(10) );
109 | expect( vo.squared, equals(null) );
110 | });
111 |
112 | test('sendNotification() ->MacroCommand', () {
113 | // Get a unique multiton instance of Facade
114 | String multitonKey = "FacadeTest4";
115 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
116 |
117 | // Register a Command
118 | String noteName = "FacadeTest4Note";
119 | facade.registerCommand( noteName, () => new FacadeTestMacroCommand() );
120 |
121 | // Create a value object
122 | FacadeTestVO vo = new FacadeTestVO( 5 );
123 |
124 | // Have the Facade execute the Command
125 | facade.sendNotification( noteName, vo );
126 |
127 | // Make sure the Command executed
128 | expect( vo.doubled, equals(10) );
129 | expect( vo.squared, equals(25) );
130 | });
131 |
132 | test('removeCommand()', () {
133 | // Get a unique multiton instance of Facade
134 | String multitonKey = "FacadeTest5";
135 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
136 |
137 | // Register a Command
138 | String noteName = "FacadeTest5Note";
139 | facade.registerCommand( noteName, () => new FacadeTestMacroCommand() );
140 |
141 | // Make sure it's registered
142 | expect( facade.hasCommand( noteName ), isTrue );
143 |
144 | // Remove the Command
145 | facade.removeCommand( noteName );
146 |
147 | // Make sur the Controller doesn't know about it any more
148 | expect( facade.hasCommand( noteName ), isFalse );
149 | });
150 | });
151 |
152 | // Test the Facade's IView interface functionality
153 | group('Facade::IView', ()
154 | {
155 | test('registerMediator(), hasMediator()', () {
156 | // Get a unique multiton instance of Facade
157 | String multitonKey = "FacadeTest6";
158 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
159 |
160 | // Register a Mediator
161 | String mediatorName = "FacadeTest6Mediator";
162 | mvc.IMediator mediator = new mvc.Mediator( mediatorName );
163 | facade.registerMediator( mediator );
164 |
165 | // Make sure it's registered
166 | expect( facade.hasMediator( mediatorName ), isTrue );
167 | });
168 |
169 | test('retrieveMediator()', () {
170 | // Get a unique multiton instance of Facade
171 | String multitonKey = "FacadeTest7";
172 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
173 |
174 | // Register a Mediator
175 | String mediatorName = "FacadeTest7Mediator";
176 | mvc.IMediator mediator = new mvc.Mediator( mediatorName );
177 | facade.registerMediator( mediator );
178 |
179 | // Make sure same mediator is retrieved
180 | expect( facade.retrieveMediator( mediatorName ), same(mediator) );
181 | });
182 |
183 | test('removeMediator()', () {
184 | // Get a unique multiton instance of Facade
185 | String multitonKey = "FacadeTest8";
186 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
187 |
188 | // Register a Mediator
189 | String mediatorName = "FacadeTest8Mediator";
190 | mvc.IMediator mediator = new mvc.Mediator( mediatorName );
191 | facade.registerMediator( mediator );
192 |
193 | // Make sure it's registered
194 | expect( facade.hasMediator( mediatorName ), isTrue );
195 |
196 | // Remove Mediator
197 | facade.removeMediator( mediatorName );
198 |
199 | // Make sure the Facade no longer knows about it
200 | expect( facade.hasMediator( mediatorName ), isFalse );
201 | });
202 |
203 | test('registerObserver(), notifyObserver()', () {
204 | // Get a unique multiton instance of Facade
205 | String multitonKey = "FacadeTest8";
206 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
207 |
208 | // Register an Observer using this test
209 | // instance's facadeTestMethod as the callback
210 | String noteName = "FacadeTest8Note";
211 | mvc.IObserver observer = new mvc.Observer( facadeTestMethod, this );
212 | facade.registerObserver( noteName, observer );
213 |
214 | // Create a notification
215 | mvc.INotification note = new mvc.Notification( noteName );
216 |
217 | // Have the Facade notify the Observer
218 | facade.notifyObservers( note );
219 |
220 | // Make sure the callback was executed
221 | expect( facadeTestVar, equals(noteName) );
222 | });
223 |
224 | test('registerMediator(), ->mediator.onRegister()', () {
225 | // Get a unique multiton instance of Facade
226 | String multitonKey = "FacadeTest9";
227 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
228 |
229 | // Create a view component
230 | FacadeTestViewComponent vc = new FacadeTestViewComponent();
231 |
232 | // Register a FacadeTestMediator
233 | mvc.IMediator mediator = new FacadeTestMediator( vc );
234 | facade.registerMediator( mediator );
235 |
236 | // Make sure it's registered
237 | expect( facade.hasMediator( FacadeTestMediator.NAME ), isTrue );
238 |
239 | // Make sure the Mediator's onRegister() method was called
240 | expect( vc.onRegisterCalled, isTrue );
241 | });
242 |
243 | test('removeMediator(), ->mediator.onRemove()', () {
244 | // Get a unique multiton instance of Facade
245 | String multitonKey = "FacadeTest10";
246 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
247 |
248 | // Create a view component
249 | FacadeTestViewComponent vc = new FacadeTestViewComponent();
250 |
251 | // Register a FacadeTestMediator
252 | mvc.IMediator mediator = new FacadeTestMediator( vc );
253 | facade.registerMediator( mediator );
254 |
255 | // Make sure it's registered
256 | expect( facade.hasMediator( FacadeTestMediator.NAME ), isTrue );
257 |
258 | // Remove the Mediator
259 | facade.removeMediator( FacadeTestMediator.NAME );
260 |
261 | // Make sure the Mediator's onRemove() method was called
262 | expect( vc.onRemoveCalled, isTrue );
263 | });
264 |
265 | test('registerMediator(), ->mediator.listNotificationInterests()', () {
266 | // Get a unique multiton instance of Facade
267 | String multitonKey = "FacadeTest11";
268 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
269 |
270 | // Create a view component
271 | FacadeTestViewComponent vc = new FacadeTestViewComponent();
272 |
273 | // Register a FacadeTestMediator
274 | mvc.IMediator mediator = new FacadeTestMediator( vc );
275 | facade.registerMediator( mediator );
276 |
277 | // Make sure the Mediator's listNotificationInterests() method was called
278 | expect( vc.listNotificationInterestsCalled, isTrue );
279 | });
280 |
281 | test('sendNotification(), ->handleNotification()', () {
282 | // Get a unique multiton instance of Facade
283 | String multitonKey = "FacadeTest12";
284 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
285 |
286 | // Create a view component
287 | FacadeTestViewComponent vc = new FacadeTestViewComponent();
288 |
289 | // Register a FacadeTestMediator
290 | mvc.IMediator mediator = new FacadeTestMediator( vc );
291 | facade.registerMediator( mediator );
292 |
293 | // Send the Notification
294 | facade.sendNotification( FacadeTestNotes.NOTE_2 );
295 |
296 | // Make sure the Mediator's listNotificationInterests() method was called
297 | expect( vc.handleNotificationCalled, isTrue );
298 | });
299 | });
300 |
301 | // Test the Facade's IModel interface functionality
302 | group('Facade::IModel', ()
303 | {
304 | test('registerProxy(), hasProxy()', () {
305 | // Unique multiton instance of Facade
306 | String multitonKey = "FacadeTest13";
307 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
308 |
309 | // Register a Proxy
310 | String proxyName = "FacadeTest13Proxy";
311 | mvc.IProxy proxy = new mvc.Proxy( proxyName );
312 | facade.registerProxy( proxy );
313 |
314 | // Make sure it's there
315 | expect( facade.hasProxy( proxyName ), isTrue );
316 | });
317 |
318 | test('retrieveProxy()', () {
319 | // Unique multiton instance of Facade
320 | String multitonKey = "FacadeTest14";
321 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
322 |
323 | // Register a Proxy
324 | String proxyName = "FacadeTest14Proxy";
325 | mvc.IProxy proxy = new mvc.Proxy( proxyName );
326 | facade.registerProxy( proxy );
327 |
328 | // Make sure same Proxy is retrieved
329 | expect( facade.retrieveProxy( proxyName ), same(proxy) );
330 | });
331 |
332 | test('removeProxy(), hasProxy()', () {
333 | // Unique multiton instance of Facade
334 | String multitonKey = "FacadeTest15";
335 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
336 |
337 | // Register a Proxy
338 | String proxyName = "FacadeTest15Proxy";
339 | mvc.IProxy proxy = new mvc.Proxy( proxyName );
340 | facade.registerProxy( proxy );
341 |
342 | // Make sure it is returned when removed
343 | expect( facade.removeProxy( proxyName ), same(proxy) );
344 |
345 | // Make sure Facade doesn't know about it anymore
346 | expect( facade.hasProxy( proxyName ), isFalse );
347 | });
348 |
349 | test('registerProxy(), ->proxy.onRegister()', () {
350 | // Unique multiton instance of Facade
351 | String multitonKey = "FacadeTest16";
352 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
353 |
354 | // Register a Proxy
355 | mvc.IProxy proxy = new FacadeTestProxy();
356 | facade.registerProxy( proxy );
357 |
358 | // Make sure the Proxy's onRegister() method is called
359 | expect( proxy.getData(), equals(FacadeTestProxy.ON_REGISTER_CALLED) );
360 | });
361 |
362 | test('removeProxy(), ->proxy.onRemove()', () {
363 | // Unique multiton instance of Facade
364 | String multitonKey = "FacadeTest17";
365 | mvc.IFacade facade = mvc.Facade.getInstance( multitonKey );
366 |
367 | // Register a Proxy
368 | mvc.IProxy proxy = new FacadeTestProxy();
369 | facade.registerProxy( proxy );
370 |
371 | // Remove the Proxy
372 | facade.removeProxy( FacadeTestProxy.NAME );
373 |
374 | // Make sure the Proxy's onRemove() method is called
375 | expect( proxy.getData(), equals(FacadeTestProxy.ON_REMOVE_CALLED) );
376 | });
377 | });
378 | }
379 |
380 | run() {
381 | _tests();
382 | }
383 | }
384 |
385 | // A callback method for the test Observer
386 | void facadeTestMethod( mvc.INotification note ) {
387 | facadeTestVar = note.getName();
388 | }
389 |
390 | String facadeTestVar;
391 |
392 | class FacadeTestNotes {
393 |
394 | static String NOTE_1 = "FacadeTest/note/name/1";
395 | static String NOTE_2 = "FacadeTest/note/name/2";
396 | static String NOTE_3 = "FacadeTest/note/name/3";
397 | }
398 |
399 | class FacadeTestViewComponent
400 | {
401 | bool onRegisterCalled = false;
402 | bool onRemoveCalled = false;
403 | bool listNotificationInterestsCalled = false;
404 | bool handleNotificationCalled = false;
405 | }
406 |
407 | class FacadeTestMediator extends mvc.Mediator
408 | {
409 | // Name Mediator will be registered as
410 | static String NAME = "FacadeTestMediator";
411 |
412 | // Constructor
413 | FacadeTestMediator( FacadeTestViewComponent viewComponent ):super( NAME, viewComponent ){}
414 |
415 | // Accessors that cast viewComponent to the correct type for this Mediator
416 | FacadeTestViewComponent get vc { return viewComponent; }
417 | void set vc( FacadeTestViewComponent facadeTestViewComponent ) { viewComponent = facadeTestViewComponent; }
418 |
419 | // Called when Mediator is registered
420 | void onRegister()
421 | {
422 | vc.onRegisterCalled = true;
423 | }
424 |
425 | // Also called when Mediator is registered
426 | List listNotificationInterests()
427 | {
428 | vc.listNotificationInterestsCalled = true;
429 | return [ FacadeTestNotes.NOTE_1,
430 | FacadeTestNotes.NOTE_2,
431 | FacadeTestNotes.NOTE_3 ];
432 | }
433 |
434 | // Called when a notification this Mediator is interested in is sent
435 | void handleNotification( mvc.INotification note )
436 | {
437 | vc.handleNotificationCalled = true;
438 | }
439 |
440 | // Called when Mediator is removed
441 | void onRemove()
442 | {
443 | vc.onRemoveCalled = true;
444 | }
445 | }
446 |
447 | class FacadeTestProxy extends mvc.Proxy
448 | {
449 | static String NAME = "FacadeTestProxyClass";
450 | static String FRESH = "Fresh Instance";
451 | static String ON_REGISTER_CALLED = "onRegister() Called";
452 | static String ON_REMOVE_CALLED = "onRemove() Called";
453 |
454 | FacadeTestProxy():super( NAME ){
455 | setData( FRESH );
456 | }
457 |
458 | void onRegister()
459 | {
460 | setData( ON_REGISTER_CALLED );
461 | }
462 |
463 | void onRemove()
464 | {
465 | setData( ON_REMOVE_CALLED );
466 | }
467 | }
468 |
469 | class FacadeTestVO
470 | {
471 | int input;
472 | int doubled;
473 | int squared;
474 |
475 | FacadeTestVO( int this.input ){}
476 | }
477 |
478 | class FacadeTestMacroCommand extends mvc.MacroCommand
479 | {
480 | void initializeMacroCommand()
481 | {
482 | // add the subcommands
483 | addSubCommand( () => new FacadeTestDoubleInputCommand() );
484 | addSubCommand( () => new FacadeTestSquareInputCommand() );
485 | }
486 | }
487 |
488 | class FacadeTestDoubleInputCommand extends mvc.SimpleCommand
489 | {
490 | void execute( mvc.INotification note )
491 | {
492 | // Get the VO from the note body
493 | FacadeTestVO vo = note.getBody();
494 |
495 | // compute the input doubled
496 | vo.doubled = vo.input * 2;
497 | }
498 | }
499 |
500 | class FacadeTestSquareInputCommand extends mvc.SimpleCommand
501 | {
502 | void execute( mvc.INotification note )
503 | {
504 | // Get the VO from the note body
505 | FacadeTestVO vo = note.getBody();
506 |
507 | // Compute the input squared
508 | vo.squared = vo.input * vo.input;
509 | }
510 | }
511 |
--------------------------------------------------------------------------------
/test/Test_MacroCommand.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_MacroCommand
4 | {
5 | _tests()
6 | {
7 | group('MacroCommand', ()
8 | {
9 | test('Constructor', () {
10 | // Create a MacroCommand
11 | mvc.ICommand macroCommand = new MacroCommandTestCommand();
12 | expect( macroCommand, isNotNull );
13 | });
14 |
15 | test('execute()', () {
16 | // Create a MacroCommand
17 | mvc.ICommand macroCommand = new MacroCommandTestCommand();
18 |
19 | // Create a VO and a Notification to pass it to the Command with
20 | MacroCommandTestVO vo = new MacroCommandTestVO( 5 );
21 | mvc.INotification note = new mvc.Notification( "MacroCommandTest", vo );
22 |
23 | // Execute the MacroCommand execute the note
24 | macroCommand.execute(note);
25 | expect( vo.doubled, equals(10) );
26 | expect( vo.squared, equals(25) );
27 | });
28 |
29 | test('initializeNotifier()', () {
30 | // Create a MacroCommand
31 | mvc.INotifier notifier = new MacroCommandTestCommand();
32 |
33 | // Call initializeNotifier()
34 | String multitonKey = "MacroCommandTest";
35 | notifier.initializeNotifier( multitonKey );
36 |
37 | // Make sure MacroCommand's multitonKey was set
38 | expect( notifier.multitonKey, isNotNull );
39 | });
40 | });
41 | }
42 |
43 | run() {
44 | _tests();
45 | }
46 | }
47 |
48 | class MacroCommandTestVO
49 | {
50 | int input;
51 | int doubled;
52 | int squared;
53 |
54 | MacroCommandTestVO( int this.input ) {}
55 | }
56 |
57 | class MacroCommandTestCommand extends mvc.MacroCommand
58 | {
59 | void initializeMacroCommand() {
60 | // Add the subcommands
61 | addSubCommand( () => new MacroCommandTestDoubleInputCommand() );
62 | addSubCommand( () => new MacroCommandTestSquareInputCommand() );
63 | }
64 | }
65 |
66 | class MacroCommandTestDoubleInputCommand extends mvc.SimpleCommand
67 | {
68 | void execute( mvc.INotification note )
69 | {
70 | // Get the VO from the note body
71 | MacroCommandTestVO vo = note.getBody();
72 |
73 | // Compute the input doubled
74 | vo.doubled = vo.input * 2;
75 | }
76 | }
77 |
78 | class MacroCommandTestSquareInputCommand extends mvc.SimpleCommand
79 | {
80 | void execute( mvc.INotification note )
81 | {
82 | // Get the VO from the note body
83 | MacroCommandTestVO vo = note.getBody();
84 |
85 | // Compute the input doubled
86 | vo.squared = vo.input * vo.input;
87 | }
88 | }
--------------------------------------------------------------------------------
/test/Test_Mediator.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_Mediator
4 | {
5 | _tests()
6 | {
7 | group('Mediator', ()
8 | {
9 | test('Constructor', () {
10 | // Create a Mediator
11 | String mediatorName = "TestMediator1";
12 | mvc.IMediator mediator = new mvc.Mediator( mediatorName );
13 |
14 | // Make sure it was created
15 | expect( mediator, isNotNull );
16 | });
17 |
18 | test('getMediatorName()', () {
19 | // Create a Mediator
20 | String mediatorName = "TestMediator2";
21 | mvc.IMediator mediator = new mvc.Mediator( mediatorName );
22 |
23 | // Make sure the Mediator's name was set
24 | expect( mediator.getName(), equals(mediatorName) );
25 | expect( mediator.name, equals(mediatorName) );
26 | });
27 |
28 | test('Constructor +viewComponent, getViewComponent(), .viewComponent', () {
29 | // Create a view component
30 | Object viewComponent = new Object();
31 |
32 | // Create a Mediator with the view component
33 | String mediatorName = "TestMediator3";
34 | mvc.IMediator mediator = new mvc.Mediator( mediatorName, viewComponent );
35 |
36 | // Make sure the view component was set
37 | expect( mediator.getViewComponent(), same(viewComponent) );
38 | expect( mediator.viewComponent, same(viewComponent) );
39 | });
40 |
41 | test('setViewComponent(), getViewComponent()', () {
42 | // Create a view component
43 | Object viewComponent = new Object();
44 |
45 | // Create a Mediator
46 | String mediatorName = "TestMediator4";
47 | mvc.IMediator mediator = new mvc.Mediator( mediatorName );
48 |
49 | // Call setViewComponent()
50 | mediator.setViewComponent( viewComponent );
51 |
52 | // Make sure the view component was set
53 | expect( mediator.getViewComponent(), same(viewComponent) );
54 | expect( mediator.viewComponent, same(viewComponent) );
55 | });
56 |
57 | test('initializeNotifier()', () {
58 | // Create a Mediator
59 | String mediatorName = "TestMediator5";
60 | mvc.INotifier notifier = new mvc.Mediator( mediatorName );
61 |
62 | // Call initializeNotifier()
63 | String multitonKey = "MediatorTestKey";
64 | notifier.initializeNotifier( multitonKey );
65 |
66 | // Make sure the Mediator's multitonKey was set
67 | expect( notifier.multitonKey, isNotNull );
68 | });
69 | });
70 | }
71 |
72 | run() {
73 | _tests();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/test/Test_Model.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_Model
4 | {
5 | _tests()
6 | {
7 | group('Model', ()
8 | {
9 | test('getInstance()', () {
10 | // Unique multiton instance of Model
11 | String multitonKey = "ModelTest1";
12 | mvc.IModel model = mvc.Model.getInstance( multitonKey );
13 | expect( model, isNotNull );
14 |
15 | // Same instance retrieved again
16 | mvc.IModel again = mvc.Model.getInstance( multitonKey );
17 | expect( model, same(again) );
18 | });
19 |
20 | test('registerProxy(), hasProxy()', () {
21 | // Unique multiton instance of Model
22 | String multitonKey = "ModelTest2";
23 | mvc.IModel model = mvc.Model.getInstance( multitonKey );
24 |
25 | // Register a Proxy
26 | String proxyName = "ModelTest2Proxy";
27 | mvc.IProxy proxy = new mvc.Proxy( proxyName );
28 | model.registerProxy( proxy );
29 |
30 | // Make sure it's there
31 | expect( model.hasProxy( proxyName ), isTrue );
32 | });
33 |
34 | test('retrieveProxy()', () {
35 | // Unique multiton instance of Model
36 | String multitonKey = "ModelTest3";
37 | mvc.IModel model = mvc.Model.getInstance( multitonKey );
38 |
39 | // Register a Proxy
40 | String proxyName = "ModelTest3Proxy";
41 | mvc.IProxy proxy = new mvc.Proxy( proxyName );
42 | model.registerProxy( proxy );
43 |
44 | // Make sure same Proxy is retrieved
45 | expect( model.retrieveProxy( proxyName ), same(proxy) );
46 | });
47 |
48 | test('removeProxy(), hasProxy()', () {
49 | // Unique multiton instance of Model
50 | String multitonKey = "ModelTest4";
51 | mvc.IModel model = mvc.Model.getInstance( multitonKey );
52 |
53 | // Register a Proxy
54 | String proxyName = "ModelTest4Proxy";
55 | mvc.IProxy proxy = new mvc.Proxy( proxyName );
56 | model.registerProxy( proxy );
57 |
58 | // Make sure it is returned when removed
59 | expect( model.removeProxy( proxyName ), same(proxy) );
60 |
61 | // Make sure Model doesn't know about it anymore
62 | expect( model.hasProxy( proxyName ), isFalse );
63 | });
64 |
65 | test('Model calls onRegister()', () {
66 | // Unique multiton instance of Model
67 | String multitonKey = "ModelTest5";
68 | mvc.IModel model = mvc.Model.getInstance( multitonKey );
69 |
70 | // Register a Proxy
71 | mvc.IProxy proxy = new ModelTestProxy();
72 | model.registerProxy( proxy );
73 |
74 | // Make sure the Model calls the Proxy's onRegister() method
75 | expect( proxy.getData(), equals(ModelTestProxy.ON_REGISTER_CALLED) );
76 | });
77 |
78 | test('Model calls onRemove()', () {
79 | // Unique multiton instance of Model
80 | String multitonKey = "ModelTest6";
81 | mvc.IModel model = mvc.Model.getInstance( multitonKey );
82 |
83 | // Register a Proxy
84 | mvc.IProxy proxy = new ModelTestProxy();
85 | model.registerProxy( proxy );
86 |
87 | // Remove the Proxy
88 | model.removeProxy( ModelTestProxy.NAME );
89 |
90 | // Make sure the Model calls the Proxy's onRemove() method
91 | expect( proxy.getData(), equals(ModelTestProxy.ON_REMOVE_CALLED) );
92 | });
93 | });
94 | }
95 |
96 | run() {
97 | _tests();
98 | }
99 | }
100 |
101 | class ModelTestProxy extends mvc.Proxy
102 | {
103 | static String NAME = "ModelTestProxyClass";
104 | static String FRESH = "Fresh Instance";
105 | static String ON_REGISTER_CALLED = "onRegister() Called";
106 | static String ON_REMOVE_CALLED = "onRemove() Called";
107 |
108 | ModelTestProxy():super( NAME ){
109 | setData( FRESH );
110 | }
111 |
112 | void onRegister()
113 | {
114 | setData( ON_REGISTER_CALLED );
115 | }
116 |
117 | void onRemove()
118 | {
119 | setData( ON_REMOVE_CALLED );
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/test/Test_Notification.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_Notification
4 | {
5 | _tests()
6 | {
7 | group('Notification', ()
8 | {
9 | test('Constructor minimum args', () {
10 | // Create a Notification with a name only
11 | String name = "Test";
12 | mvc.INotification note = new mvc.Notification( name );
13 |
14 | // Make sure the note was created
15 | expect( note, isNotNull );
16 | });
17 |
18 | test('.name, getName()', () {
19 | // Create a Notification with name only
20 | String name = "Test";
21 | mvc.INotification note = new mvc.Notification( name );
22 |
23 | // Make sure the name was set
24 | expect( name, equals( note.getName() ) );
25 | expect( name, equals( note.name ) );
26 | });
27 |
28 | test('.type, getType()', () {
29 | // Create a Notification with name and type only
30 | String name = "Test";
31 | String type = "Type";
32 | mvc.INotification note = new mvc.Notification( name, null, type );
33 |
34 | // Make Sure the type was set
35 | expect( type, equals( note.getType() ) );
36 | expect( type, equals( note.type ) );
37 | });
38 |
39 | test('.body, getBody()', () {
40 | // Create a Notification with a body
41 | String name = "Test";
42 | List body = new List();
43 | mvc.INotification note = new mvc.Notification( name, body );
44 |
45 | // Make sure the body was set
46 | expect( body, equals( note.getBody() ) );
47 | expect( body, equals( note.body ) );
48 | });
49 | });
50 | }
51 |
52 | run() {
53 | _tests();
54 | }
55 | }
--------------------------------------------------------------------------------
/test/Test_Observer.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_Observer
4 | {
5 | _tests()
6 | {
7 | group('Observer', ()
8 | {
9 | test('Constructor null args', () {
10 | // Create a blind Observer
11 | mvc.IObserver observer = new mvc.Observer( null, null );
12 |
13 | // Make sure Observer was created
14 | expect( observer, isNotNull );
15 | });
16 |
17 | test('Constructor complete args', () {
18 | // Create an observer with callback method and caller instance defined
19 | mvc.IObserver observer = new mvc.Observer( this.observerTestMethod, this );
20 |
21 | // Make sure the Observer was created
22 | expect( observer, isNotNull );
23 |
24 | // Make sure caller and callback were set
25 | expect( observer.getNotifyMethod(), isNotNull );
26 | expect( observer.notifyMethod, isNotNull );
27 | expect( observer.getNotifyContext(), isNotNull );
28 | expect( observer.notifyContext, isNotNull );
29 |
30 | });
31 |
32 | test('Constructor minimum args', () {
33 | // Create an Observer with callack only
34 | mvc.IObserver observer = new mvc.Observer( this.observerTestMethod );
35 |
36 | // Make sure Observer was created
37 | expect( observer, isNotNull );
38 |
39 | // Make sure callback method was set
40 | expect( observer.getNotifyMethod(), isNotNull );
41 | });
42 |
43 | test('setNotifyMethod()', () {
44 | // Create an Observer
45 | mvc.IObserver observer = new mvc.Observer( null );
46 |
47 | // Call setNotifyMethod()
48 | observer.setNotifyMethod( observerTestMethod );
49 |
50 | // Make sure callback method was set
51 | expect( observer.getNotifyMethod(), isNotNull );
52 | expect( observer.notifyMethod, isNotNull );
53 |
54 | });
55 |
56 | test('setNotifyContext()', () {
57 | // Create an Observer
58 | mvc.IObserver observer = new mvc.Observer( null );
59 |
60 | // Call setNotifyContext()
61 | observer.setNotifyContext( this );
62 |
63 | // Make sure caller was set
64 | expect( observer.getNotifyContext(), isNotNull );
65 | expect( observer.getNotifyContext(), same(this) );
66 | expect( observer.notifyContext, isNotNull );
67 | expect( observer.notifyContext, same(this) );
68 | });
69 |
70 | test('compareNotifyContext()', () {
71 | // Create an Observer with only a caller
72 | mvc.IObserver observer = new mvc.Observer( null, this );
73 |
74 | // Make sure the caller was set
75 | expect( observer.compareNotifyContext( this ), isTrue );
76 | });
77 |
78 | test('notifyObserver()', () {
79 | // Create an Observer with this test instance's observerTestMethod() as the callback
80 | mvc.IObserver observer = new mvc.Observer( this.observerTestMethod, this );
81 |
82 | // Create a Notification
83 | String name = "Test";
84 | mvc.INotification note = new mvc.Notification( name );
85 |
86 | // Notify the Observer
87 | observer.notifyObserver( note );
88 |
89 | // Make sure the Observer was notified
90 | expect( observerTestNote, isNotNull );
91 | expect( observerTestNote.name, equals(name) );
92 | });
93 | });
94 | }
95 |
96 | // Test Notification
97 | mvc.INotification observerTestNote;
98 |
99 | // Callback method for Observer
100 | observerTestMethod( mvc.INotification note ){
101 | observerTestNote = note;
102 | }
103 |
104 | run() {
105 | _tests();
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/test/Test_Proxy.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_Proxy
4 | {
5 | _tests()
6 | {
7 | group('ProxyTest', ()
8 | {
9 | test('Constructor +name', () {
10 | String proxyName = "TestProxy1";
11 | mvc.IProxy proxy = new mvc.Proxy( proxyName );
12 | expect( proxy, isNotNull );
13 | });
14 |
15 | test('getName(), .name', () {
16 | // Create a Proxy
17 | String proxyName = "TestProxy2";
18 | mvc.IProxy proxy = new mvc.Proxy( proxyName );
19 |
20 | // Make sure the Proxy name was set
21 | expect( proxy.getName(), equals(proxyName) );
22 | expect( proxy.name, equals(proxyName) );
23 | });
24 |
25 | test('Constructor +data, getData(), .data', () {
26 | // Create some data
27 | List data = ['red', 'green', 'blue'];
28 |
29 | // Create a Proxy with that data
30 | String proxyName = "TestProxy3";
31 | mvc.IProxy proxy = new mvc.Proxy( proxyName, data );
32 |
33 | // Make sure the Proxy was created
34 | expect( proxy, isNotNull );
35 |
36 | // Make sure the data was set
37 | expect( proxy.getData(), same(data) );
38 | expect( proxy.data, same(data) );
39 | });
40 |
41 | test('setData(), getData(), .data', () {
42 | // Create some data
43 | List data = ['red', 'green', 'blue'];
44 |
45 | // Create a Proxy
46 | String proxyName = "TestProxy4";
47 | mvc.IProxy proxy = new mvc.Proxy( proxyName );
48 |
49 | // Call setData()
50 | proxy.setData( data );
51 |
52 | // Make sure the data was set
53 | expect( proxy.getData(), same(data) );
54 | expect( proxy.data, same(data) );
55 |
56 | });
57 |
58 | test('initializeNotifier()', () {
59 | // Create a Proxy
60 | String proxyName = "TestProxy5";
61 | mvc.INotifier notifier = new mvc.Proxy( proxyName );
62 |
63 | // Call initializeNotifier()
64 | String multitonKey = "ProxyTestKey";
65 | notifier.initializeNotifier( multitonKey );
66 |
67 | // Make sure the Proxy's multitonKey was set
68 | expect( notifier.multitonKey, isNotNull );
69 | });
70 | });
71 | }
72 |
73 | run() {
74 | _tests();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/test/Test_SimpleCommand.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_SimpleCommand
4 | {
5 | _tests()
6 | {
7 | group('SimpleCommand', ()
8 | {
9 | test('Constructor', () {
10 | // Create a SimpeCommand
11 | mvc.ICommand simpleCommand = new SimpleCommandTestDoubleInputCommand();
12 | expect( simpleCommand, isNotNull );
13 | });
14 |
15 | test('execute()', () {
16 | // Create a SimpeCommand
17 | mvc.ICommand simpleCommand = new SimpleCommandTestDoubleInputCommand();
18 |
19 | // Crete a VO and a Notification to pass it to the Command with
20 | SimpleCommandTestVO vo = new SimpleCommandTestVO( 5 );
21 | mvc.INotification note = new mvc.Notification( "SimpleCommandTestNote", vo );
22 |
23 | // Execute the SimpleCommand with the note
24 | simpleCommand.execute( note );
25 |
26 | // Make sure the SimpleCommand logic was executed
27 | expect( vo.result, equals(10) );
28 | });
29 |
30 | test('initializeNotifier()', () {
31 | // Create a SimpleCommand
32 | mvc.INotifier notifier = new SimpleCommandTestDoubleInputCommand();
33 |
34 | // call initializeNotifier()
35 | String multitonKey = "SimpleCommandTest";
36 | notifier.initializeNotifier( multitonKey );
37 |
38 | // Make sure the SimpleCommand's multitonKey was set
39 | expect( notifier.multitonKey, isNotNull );
40 | });
41 | });
42 | }
43 |
44 | run() {
45 | _tests();
46 | }
47 | }
48 |
49 | class SimpleCommandTestVO
50 | {
51 | SimpleCommandTestVO( int this.input ) {
52 | }
53 |
54 | int input;
55 | int result;
56 | }
57 |
58 | class SimpleCommandTestDoubleInputCommand extends mvc.SimpleCommand
59 | {
60 | void execute( mvc.INotification note )
61 | {
62 | // Get the VO from the note
63 | SimpleCommandTestVO vo = note.getBody();
64 |
65 | // Fabricate a result
66 | vo.result = 2 * vo.input;
67 | }
68 | }
--------------------------------------------------------------------------------
/test/Test_View.dart:
--------------------------------------------------------------------------------
1 | part of puremvc_unit_tests;
2 |
3 | class Test_View
4 | {
5 | _tests()
6 | {
7 | group('ViewTest', ()
8 | {
9 | test('getInstance()', () {
10 | // Get a unique multiton instance of View
11 | String multitonKey = "ViewTest1";
12 | mvc.IView view = mvc.View.getInstance( multitonKey );
13 |
14 | // Make sure a View instance was returned
15 | expect( view, isNotNull );
16 |
17 | // Call getInstance() again
18 | mvc.IView again = mvc.View.getInstance( multitonKey );
19 |
20 | // Make sure the same View instance was returned
21 | expect( view, same(again) );
22 | });
23 |
24 | test('registerMediator(), hasMediator()', () {
25 | // Get a unique multiton instance of View
26 | String multitonKey = "ViewTest2";
27 | mvc.IView view = mvc.View.getInstance( multitonKey );
28 |
29 | // Register a Mediator
30 | String mediatorName = "ViewTest3Mediator";
31 | mvc.IMediator mediator = new mvc.Mediator( mediatorName );
32 | view.registerMediator( mediator );
33 |
34 | // Make sure it's registered
35 | expect( view.hasMediator( mediatorName ), isTrue );
36 | });
37 |
38 | test('retrieveMediator()', () {
39 | // Get a unique multiton instance of View
40 | String multitonKey = "ViewTest3";
41 | mvc.IView view = mvc.View.getInstance( multitonKey );
42 |
43 | // Register a Mediator
44 | String mediatorName = "ViewTest3Mediator";
45 | mvc.IMediator mediator = new mvc.Mediator( mediatorName );
46 | view.registerMediator( mediator );
47 |
48 | // Make sure same mediator is retrieved
49 | expect( view.retrieveMediator( mediatorName ), same(mediator) );
50 | });
51 |
52 | test('removeMediator()', () {
53 | // Get a unique multiton instance of View
54 | String multitonKey = "ViewTest4";
55 | mvc.IView view = mvc.View.getInstance( multitonKey );
56 |
57 | // Register a Mediator
58 | String mediatorName = "ViewTest4Mediator";
59 | mvc.IMediator mediator = new mvc.Mediator( mediatorName );
60 | view.registerMediator( mediator );
61 |
62 | // Make sure it's registered
63 | expect( view.hasMediator( mediatorName ), isTrue );
64 |
65 | // Remove Mediator
66 | view.removeMediator( mediatorName );
67 |
68 | // Make sure the View no longer knows about it
69 | expect( view.hasMediator( mediatorName ), isFalse );
70 | });
71 |
72 | test('registerObserver(), notifyObserver()', () {
73 | // Get a unique multiton instance of View
74 | String multitonKey = "ViewTest5";
75 | mvc.IView view = mvc.View.getInstance( multitonKey );
76 |
77 | // Register an Observer using this test
78 | // instance's viewTestMethod as the callback
79 | String noteName = "ViewTest5Note";
80 | mvc.IObserver observer = new mvc.Observer( viewTestMethod, this );
81 | view.registerObserver( noteName, observer );
82 |
83 | // Create a notification
84 | mvc.INotification note = new mvc.Notification( noteName );
85 |
86 | // Have the View notify the Observer
87 | view.notifyObservers( note );
88 |
89 | // Make sure the callback was executed
90 | expect( viewTestVar, equals(noteName) );
91 | });
92 |
93 | test('View calls onRegister()', () {
94 | // Get a unique multiton instance of View
95 | String multitonKey = "ViewTest6";
96 | mvc.IView view = mvc.View.getInstance( multitonKey );
97 |
98 | // Create a view component
99 | ViewTestViewComponent vc = new ViewTestViewComponent();
100 |
101 | // Register a ViewTestMediator
102 | mvc.IMediator mediator = new ViewTestMediator( vc );
103 | view.registerMediator( mediator );
104 |
105 | // Make sure it's registered
106 | expect( view.hasMediator( ViewTestMediator.NAME ), isTrue );
107 |
108 | // Make sure the Mediator's onRegister() method was called
109 | expect( vc.onRegisterCalled, isTrue );
110 | });
111 |
112 | test('View calls onRemove()', () {
113 | // Get a unique multiton instance of View
114 | String multitonKey = "ViewTest7";
115 | mvc.IView view = mvc.View.getInstance( multitonKey );
116 |
117 | // Create a view component
118 | ViewTestViewComponent vc = new ViewTestViewComponent();
119 |
120 | // Register a ViewTestMediator
121 | mvc.IMediator mediator = new ViewTestMediator( vc );
122 | view.registerMediator( mediator );
123 |
124 | // Make sure it's registered
125 | expect( view.hasMediator( ViewTestMediator.NAME ), isTrue );
126 |
127 | // Remove the Mediator
128 | view.removeMediator( ViewTestMediator.NAME );
129 |
130 | // Make sure the Mediator's onRemove() method was called
131 | expect( vc.onRemoveCalled, isTrue );
132 | });
133 |
134 | test('View calls listNotificationInterests()', () {
135 | // Get a unique multiton instance of View
136 | String multitonKey = "ViewTest8";
137 | mvc.IView view = mvc.View.getInstance( multitonKey );
138 |
139 | // Create a view component
140 | ViewTestViewComponent vc = new ViewTestViewComponent();
141 |
142 | // Register a ViewTestMediator
143 | mvc.IMediator mediator = new ViewTestMediator( vc );
144 | view.registerMediator( mediator );
145 |
146 | // Make sure the Mediator's listNotificationInterests() method was called
147 | expect( vc.listNotificationInterestsCalled, isTrue );
148 | });
149 |
150 | test('View calls handleNotification()', () {
151 | // Get a unique multiton instance of View
152 | String multitonKey = "ViewTest9";
153 | mvc.IView view = mvc.View.getInstance( multitonKey );
154 |
155 | // Create a view component
156 | ViewTestViewComponent vc = new ViewTestViewComponent();
157 |
158 | // Register a ViewTestMediator
159 | mvc.IMediator mediator = new ViewTestMediator( vc );
160 | view.registerMediator( mediator );
161 |
162 | // Create a Notification
163 | mvc.INotification note = new mvc.Notification( ViewTestNotes.NOTE_2 );
164 |
165 | // Send the Notification
166 | view.notifyObservers( note );
167 |
168 | // Make sure the Mediator's listNotificationInterests() method was called
169 | expect( vc.handleNotificationCalled, isTrue );
170 | });
171 | });
172 | }
173 |
174 | // A callback method for the test Observer
175 | void viewTestMethod( mvc.INotification note ) {
176 | viewTestVar = note.getName();
177 | }
178 |
179 | String viewTestVar;
180 |
181 | run() {
182 | _tests();
183 | }
184 | }
185 |
186 | class ViewTestNotes {
187 |
188 | static String NOTE_1 = "ViewTest/note/name/1";
189 | static String NOTE_2 = "ViewTest/note/name/2";
190 | static String NOTE_3 = "ViewTest/note/name/3";
191 | }
192 |
193 | class ViewTestViewComponent
194 | {
195 | bool onRegisterCalled = false;
196 | bool onRemoveCalled = false;
197 | bool listNotificationInterestsCalled = false;
198 | bool handleNotificationCalled = false;
199 | }
200 |
201 | class ViewTestMediator extends mvc.Mediator
202 | {
203 | // Name Mediator will be registered as
204 | static String NAME = "ViewTestMediator";
205 |
206 | // Constructor
207 | ViewTestMediator( ViewTestViewComponent viewComponent ):super( NAME, viewComponent ){}
208 |
209 | // Accessors that cast viewComponent to the correct type for this Mediator
210 | ViewTestViewComponent get vc { return viewComponent; }
211 | void set vc( ViewTestViewComponent viewTestViewComponent ) { viewComponent = viewTestViewComponent; }
212 |
213 | // Called when Mediator is registered
214 | void onRegister()
215 | {
216 | vc.onRegisterCalled = true;
217 | }
218 |
219 | // Also called when Mediator is registered
220 | List listNotificationInterests()
221 | {
222 | vc.listNotificationInterestsCalled = true;
223 | return [ ViewTestNotes.NOTE_1,
224 | ViewTestNotes.NOTE_2,
225 | ViewTestNotes.NOTE_3 ];
226 | }
227 |
228 | // Called when a notification this Mediator is interested in is sent
229 | void handleNotification( mvc.INotification note )
230 | {
231 | vc.handleNotificationCalled = true;
232 | }
233 |
234 | // Called when Mediator is removed
235 | void onRemove()
236 | {
237 | vc.onRemoveCalled = true;
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/test/Unit_Tests.css:
--------------------------------------------------------------------------------
1 |
2 | body {
3 | background-color: #F8F8F8;
4 | font-family: 'Open Sans', sans-serif;
5 | font-size: 16px;
6 | font-weight: normal;
7 | line-height: 1.2em;
8 | margin: 15px;
9 | }
10 |
11 | p {
12 | color: #333;
13 | }
14 |
15 | #container {
16 | width: 100%;
17 | height: 1600px;
18 | position: relative;
19 | border: 1px solid #ccc;
20 | background-color: #fff;
21 | }
22 |
23 | #text {
24 | font-size: 24pt;
25 | text-align: center;
26 | margin-top: 140px;
27 | }
28 |
--------------------------------------------------------------------------------
/test/Unit_Tests.dart:
--------------------------------------------------------------------------------
1 | // PureMVC Unit Test Library
2 | library puremvc_unit_tests;
3 |
4 | // DART HTML Library
5 | import 'dart:html';
6 |
7 | // The Unit Testing Framework for Dart
8 | import 'package:unittest/unittest.dart';
9 | import 'package:unittest/html_enhanced_config.dart';
10 |
11 | // PureMVC Framework for Dart
12 | import 'package:puremvc/puremvc.dart' as mvc;
13 |
14 | // PureMVC Unit Tests
15 | part 'Test_Notification.dart';
16 | part 'Test_Observer.dart';
17 | part 'Test_SimpleCommand.dart';
18 | part 'Test_MacroCommand.dart';
19 | part 'Test_Proxy.dart';
20 | part 'Test_Mediator.dart';
21 | part 'Test_Model.dart';
22 | part 'Test_View.dart';
23 | part 'Test_Controller.dart';
24 | part 'Test_Facade.dart';
25 |
26 | class Unit_Tests
27 | {
28 | Unit_Tests()
29 | {
30 | // unittestConfiguration = new Unit_Tests_Config();
31 | useHtmlEnhancedConfiguration();
32 | }
33 |
34 | void onTestResult( TestCase testCase ) {
35 | write( "${testCase.result} ${testCase.currentGroup}" );
36 |
37 | }
38 |
39 | void write(String message) {
40 | document.querySelector('#status').innerHtml = message;
41 | }
42 |
43 | void run() {
44 |
45 | // Now, run the PureMVC Tests
46 | new Test_Notification().run();
47 | new Test_Observer().run();
48 | new Test_SimpleCommand().run();
49 | new Test_MacroCommand().run();
50 | new Test_Proxy().run();
51 | new Test_Mediator().run();
52 | new Test_Model().run();
53 | new Test_View().run();
54 | new Test_Controller().run();
55 | new Test_Facade().run();
56 | }
57 | }
58 |
59 |
60 | /**
61 | * Application entry point.
62 | */
63 | void main()
64 | {
65 | // Unit test program, reporting for duty!
66 | new Unit_Tests().run();
67 | }
--------------------------------------------------------------------------------
/test/Unit_Tests.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PureMVC MultiCore Framework for Dart - Unit Tests
6 |
7 |
8 |
9 |