commandz 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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('')
|