defacer 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Defacer::Namer do
4
+ it 'should start with a' do
5
+ expect(Defacer::Namer.name_var_at_index(0)).to eq('a')
6
+ end
7
+
8
+ it 'should end at z' do
9
+ expect(Defacer::Namer.name_var_at_index(25)).to eq('z')
10
+ end
11
+
12
+ it 'should continue to aa' do
13
+ expect(Defacer::Namer.name_var_at_index(26)).to eq('aa')
14
+ end
15
+
16
+ it 'should go through az' do
17
+ expect(Defacer::Namer.name_var_at_index(51)).to eq('az')
18
+ end
19
+
20
+ it 'should then use ba' do
21
+ expect(Defacer::Namer.name_var_at_index(52)).to eq('ba')
22
+ end
23
+
24
+ it 'should cycle on to ca' do
25
+ expect(Defacer::Namer.name_var_at_index(78)).to eq('ca')
26
+ end
27
+
28
+ it 'should take a while to get to three letter names', focus: true do
29
+ expect(Defacer::Namer.name_var_at_index(27 * 26)).to eq('aaa')
30
+ end
31
+ end
@@ -1,28 +1,165 @@
1
+ require 'execjs'
1
2
  require 'spec_helper'
3
+
2
4
  describe Defacer do
3
- it 'should echo back a simple expression' do
4
- expression = '1 + 1;'
5
+
6
+ let(:example_google_maps) { IO.read 'spec/fixtures/google_maps_example.js' }
7
+
8
+ it 'should be able to handle some moderately complex js' do
9
+ expect { Defacer.compress example_google_maps }.to_not raise_error(Exception)
10
+ end
11
+
12
+ let(:example_jquery) { IO.read 'spec/fixtures/jquery-2.1.1.js' }
13
+
14
+ it 'should be able to handle some very complex js' do
15
+ expect { Defacer.compress example_jquery }.to_not raise_error(Exception)
16
+ end
17
+
18
+ it 'should echo back an unminifiable expression' do
19
+ expression = '1+1;'
5
20
  expect(Defacer.compress expression).to eq(expression)
6
21
  end
7
22
 
8
23
  it 'should remove newlines' do
9
- expect(Defacer.compress "1 + 1;\n2 + 2").to eq("1 + 1;2 + 2;")
24
+ expect(Defacer.compress "1 + 1;\n2 + 2").to eq("1+1;2+2;")
10
25
  end
11
26
 
12
27
  it 'should remove all whitespace in functions' do
13
28
  function = "function double(x){\n return x * 2;\n}\n"
14
- expect(Defacer.compress function).to eq("function double(x) {return x * 2;}")
29
+ expect(Defacer.compress function).to eq("function double(a){return a*2;}")
15
30
  end
16
31
 
17
- let(:example_google_maps) { IO.read 'spec/fixtures/google_maps_example.js' }
32
+ it 'should remove whitespace inside object literals' do
33
+ literal = "var mapOptions = {\n zoom: 3,\n center: chicago\n};"
34
+ minified = "var mapOptions={zoom:3,center:chicago};"
35
+ expect(Defacer.compress literal).to eq(minified)
36
+ end
18
37
 
19
- it 'should be able to handle some moderately complex js' do
20
- expect { Defacer.compress example_google_maps }.to_not raise_error(Exception)
38
+ it 'should remove spaces in var assignment statements' do
39
+ assignment = "var meaningOfLife = 42;"
40
+ minified = "var meaningOfLife=42;"
41
+ expect(Defacer.compress assignment).to eq(minified)
21
42
  end
22
43
 
23
- let(:example_jquery) { IO.read 'spec/fixtures/jquery-2.1.1.js' }
44
+ it 'should remove spaces in reassignments' do
45
+ reassignment = "meaningOfLife = 42;"
46
+ minified = "meaningOfLife=42;"
47
+ expect(Defacer.compress reassignment).to eq(minified)
48
+ end
24
49
 
