commandz 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.jasmine-headless-webkit +2 -0
- data/Gemfile +2 -0
- data/Guardfile +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +200 -0
- data/Rakefile +49 -0
- data/commandz.gemspec +21 -0
- data/commandz.min.js +10 -0
- data/config/jasmine.yml +10 -0
- data/lib/assets/javascripts/commandz.coffee +50 -0
- data/lib/commandz.rb +2 -0
- data/lib/commandz/engine.rb +3 -0
- data/lib/commandz/version.rb +3 -0
- data/lib/tasks/task_helpers.rb +18 -0
- data/spec/commandz_spec.coffee +118 -0
- data/spec/fixtures/spec_container.html +1 -0
- data/spec/helpers/spec_helper.coffee +1 -0
- data/vendor/jasmine-jquery.js +673 -0
- data/vendor/jquery.js +9789 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 702744b575b0c129c8031ffb874531ccabc57686
|
4
|
+
data.tar.gz: fcd2c78539f793ce8ca8d2724bcd00a03e234d95
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 49f382728b5c447021de95d10e8b7ed1a6a6386592dfd1945fda902933962fd7c99149008a4332331235ff9ab03bb499c726952cd0a9dcc06c0b872b8ba0a596
|
7
|
+
data.tar.gz: c349a981e728cb17c0b8fb885e4bec53d545367c9e1def72e37f833d30a112d4a949d40995df85542731a9f55d6887cbf44d8d992d932e35b3087c9a23adfbb8
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
spec_location = "spec/%s_spec"
|
2
|
+
|
3
|
+
guard 'jasmine-headless-webkit' do
|
4
|
+
watch(%r{^lib/assets/javascripts/(.*)\.coffee$}) { |m| newest_js_file(spec_location % m[1]) }
|
5
|
+
watch(%r{^spec/(.*)_spec\..*}) { |m| newest_js_file(spec_location % m[1]) }
|
6
|
+
watch(%r{spec/fixtures/.+$})
|
7
|
+
end
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Etienne Lemay
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
<p align="center">
|
2
|
+
<a href="https://github.com/EtienneLem/commandz">
|
3
|
+
<img src="https://f.cloud.github.com/assets/436043/1047139/032acfc8-1059-11e3-8baa-d22caee7e517.png">
|
4
|
+
</a>
|
5
|
+
</p>
|
6
|
+
|
7
|
+
<p align="center">
|
8
|
+
<strong>CommandZ</strong> undo and redo commands.<br>
|
9
|
+
Add commands history support to your web app.
|
10
|
+
</p>
|
11
|
+
|
12
|
+
<p align="center">
|
13
|
+
<a href="http://badge.fury.io/rb/commandz"><img src="https://badge.fury.io/rb/commandz@2x.png" alt="Gem Version" height="18"></a>
|
14
|
+
</p>
|
15
|
+
|
16
|
+
## API
|
17
|
+
#### Glossary
|
18
|
+
```js
|
19
|
+
COMMANDS: An Array of COMMAND
|
20
|
+
COMMAND: {
|
21
|
+
up: function() {},
|
22
|
+
down: function() {}
|
23
|
+
}
|
24
|
+
```
|
25
|
+
|
26
|
+
### execute
|
27
|
+
Receive `COMMAND` or `COMMANDS` and execute `COMMAND.up()`.
|
28
|
+
|
29
|
+
**Single command per history item**<br>
|
30
|
+
Store one history item per `COMMAND`.
|
31
|
+
|
32
|
+
```js
|
33
|
+
CommandZ.execute({
|
34
|
+
up: function() { console.log('up 1') },
|
35
|
+
down: function() { console.log('down 1') }
|
36
|
+
}) // => up 1
|
37
|
+
|
38
|
+
CommandZ.execute({
|
39
|
+
up: function() { console.log('up 2') },
|
40
|
+
down: function() { console.log('down 2') }
|
41
|
+
}) // => up 2
|
42
|
+
|
43
|
+
console.log(CommandZ.commands.length) // => 2
|
44
|
+
console.log(CommandZ.index) // => 1
|
45
|
+
```
|
46
|
+
|
47
|
+
**Multiple commands per history item**<br>
|
48
|
+
Store one history item per `COMMAND` group (`COMMANDS`).<br>
|
49
|
+
A *single* undo would go back through *all* of the `COMMAND` inside `COMMANDS`.
|
50
|
+
|
51
|
+
```js
|
52
|
+
commands = []
|
53
|
+
for (var i=1; i <= 5; i++) {
|
54
|
+
commands.push({
|
55
|
+
up: function() { 'up 1.' + i },
|
56
|
+
down: function() { 'down 1.' + i }
|
57
|
+
})
|
58
|
+
}
|
59
|
+
|
60
|
+
CommandZ.execute(commands) // => up 1.1, up 1.2, up 1.3, up 1.4, up 1.5
|
61
|
+
|
62
|
+
console.log(CommandZ.commands.length) // => 1
|
63
|
+
console.log(CommandZ.index) // => 0
|
64
|
+
```
|
65
|
+
|
66
|
+
### undo
|
67
|
+
Call `COMMAND.down()` and set the index to the previous command.
|
68
|
+
|
69
|
+
```js
|
70
|
+
CommandZ.execute({
|
71
|
+
up: function() { console.log('up 1') },
|
72
|
+
down: function() { console.log('down 1') }
|
73
|
+
}) // => up 1
|
74
|
+
|
75
|
+
CommandZ.execute({
|
76
|
+
up: function() { console.log('up 2') },
|
77
|
+
down: function() { console.log('down 2') }
|
78
|
+
}) // => up 2
|
79
|
+
|
80
|
+
CommandZ.undo() // => down 2
|
81
|
+
|
82
|
+
console.log(CommandZ.commands.length) // => 2
|
83
|
+
console.log(CommandZ.index) // => 0
|
84
|
+
|
85
|
+
CommandZ.undo() // => down 1
|
86
|
+
|
87
|
+
console.log(CommandZ.commands.length) // => 2
|
88
|
+
console.log(CommandZ.index) // => -1
|
89
|
+
```
|
90
|
+
|
91
|
+
### redo
|
92
|
+
Set the index to the next command and call `COMMAND.up()`.
|
93
|
+
|
94
|
+
```js
|
95
|
+
CommandZ.execute({
|
96
|
+
up: function() { console.log('up 1') },
|
97
|
+
down: function() { console.log('down 1') }
|
98
|
+
}) // => up 1
|
99
|
+
|
100
|
+
CommandZ.execute({
|
101
|
+
up: function() { console.log('up 2') },
|
102
|
+
down: function() { console.log('down 2') }
|
103
|
+
}) // => up 2
|
104
|
+
|
105
|
+
CommandZ.undo(2) // => down 2, down 1
|
106
|
+
CommandZ.redo() // => up 1
|
107
|
+
|
108
|
+
console.log(CommandZ.commands.length) // => 2
|
109
|
+
console.log(CommandZ.index) // => 0
|
110
|
+
```
|
111
|
+
|
112
|
+
### status
|
113
|
+
Return the current `COMMAND`.
|
114
|
+
|
115
|
+
```js
|
116
|
+
CommandZ.execute({
|
117
|
+
up: function() { console.log('up 1') },
|
118
|
+
down: function() { console.log('down 1') }
|
119
|
+
}) // => up 1
|
120
|
+
|
121
|
+
CommandZ.execute({
|
122
|
+
up: function() { console.log('up 2') },
|
123
|
+
down: function() { console.log('down 2') }
|
124
|
+
}) // => up 2
|
125
|
+
|
126
|
+
console.log(CommandZ.status()) // => { up: function() { console.log('up 2') }, down: function() { console.log('down 2') } }
|
127
|
+
console.log(CommandZ.commands.length) // => 2
|
128
|
+
console.log(CommandZ.index) // => 1
|
129
|
+
```
|
130
|
+
|
131
|
+
### clear
|
132
|
+
Clear history.
|
133
|
+
|
134
|
+
```js
|
135
|
+
CommandZ.execute({
|
136
|
+
up: function() { console.log('up 1') },
|
137
|
+
down: function() { console.log('down 1') }
|
138
|
+
}) // => up 1
|
139
|
+
|
140
|
+
CommandZ.execute({
|
141
|
+
up: function() { console.log('up 2') },
|
142
|
+
down: function() { console.log('down 2') }
|
143
|
+
}) // => up 2
|
144
|
+
|
145
|
+
CommandZ.clear()
|
146
|
+
|
147
|
+
console.log(CommandZ.status()) // => undefined
|
148
|
+
console.log(CommandZ.commands.length) // => 0
|
149
|
+
console.log(CommandZ.index) // => -1
|
150
|
+
```
|
151
|
+
|
152
|
+
## DOM Example
|
153
|
+
```js
|
154
|
+
// This example requires jQuery or Zepto
|
155
|
+
$container = $('<div></div>')
|
156
|
+
|
157
|
+
// Lets do 5 commands
|
158
|
+
[1, 2, 3, 4, 5].forEach(function(i) {
|
159
|
+
var $i = $('<i>' + i + '</i>')
|
160
|
+
CommandZ.execute({
|
161
|
+
up: function() { $container.append($i) },
|
162
|
+
down: function() { $i.detach() } // When removing DOM elements, I highly recommend .detach()
|
163
|
+
})
|
164
|
+
})
|
165
|
+
|
166
|
+
console.log($container.html()) // => <i>1</i><i>2</i><i>3</i><i>4</i><i>5</i>
|
167
|
+
|
168
|
+
// Undo
|
169
|
+
CommandZ.undo()
|
170
|
+
console.log($container.html()) // => <i>1</i><i>2</i><i>3</i><i>4</i>
|
171
|
+
|
172
|
+
// Redo
|
173
|
+
CommandZ.redo()
|
174
|
+
console.log($container.html()) // => <i>1</i><i>2</i><i>3</i><i>4</i><i>5</i>
|
175
|
+
|
176
|
+
// When undoing, a new command will overwrite all upcoming commands
|
177
|
+
CommandZ.undo(3)
|
178
|
+
|
179
|
+
$i = $('<i>1337</i>')
|
180
|
+
CommandZ.execute({
|
181
|
+
up: function() { $container.append($i) },
|
182
|
+
down: function() { $i.detach() }
|
183
|
+
})
|
184
|
+
|
185
|
+
console.log($container.html()) // => <i>1</i><i>2</i><i>1337</i>
|
186
|
+
console.log(CommandZ.commands.length) // => 3
|
187
|
+
console.log(CommandZ.index) // => 2
|
188
|
+
```
|
189
|
+
|
190
|
+
## Setup
|
191
|
+
### Rails
|
192
|
+
1. Add `gem 'commandz'` to your Gemfile.
|
193
|
+
2. Add `//= require commandz` to your JavaScript manifest file.
|
194
|
+
3. Restart your server and `CMD+Z` - `CMD+SHIFT+Z` away!
|
195
|
+
|
196
|
+
### Other
|
197
|
+
Download and include [commandz.min.js](https://raw.github.com/EtienneLem/commandz/master/commandz.min.js) in your HTML pages.
|
198
|
+
|
199
|
+
## Tests
|
200
|
+
Run the `rake spec` task or `bundle exec guard` for continuous testing.
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), *%w[lib])
|
2
|
+
require 'tasks/task_helpers'
|
3
|
+
|
4
|
+
# Rubygems
|
5
|
+
require 'bundler'
|
6
|
+
Bundler::GemHelper.install_tasks
|
7
|
+
|
8
|
+
# Dependencies
|
9
|
+
require 'uglifier'
|
10
|
+
require 'commandz'
|
11
|
+
require 'sprockets'
|
12
|
+
|
13
|
+
# Tasks
|
14
|
+
desc 'Merge, compiles and minify CoffeeScript files'
|
15
|
+
task :compile do
|
16
|
+
@environment = Sprockets::Environment.new
|
17
|
+
@environment.append_path 'lib/assets/javascripts'
|
18
|
+
@environment.js_compressor = Uglifier.new(mangle: true)
|
19
|
+
|
20
|
+
compile('commandz.js')
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'run Jasmine specs'
|
24
|
+
task :spec do
|
25
|
+
system('bundle exec jasmine-headless-webkit')
|
26
|
+
end
|
27
|
+
|
28
|
+
# Helpers
|
29
|
+
def compile(file)
|
30
|
+
minjs = @environment[file].to_s
|
31
|
+
out = "#{file.sub('.js', '.min.js')}"
|
32
|
+
|
33
|
+
File.open(out, 'w') { |f| f.write(copyright + minjs + "\n") }
|
34
|
+
success "Compiled #{out}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def copyright
|
38
|
+
@copyright ||= <<-EOS
|
39
|
+
/*
|
40
|
+
* CommandZ v#{CommandZ::VERSION}
|
41
|
+
* https://github.com/EtienneLem/commandz
|
42
|
+
*
|
43
|
+
* Copyright 2013, Etienne Lemay http://heliom.ca
|
44
|
+
* Released under the MIT license
|
45
|
+
*
|
46
|
+
* Date: #{Time.now}
|
47
|
+
*/
|
48
|
+
EOS
|
49
|
+
end
|
data/commandz.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require './lib/commandz/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'commandz'
|
5
|
+
s.version = CommandZ::VERSION
|
6
|
+
s.authors = ['Etienne Lemay']
|
7
|
+
s.email = ['etienne@heliom.ca']
|
8
|
+
s.homepage = 'https://github.com/EtienneLem/commandz'
|
9
|
+
s.summary = 'CommandZ undo and redo commands'
|
10
|
+
s.license = 'MIT'
|
11
|
+
|
12
|
+
s.files = `git ls-files`.split($/)
|
13
|
+
s.test_files = s.files.grep(%r{^(spec)/})
|
14
|
+
|
15
|
+
s.add_development_dependency 'rake'
|
16
|
+
s.add_development_dependency 'jasmine'
|
17
|
+
s.add_development_dependency 'uglifier'
|
18
|
+
s.add_development_dependency 'sprockets'
|
19
|
+
s.add_development_dependency 'jasmine-headless-webkit'
|
20
|
+
s.add_development_dependency 'guard-jasmine-headless-webkit'
|
21
|
+
end
|
data/commandz.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
/*
|
2
|
+
* CommandZ v0.0.1
|
3
|
+
* https://github.com/EtienneLem/commandz
|
4
|
+
*
|
5
|
+
* Copyright 2013, Etienne Lemay http://heliom.ca
|
6
|
+
* Released under the MIT license
|
7
|
+
*
|
8
|
+
* Date: 2013-08-28 23:28:40 -0400
|
9
|
+
*/
|
10
|
+
(function(){var t;t=function(){function t(){this.VERSION="0.0.1",this.clear()}return t.prototype.clear=function(){return this.commands=[],this.index=-1},t.prototype.execute=function(t){var n;return this.up(t),this.index<this.commands.length-1&&(n=this.commands.length-this.index-1,this.commands.splice(-n)),this.commands.push(t),this.index=this.commands.length-1},t.prototype.undo=function(t){var n,i;if(null==t&&(t=1),!(this.index<0))for(n=i=1;t>=1?t>=i:i>=t;n=t>=1?++i:--i){if(!this.commands[this.index])return;this.down(this.commands[this.index]),this.index--}},t.prototype.redo=function(t){var n,i;if(null==t&&(t=1),!(this.index>=this.commands.length-1))for(n=i=1;t>=1?t>=i:i>=t;n=t>=1?++i:--i){if(!this.commands[this.index+1])return;this.index++,this.up(this.commands[this.index])}},t.prototype.exec=function(t,n){var i,s,e,o;if(!(n instanceof Array))return n[t]();for(o=[],s=0,e=n.length;e>s;s++)i=n[s],o.push(i[t]());return o},t.prototype.up=function(t){return this.exec("up",t)},t.prototype.down=function(t){return this.exec("down",t)},t.prototype.status=function(){return this.commands[this.index]},t}(),this.CommandZ=new t}).call(this);
|
data/config/jasmine.yml
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
class CommandZ
|
2
|
+
|
3
|
+
constructor: ->
|
4
|
+
@VERSION = '0.0.1'
|
5
|
+
this.clear()
|
6
|
+
|
7
|
+
clear: ->
|
8
|
+
@commands = []
|
9
|
+
@index = -1
|
10
|
+
|
11
|
+
execute: (command) ->
|
12
|
+
this.up(command)
|
13
|
+
|
14
|
+
# Overwrites following commands (if @index < @commands.length)
|
15
|
+
if (@index < @commands.length - 1)
|
16
|
+
difference = (@commands.length - @index) - 1
|
17
|
+
@commands.splice(-difference)
|
18
|
+
|
19
|
+
# Push new command
|
20
|
+
@commands.push(command)
|
21
|
+
@index = @commands.length - 1
|
22
|
+
|
23
|
+
undo: (times=1) ->
|
24
|
+
return if @index < 0
|
25
|
+
for i in [1..times]
|
26
|
+
return unless @commands[@index]
|
27
|
+
this.down(@commands[@index])
|
28
|
+
@index--
|
29
|
+
|
30
|
+
redo: (times=1) ->
|
31
|
+
return if @index >= @commands.length - 1
|
32
|
+
for i in [1..times]
|
33
|
+
return unless @commands[@index + 1]
|
34
|
+
@index++
|
35
|
+
this.up(@commands[@index])
|
36
|
+
|
37
|
+
# Execute up/down on a command
|
38
|
+
# command can be a group of commands or a single command
|
39
|
+
exec: (action, command) ->
|
40
|
+
return command[action]() unless command instanceof Array
|
41
|
+
c[action]() for c in command
|
42
|
+
|
43
|
+
up: (command) -> this.exec('up', command)
|
44
|
+
down: (command) -> this.exec('down', command)
|
45
|
+
|
46
|
+
# Return current command
|
47
|
+
status: -> @commands[@index]
|
48
|
+
|
49
|
+
# Singleton
|
50
|
+
@CommandZ = new CommandZ
|
data/lib/commandz.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
def colorize(text, color_code)
|
2
|
+
"\e[#{color_code}m#{text}\e[0m"
|
3
|
+
end
|
4
|
+
|
5
|
+
{ # See: http://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/
|
6
|
+
31 => 'red',
|
7
|
+
32 => 'green',
|
8
|
+
33 => 'yellow',
|
9
|
+
34 => 'blue',
|
10
|
+
35 => 'magenta',
|
11
|
+
36 => 'cyan',
|
12
|
+
}.each do |code, color|
|
13
|
+
Kernel.send(:define_method, color) { |text| colorize(text, code) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def error(text); puts red('ERROR: ') + text; end
|
17
|
+
def success(text); puts green('SUCCESS: ') + text; end
|
18
|
+
def warn(text); puts yellow('WARNING: ') + text; end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
describe 'CommandZ', ->
|
2
|
+
describe 'unit', ->
|
3
|
+
it 'stores commands', ->
|
4
|
+
[0..9].forEach (i) -> CommandZ.execute({up: (-> i), down: (-> i)})
|
5
|
+
|
6
|
+
expect(CommandZ.commands.length).toBe(10)
|
7
|
+
expect(CommandZ.index).toBe(9)
|
8
|
+
|
9
|
+
it 'undo', ->
|
10
|
+
[0..3].forEach -> CommandZ.undo()
|
11
|
+
|
12
|
+
expect(CommandZ.commands.length).toBe(10)
|
13
|
+
expect(CommandZ.index).toBe(5)
|
14
|
+
|
15
|
+
it 'redo', ->
|
16
|
+
CommandZ.redo()
|
17
|
+
|
18
|
+
expect(CommandZ.commands.length).toBe(10)
|
19
|
+
expect(CommandZ.index).toBe(6)
|
20
|
+
|
21
|
+
it 'undo many times', ->
|
22
|
+
CommandZ.undo(3)
|
23
|
+
expect(CommandZ.commands.length).toBe(10)
|
24
|
+
expect(CommandZ.index).toBe(3)
|
25
|
+
|
26
|
+
CommandZ.undo(100)
|
27
|
+
expect(CommandZ.commands.length).toBe(10)
|
28
|
+
expect(CommandZ.index).toBe(-1)
|
29
|
+
|
30
|
+
it 'redo many times', ->
|
31
|
+
CommandZ.redo(3)
|
32
|
+
expect(CommandZ.commands.length).toBe(10)
|
33
|
+
expect(CommandZ.index).toBe(2)
|
34
|
+
|
35
|
+
CommandZ.redo(100)
|
36
|
+
expect(CommandZ.commands.length).toBe(10)
|
37
|
+
expect(CommandZ.index).toBe(9)
|
38
|
+
|
39
|
+
it 'returns current command', ->
|
40
|
+
currentCommand = CommandZ.status()
|
41
|
+
expect(currentCommand.up()).toBe(9)
|
42
|
+
|
43
|
+
it 'overwrites upcoming commands', ->
|
44
|
+
CommandZ.undo(3)
|
45
|
+
CommandZ.execute({up: (->), down: (->)})
|
46
|
+
|
47
|
+
expect(CommandZ.commands.length).toBe(8)
|
48
|
+
expect(CommandZ.index).toBe(7)
|
49
|
+
|
50
|
+
it 'clears commands', ->
|
51
|
+
CommandZ.clear()
|
52
|
+
|
53
|
+
expect(CommandZ.commands.length).toBe(0)
|
54
|
+
expect(CommandZ.index).toBe(-1)
|
55
|
+
|
56
|
+
it 'stores grouped commands', ->
|
57
|
+
CommandZ.execute([{up: (->), down: (->)}, {up: (->), down: (->)}])
|
58
|
+
CommandZ.undo()
|
59
|
+
CommandZ.redo()
|
60
|
+
|
61
|
+
expect(CommandZ.commands.length).toBe(1)
|
62
|
+
expect(CommandZ.commands[0].length).toBe(2)
|
63
|
+
|
64
|
+
expect(CommandZ.index).toBe(0)
|
65
|
+
|
66
|
+
describe 'integration', ->
|
67
|
+
$container = null
|
68
|
+
|
69
|
+
beforeEach ->
|
70
|
+
CommandZ.clear()
|
71
|
+
loadFixtures('spec_container.html')
|
72
|
+
|
73
|
+
$container = $('#spec-container')
|
74
|
+
[0..4].forEach ->
|
75
|
+
$test = $('<div class="foo"></div>')
|
76
|
+
CommandZ.execute
|
77
|
+
up: -> $container.append($test)
|
78
|
+
down: -> $test.remove()
|
79
|
+
|
80
|
+
it 'executes commands', ->
|
81
|
+
expect($container.children().length).toBe(5)
|
82
|
+
|
83
|
+
it 'undo', ->
|
84
|
+
CommandZ.undo(3)
|
85
|
+
expect($container.children().length).toBe(2)
|
86
|
+
|
87
|
+
it 'redo', ->
|
88
|
+
CommandZ.undo(3)
|
89
|
+
CommandZ.redo()
|
90
|
+
|
91
|
+
expect($container.children().length).toBe(3)
|
92
|
+
|
93
|
+
it 'overwrites upcoming commands', ->
|
94
|
+
CommandZ.undo(10)
|
95
|
+
CommandZ.redo()
|
96
|
+
|
97
|
+
$bar = $('<div class="bar"></div>')
|
98
|
+
CommandZ.execute
|
99
|
+
up: -> $container.append($bar)
|
100
|
+
down: -> $bar.remove()
|
101
|
+
|
102
|
+
expect($container.html()).toBe('<div class="foo"></div><div class="bar"></div>')
|
103
|
+
|
104
|
+
it 'executes grouped commands', ->
|
105
|
+
$container.html('')
|
106
|
+
commands = []
|
107
|
+
|
108
|
+
[1..3].forEach (i) ->
|
109
|
+
$i = $("<i>#{i}</i>")
|
110
|
+
commands.push
|
111
|
+
up: -> $container.append($i)
|
112
|
+
down: -> $i.remove()
|
113
|
+
|
114
|
+
CommandZ.execute(commands)
|
115
|
+
expect($container.html()).toBe('<i>1</i><i>2</i><i>3</i>')
|
116
|
+
|
117
|
+
CommandZ.undo()
|
118
|
+
expect($container.html()).toBe('')
|