25
- it 'should be able to handle some very complex js' do
26
- expect { Defacer.compress example_jquery }.to_not raise_error(Exception)
50
+ it 'should remove spaces from function call argument lists' do
51
+ fn_call = "foo(a, 'b', 10);"
52
+ minified = "foo(a,'b',10);"
53
+ expect(Defacer.compress fn_call).to eq(minified)
54
+ end
55
+
56
+ it 'should remove spaces from function decl argument lists' do
57
+ fn_decl = "function bar(x, y) {return x - y;}"
58
+ minified = "function bar(a,b){return a-b;}"
59
+ expect(Defacer.compress fn_decl).to eq(minified)
60
+ end
61
+
62
+ it 'should remove spaces between binary operators' do
63
+ expect(Defacer.compress 'a + b;').to eq('a+b;')
64
+ expect(Defacer.compress 'a - b;').to eq('a-b;')
65
+ expect(Defacer.compress 'a * b;').to eq('a*b;')
66
+ expect(Defacer.compress 'a / b;').to eq('a/b;')
67
+ end
68
+
69
+ it 'should remove whitespace in array literals' do
70
+ array = "var arr = ['1', 2, a,\n b,'c'];"
71
+ minified = "var arr=['1',2,a,b,'c'];"
72
+ expect(Defacer.compress array).to eq(minified)
73
+ end
74
+
75
+ it 'should remove whitespace in variable lists' do
76
+ assignments = "var a = 42, b = 43;"
77
+ minified = "var a=42,b=43;"
78
+ expect(Defacer.compress assignments).to eq(minified)
27
79
  end
80
+
81
+ it 'should remove whitespace in if...else statements' do
82
+ if_else = 'if (2 > 1) { return x; } else { return 99; }'
83
+ minified = 'if(2>1){return x;}else {return 99;}'
84
+ expect(Defacer.compress if_else).to eq(minified)
85
+ end
86
+
87
+ it 'should remove whitespace in for statements' do
88
+ for_statement = 'for (var i = 0; i < 12; i += 1) { x = x + i; }'
89
+ minified = 'for(var i=0;i<12;i+=1){x=x+i;}'
90
+ expect(Defacer.compress for_statement).to eq(minified)
91
+ end
92
+
93
+ it 'should rename local variables' do
94
+ js = 'function fooBar(){ var localA = 2; return localA + 2; }'
95
+ minified = 'function fooBar(){var a=2;return a+2;}'
96
+ expect(Defacer.compress js).to eq(minified)
97
+ end
98
+
99
+ it 'should rename local variables, but not global variables' do
100
+ js = 'var globalA = 1; function fooBar(){ var localA = 2; var localB = function(){ var localC = 3; return globalA + localA + localC + 5;}(); return localA + localB; }';
101
+ minified = 'var globalA=1;function fooBar(){var a=2;var b=function(){var c=3;return globalA+a+c+5;}();return a+b;}';
102
+ expect(Defacer.compress js).to eq(minified)
103
+ end
104
+
105
+ it 'should recycle bound var names in sibling functions' do
106
+ js = 'function foo(){ var localA = 2; return localA + 2; };function bar(){ var localB = 4; return localB + 4; }'
107
+ minified = 'function foo(){var a=2;return a+2;};function bar(){var a=4;return a+4;}'
108
+ expect(Defacer.compress js).to eq(minified)
109
+ end
110
+
111
+ it 'does not mix variable name bindings across sibling blocks' do
112
+ js = 'function alpha(){ var foo = 1, bar = 2, baz = 3, quux = 4; return foo*bar*baz*quux; };function beta(){ var baz = 4, quux = 9; return quux - baz; }'
113
+ minified = 'function alpha(){var a=1,b=2,c=3,d=4;return a*b*c*d;};function beta(){var a=4,b=9;return b-a;}'
114
+ expect(Defacer.compress js).to eq(minified)
115
+ end
116
+
117
+ let(:hella_variable_names) { IO.read 'spec/fixtures/hella_variable_names.js' }
118
+
119
+ it 'should be able to shorten more than 26 variable names' do
120
+ compressed = Defacer.compress(hella_variable_names)
121
+ # Look for two-char names like aa, ab
122
+ expect(compressed).to match(/aa/)
123
+ expect(compressed).to match(/ab/)
124
+ end
125
+
126
+ it 'will not shorten local names even if var keyword is omitted' do
127
+ js = 'var x = function(){veryLongVarName = 2; var otherLongVarName = 5; return veryLongVarName + otherLongVarName;}()'
128
+ minified = 'var x=function(){veryLongVarName=2;var a=5;return veryLongVarName+a;}();'
129
+ expect(Defacer.compress js).to eq(minified)
130
+ end
131
+
132
+ it 'should correctly shorten shadowed names' do
133
+ js = "var result = function(){var foo = 2, bar = 3; return function(){var bar = 9; return bar + 1;}() + foo + bar;}();"
134
+ minified = "var result=function(){var a=2,b=3;return function(){var c=9;return c+1;}()+a+b;}();"
135
+ expect(Defacer.compress js).to eq(minified)
136
+ # TODO actually run the minified JS!
137
+ end
138
+
139
+ it 'should correctly shorted shadowed names in function parameters' do
140
+ js = "var result = function(){var foo = 2, bar = 3; return function(bar){return bar + 1;}(foo) + foo + bar;}();"
141
+ minified = "var result=function(){var a=2,b=3;return function(c){return c+1;}(a)+a+b;}();"
142
+ expect(Defacer.compress js).to eq(minified)
143
+
144
+ # Actually run the JS to make sure the transformation is safe
145
+ expect(ExecJS.compile(js).eval('result')).to eq(8) # precondition
146
+ expect(ExecJS.compile(minified).eval('result')).to eq(8) # our version
147
+ end
148
+
149
+ let(:example_underscore) { IO.read 'spec/fixtures/underscore.js' }
150
+
151
+ it 'should correctly minify underscore', focus: true do
152
+ minified = Defacer.compress(example_underscore)
153
+ compiled = ExecJS.compile(minified)
154
+ result = compiled.eval('_.max([1, 42, 3, 9, 0])')
155
+ expect(result).to eq(42)
156
+ end
157
+
158
+ # TODO improve angular, worst minification of examples
159
+ # TODO rename functions declared like function fooBar(){} if they are not at global scope
160
+
161
+
162
+ # TODO still a lot of extra whitespace
163
+
164
+ it 'should remove unused code' # yikes!
28
165
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: defacer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bradley Buda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-12 00:00:00.000000000 Z
11
+ date: 2014-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rkelly-remix
@@ -80,6 +80,48 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '4.2'
83
+ - !ruby/object:Gem::Dependency
84
+ name: closure-compiler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: terminal-table
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.4'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.4'
111
+ - !ruby/object:Gem::Dependency
112
+ name: uglifier
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.5'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.5'
83
125
  description: Favors speed over size of minified JS, works on any ruby platform, works
84
126
  well with the Rails asset pipeline and Sprockets
85
127
  email:
@@ -96,11 +138,17 @@ files:
96
138
  - LICENSE.txt
97
139
  - README.md
98
140
  - Rakefile
141
+ - benchmark.rb
99
142
  - defacer.gemspec
100
143
  - lib/defacer.rb
144
+ - lib/defacer/namer.rb
101
145
  - lib/defacer/version.rb
146
+ - spec/fixtures/angular.js
102
147
  - spec/fixtures/google_maps_example.js
148
+ - spec/fixtures/hella_variable_names.js
103
149
  - spec/fixtures/jquery-2.1.1.js
150
+ - spec/fixtures/underscore.js
151
+ - spec/lib/defacer/namer_spec.rb
104
152
  - spec/lib/defacer_spec.rb
105
153
  - spec/spec_helper.rb
106
154
  homepage: https://github.com/meldium/defacer
@@ -128,8 +176,12 @@ signing_key:
128
176
  specification_version: 4
129
177
  summary: Pure-ruby JavaScript minifier
130
178
  test_files:
179
+ - spec/fixtures/angular.js
131
180
  - spec/fixtures/google_maps_example.js
181
+ - spec/fixtures/hella_variable_names.js
132
182
  - spec/fixtures/jquery-2.1.1.js
183
+ - spec/fixtures/underscore.js
184
+ - spec/lib/defacer/namer_spec.rb
133
185
  - spec/lib/defacer_spec.rb
134
186
  - spec/spec_helper.rb
135
187
  has_rdoc: