fron 0.1.4 → 0.2.0rc1

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.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.reek +11 -0
  4. data/.rubocop.yml +54 -0
  5. data/.travis.yml +11 -0
  6. data/.yardopts +4 -0
  7. data/Changelog.md +7 -0
  8. data/Gemfile +3 -1
  9. data/Gemfile.lock +106 -15
  10. data/Rakefile +19 -15
  11. data/Readme.md +23 -0
  12. data/fron.gemspec +2 -2
  13. data/lib/fron/version.rb +2 -1
  14. data/opal/fron.rb +5 -5
  15. data/opal/fron/core.rb +3 -10
  16. data/opal/fron/core/behaviors/components.rb +42 -0
  17. data/opal/fron/core/behaviors/events.rb +27 -0
  18. data/opal/fron/core/behaviors/routes.rb +59 -0
  19. data/opal/fron/core/component.rb +64 -90
  20. data/opal/fron/core/eventable.rb +18 -0
  21. data/opal/fron/core/logger.rb +10 -1
  22. data/opal/fron/core_ext.rb +9 -0
  23. data/opal/fron/core_ext/array.rb +12 -0
  24. data/opal/fron/core_ext/date.rb +57 -0
  25. data/opal/fron/core_ext/hash.rb +52 -0
  26. data/opal/fron/core_ext/kernel.rb +57 -0
  27. data/opal/fron/core_ext/nil.rb +7 -0
  28. data/opal/fron/core_ext/numeric.rb +19 -0
  29. data/opal/fron/core_ext/object.rb +11 -0
  30. data/opal/fron/core_ext/proc.rb +19 -0
  31. data/opal/fron/{core-ext → core_ext}/string.rb +4 -0
  32. data/opal/fron/dom.rb +15 -13
  33. data/opal/fron/dom/document.rb +22 -6
  34. data/opal/fron/dom/element.rb +105 -67
  35. data/opal/fron/dom/event.rb +110 -40
  36. data/opal/fron/dom/{file-reader.rb → file_reader.rb} +6 -1
  37. data/opal/fron/dom/fragment.rb +2 -0
  38. data/opal/fron/dom/modules/attributes.rb +43 -0
  39. data/opal/fron/dom/modules/classlist.rb +26 -13
  40. data/opal/fron/dom/modules/dimensions.rb +79 -9
  41. data/opal/fron/dom/modules/element_accessor.rb +35 -0
  42. data/opal/fron/dom/modules/events.rb +67 -20
  43. data/opal/fron/dom/node.rb +98 -39
  44. data/opal/fron/dom/nodelist.rb +9 -2
  45. data/opal/fron/dom/style.rb +23 -2
  46. data/opal/fron/dom/text.rb +4 -0
  47. data/opal/fron/dom/window.rb +31 -2
  48. data/opal/fron/event_mock.rb +54 -0
  49. data/opal/fron/js/syntetic_event.js +16 -0
  50. data/opal/fron/request.rb +2 -2
  51. data/opal/fron/request/request.rb +77 -14
  52. data/opal/fron/request/response.rb +33 -6
  53. data/opal/fron/storage.rb +1 -1
  54. data/opal/fron/storage/local_storage.rb +54 -0
  55. data/opal/fron/utils/drag.rb +135 -0
  56. data/opal/fron/utils/keyboard.rb +70 -0
  57. data/opal/fron/utils/point.rb +78 -0
  58. data/opal/fron/utils/render_proc.rb +27 -0
  59. data/spec/core-ext/array_spec.rb +15 -0
  60. data/spec/core-ext/date_spec.rb +54 -0
  61. data/spec/core-ext/hash_spec.rb +18 -2
  62. data/spec/core-ext/kernel_spec.rb +57 -0
  63. data/spec/core-ext/nil_spec.rb +9 -0
  64. data/spec/core-ext/numeric_spec.rb +25 -0
  65. data/spec/core-ext/proc_spec.rb +15 -0
  66. data/spec/core-ext/string_spec.rb +11 -0
  67. data/spec/core/behaviors/events_spec.rb +25 -0
  68. data/spec/core/behaviors/routes_spec.rb +59 -0
  69. data/spec/core/component_inheritance_spec.rb +26 -16
  70. data/spec/core/component_spec.rb +25 -29
  71. data/spec/core/eventable_spec.rb +19 -19
  72. data/spec/core/logger_spec.rb +5 -6
  73. data/spec/dom/document_spec.rb +4 -5
  74. data/spec/dom/element_spec.rb +106 -15
  75. data/spec/dom/event_spec.rb +101 -61
  76. data/spec/dom/file_reader_spec.rb +11 -0
  77. data/spec/dom/fragment_spec.rb +3 -4
  78. data/spec/dom/instance_retaining_spec.rb +58 -0
  79. data/spec/dom/modules/classlist_spec.rb +18 -19
  80. data/spec/dom/modules/dimensions_spec.rb +87 -22
  81. data/spec/dom/modules/events_spec.rb +22 -8
  82. data/spec/dom/node_spec.rb +25 -17
  83. data/spec/dom/nodelist_spec.rb +2 -3
  84. data/spec/dom/style_spec.rb +6 -5
  85. data/spec/dom/text_spec.rb +4 -3
  86. data/spec/dom/window_spec.rb +24 -9
  87. data/spec/js/mocks.js +14 -0
  88. data/spec/request/request_spec.rb +34 -15
  89. data/spec/request/response_spec.rb +9 -10
  90. data/spec/spec_helper.rb +11 -0
  91. data/spec/storage/{local-storage_spec.rb → local_storage_spec.rb} +6 -7
  92. data/spec/utils/drag_spec.rb +136 -0
  93. data/spec/utils/keyboard_spec.rb +75 -0
  94. data/spec/utils/point_spec.rb +55 -0
  95. data/spec/utils/render_proc_spec.rb +18 -0
  96. metadata +58 -36
  97. data/docs/application.md +0 -7
  98. data/docs/configuration.md +0 -29
  99. data/docs/controllers.md +0 -35
  100. data/docs/routing.md +0 -63
  101. data/opal/fron/core-ext.rb +0 -5
  102. data/opal/fron/core-ext/hash.rb +0 -31
  103. data/opal/fron/core-ext/kernel.rb +0 -10
  104. data/opal/fron/core-ext/numeric.rb +0 -9
  105. data/opal/fron/core-ext/proc.rb +0 -9
  106. data/opal/fron/core/adapters/local.rb +0 -43
  107. data/opal/fron/core/adapters/rails.rb +0 -65
  108. data/opal/fron/core/application.rb +0 -42
  109. data/opal/fron/core/configuration.rb +0 -29
  110. data/opal/fron/core/controller.rb +0 -41
  111. data/opal/fron/core/model.rb +0 -90
  112. data/opal/fron/core/router.rb +0 -86
  113. data/opal/fron/storage/local-storage.rb +0 -34
  114. data/spec/core/adapter/local_spec.rb +0 -65
  115. data/spec/core/adapter/rails_spec.rb +0 -77
  116. data/spec/core/application_spec.rb +0 -35
  117. data/spec/core/configuration_spec.rb +0 -20
  118. data/spec/core/controlller_spec.rb +0 -68
  119. data/spec/core/model_spec.rb +0 -125
  120. data/spec/core/router_spec.rb +0 -124
@@ -1,9 +1,10 @@
1
- describe DOM::Text do
1
+ require 'spec_helper'
2
2
 
3
+ describe DOM::Text do
3
4
  subject { described_class.new('test') }
4
- let(:el) { subject.instance_variable_get("@el") }
5
+ let(:el) { subject.instance_variable_get('@el') }
5
6
 
6
- describe "#initailize" do
7
+ describe '#initailize' do
7
8
  it 'should create textNode with given value' do
8
9
  subject.text.should eq 'test'
9
10
  `#{el} instanceof Text`.should be true
@@ -1,30 +1,45 @@
1
- describe DOM::Window do
1
+ require 'spec_helper'
2
2
 
3
+ describe DOM::Window do
3
4
  subject { described_class }
4
5
 
5
- describe "#hash" do
6
+ describe '#state' do
7
+ it 'should return the pathname' do
8
+ subject.state.should eq '/'
9
+ end
10
+ end
11
+
12
+ describe '#state=' do
13
+ it 'should set the state' do
14
+ subject.should receive(:trigger).with 'popstate'
15
+ subject.state = '/test'
16
+ subject.state.should eq '/test'
17
+ end
18
+ end
19
+
20
+ describe '#hash' do
6
21
  it 'should return the hash of the url' do
7
22
  `window.location.hash = 'test'`
8
23
  subject.hash.should eq 'test'
9
24
  end
10
25
  end
11
26
 
12
- describe "#hash=" do
27
+ describe '#hash=' do
13
28
  it 'should set the hash of the url' do
14
- subject.hash = 'test'
15
- `window.location.hash.slice(1)`.should eq 'test'
29
+ subject.hash = 'test2'
30
+ `window.location.hash.slice(1)`.should eq 'test2'
16
31
  end
17
32
  end
18
33
 
19
- describe "scrollY" do
34
+ describe 'scrollY' do
20
35
  it 'should return the vertical scroll position' do
21
- subject.scrollY.should eq 0
36
+ subject.scroll_y.should eq 0
22
37
  end
23
38
  end
24
39
 
25
- describe "scrollX" do
40
+ describe 'scrollX' do
26
41
  it 'should return the horizontal scroll position' do
27
- subject.scrollX.should eq 0
42
+ subject.scroll_x.should eq 0
28
43
  end
29
44
  end
30
45
  end
@@ -0,0 +1,14 @@
1
+ window.requestAnimationFrame = function(callback){ callback() }
2
+ window.setTimeout = function(callback) { callback() }
3
+ window.clearTimeout = function() { return true }
4
+ window.alert = function(text) { return 'alert' }
5
+ window.confirm = function(text) { return true }
6
+ window.prompt = function(text, value) { return value }
7
+
8
+ window.FileReader = function(){}
9
+ window.FileReader.prototype.readAsDataURL = function(){
10
+ return 'data:image/gif;base64,R0lGODlhyAAiALM...DfD0QAADs='
11
+ }
12
+
13
+ window.throttle = function(fn){ return fn }
14
+ window.debounce = function(fn){ return fn }
@@ -1,23 +1,26 @@
1
- require 'fron/request'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Fron::Request do
4
-
5
- subject { described_class.new 'url' }
6
- let(:request) {%x{
7
- return { readyState: 0,
8
- open: function(){this.opened = true},
9
- send: function(){this.sent = true}}
10
- }}
11
- let(:data) { double :data, to_query_string: '', to_form_data: true }
4
+ subject { described_class.new 'url', 'Content-Type' => 'application/json' }
5
+ let(:request) {
6
+ %x{
7
+ return { readyState: 0,
8
+ open: function(){this.opened = true},
9
+ send: function(){this.sent = true},
10
+ setRequestHeader: function(){},
11
+ getAllResponseHeaders: function(){return ''}}
12
+ }
13
+ }
14
+ let(:data) { Hash.new }
12
15
 
13
16
  before do
14
- subject.instance_variable_set("@request", request)
17
+ subject.instance_variable_set('@request', request)
15
18
  end
16
19
 
17
- describe "#request" do
20
+ describe '#request' do
18
21
  it 'should raise if the rquest is already running' do
19
22
  allow(subject).to receive(:ready_state).and_return 1
20
- expect(Proc.new {subject.request} ).to raise_error
23
+ expect(proc { subject.request }).to raise_error
21
24
  end
22
25
 
23
26
  it 'should call #open on request' do
@@ -30,6 +33,11 @@ describe Fron::Request do
30
33
  expect(`#{request}.sent`).to be true
31
34
  end
32
35
 
36
+ it 'should call #to_form_data on data if it is an UPLOAD' do
37
+ expect(data).to receive(:to_form_data)
38
+ subject.request 'UPLOAD', data
39
+ end
40
+
33
41
  it 'should call #to_query_string on data if it is a GET' do
34
42
  expect(data).to receive(:to_query_string)
35
43
  expect(data).not_to receive(:to_json)
@@ -48,24 +56,35 @@ describe Fron::Request do
48
56
  end
49
57
  end
50
58
 
51
- describe "#get" do
59
+ describe '#get' do
52
60
  it 'should call #request with GET' do
53
61
  expect(subject).to receive(:request).once
54
62
  subject.get
55
63
  end
56
64
  end
57
65
 
58
- describe "#post" do
66
+ describe '#post' do
59
67
  it 'should call #request with POST' do
60
68
  expect(subject).to receive(:request).once
61
69
  subject.post
62
70
  end
63
71
  end
64
72
 
65
- describe "#put" do
73
+ describe '#put' do
66
74
  it 'should call #request with PUT' do
67
75
  expect(subject).to receive(:request).once
68
76
  subject.put
69
77
  end
70
78
  end
79
+
80
+ describe '#handle_state_change' do
81
+ it 'should run callback' do
82
+ callback = proc {}
83
+ subject.instance_variable_set('@callback', callback)
84
+ callback.should receive(:call)
85
+ subject.should receive(:ready_state).and_return 4
86
+ subject.should receive(:trigger).with :loaded
87
+ subject.handle_state_change
88
+ end
89
+ end
71
90
  end
@@ -1,14 +1,13 @@
1
- require 'fron/request'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Fron::Response do
4
-
5
- let(:headers) { "Content-Type: application/json"}
4
+ let(:headers) { 'Content-Type: application/json' }
6
5
  let(:status) { 200 }
7
- let(:body) {'<div></div>'}
6
+ let(:body) { '<div></div>' }
8
7
  subject { described_class.new status, body, headers }
9
8
 
10
- describe "#json" do
11
- let(:body) { {key: 'value'}.to_json }
9
+ describe '#json' do
10
+ let(:body) { { key: 'value' }.to_json }
12
11
 
13
12
  it 'should return the json body as a hash' do
14
13
  subject.json.class.should eq Hash
@@ -16,14 +15,14 @@ describe Fron::Response do
16
15
  end
17
16
  end
18
17
 
19
- describe "#ok?" do
20
- context "200" do
18
+ describe '#ok?' do
19
+ context '200' do
21
20
  it 'should return true if status is 200' do
22
21
  subject.ok?.should be true
23
22
  end
24
23
  end
25
24
 
26
- context "404" do
25
+ context '404' do
27
26
  let(:status) { 404 }
28
27
  it 'should return false if status is not 200' do
29
28
  subject.ok?.should be false
@@ -31,7 +30,7 @@ describe Fron::Response do
31
30
  end
32
31
  end
33
32
 
34
- describe "#dom" do
33
+ describe '#dom' do
35
34
  it 'should return with a Fragment' do
36
35
  subject.dom.class.should eq DOM::Fragment
37
36
  subject.dom.children[0].should_not be nil
@@ -0,0 +1,11 @@
1
+ require 'rspec_coverage_helper'
2
+ require 'js/mocks'
3
+ require 'fron'
4
+ require 'fron/event_mock'
5
+
6
+ ::RSpec.configure do |c|
7
+ c.after(:each) do
8
+ DOM::Document.body.off
9
+ DOM::Window.off
10
+ end
11
+ end
@@ -1,15 +1,14 @@
1
- require 'fron/storage'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Fron::Storage::LocalStorage do
4
-
5
4
  subject { described_class }
6
5
 
7
6
  before do
8
7
  subject.clear
9
- subject.set 'key', { data: 'value' }
8
+ subject.set 'key', data: 'value'
10
9
  end
11
10
 
12
- describe "#get" do
11
+ describe '#get' do
13
12
  it 'should get the data for the key' do
14
13
  data = subject.get('key')
15
14
  data.class.should eq Hash
@@ -17,9 +16,9 @@ describe Fron::Storage::LocalStorage do
17
16
  end
18
17
  end
19
18
 
20
- describe "#set" do
19
+ describe '#set' do
21
20
  it 'should set data for the key' do
22
- subject.set 'key2', { data: 'value' }
21
+ subject.set 'key2', data: 'value'
23
22
  subject.keys.include?('key2').should be true
24
23
  subject.all.length.should be 2
25
24
  end
@@ -40,7 +39,7 @@ describe Fron::Storage::LocalStorage do
40
39
  end
41
40
  end
42
41
 
43
- describe "#all" do
42
+ describe '#all' do
44
43
  it 'should get the data for all key' do
45
44
  data = subject.all[0]
46
45
  data.class.should eq Hash
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+ require 'fron/utils/drag'
3
+
4
+ describe Fron::Drag do
5
+ let(:event) { double(pageX: 0, pageY: 0, preventDefult: true, stop: true, target: true) }
6
+ let(:base) { DOM::Element.new 'div' }
7
+ let(:position) { double }
8
+
9
+ subject { described_class.new base }
10
+
11
+ before do
12
+ allow(subject).to receive(:request_animation_frame)
13
+ end
14
+
15
+ around(:each) do |example|
16
+ EventMock.mock_events(&example)
17
+ end
18
+
19
+ describe 'Events' do
20
+ it 'should call start on mousedown' do
21
+ subject.should receive(:start)
22
+ subject.base.trigger 'mousedown'
23
+ end
24
+
25
+ it 'should call pos when mouse moves' do
26
+ subject.should receive(:pos)
27
+ subject.should receive(:request_animation_frame) do |&block|
28
+ subject.instance_variable_set('@mouse_is_down', false)
29
+ block.call
30
+ end
31
+ subject.start event
32
+ subject.body.trigger 'mousemove'
33
+ end
34
+
35
+ it 'should call up when mouse moves' do
36
+ subject.should receive(:up)
37
+ subject.start event
38
+ subject.body.trigger 'mouseup'
39
+ end
40
+ end
41
+
42
+ describe '#initialize' do
43
+ it 'should set the body' do
44
+ subject.body.should eq DOM::Document.body
45
+ end
46
+
47
+ it 'should add mousedown event listener to the base' do
48
+ subject.base.listeners['mousedown'].length.should eq 1
49
+ end
50
+ end
51
+
52
+ describe '#diff' do
53
+ it 'should diff start position and current position' do
54
+ subject.instance_variable_set('@start_position', position)
55
+ position.should receive(:-)
56
+ subject.diff
57
+ end
58
+ end
59
+
60
+ describe '#start' do
61
+ it 'should call request_animation_frame' do
62
+ subject.should receive(:request_animation_frame).once
63
+ subject.start event
64
+ end
65
+
66
+ it 'should remove events if the dragging not finished properly' do
67
+ subject.instance_variable_set('@pos_method', true)
68
+ subject.should receive(:off)
69
+ subject.start event
70
+ end
71
+ end
72
+
73
+ describe '#pos' do
74
+ it 'it should set position' do
75
+ event.should receive(:stop)
76
+ position.should receive(:distance).and_return 0
77
+ subject.should receive(:diff).and_return position
78
+ subject.should receive(:position).and_return position
79
+ subject.pos event
80
+ pos = subject.instance_variable_get('@position')
81
+ pos.should eq position
82
+ end
83
+ end
84
+
85
+ describe '#up' do
86
+ it 'should stop dragging and reset things' do
87
+ event.should receive(:stop)
88
+ event.should receive(:preventDefault)
89
+ subject.instance_variable_set('@started', true)
90
+ subject.should receive(:reset)
91
+ subject.should receive(:off)
92
+ subject.should receive(:trigger).with 'end'
93
+ subject.up event
94
+ end
95
+ end
96
+
97
+ describe '#move' do
98
+ it 'should call request_animation_frame if mouse is down' do
99
+ subject.instance_variable_set('@mouse_is_down', true)
100
+ subject.should receive(:request_animation_frame) do |&block|
101
+ subject.instance_variable_set('@mouse_is_down', false)
102
+ block.call
103
+ end
104
+ subject.move
105
+ end
106
+
107
+ it 'should trigger move if dragging' do
108
+ subject.instance_variable_set('@started', true)
109
+ subject.instance_variable_set('@position', position)
110
+ subject.should receive(:trigger).with 'move', position
111
+ subject.move
112
+ end
113
+
114
+ it 'should not trigger move if not dragging' do
115
+ subject.should_not receive(:trigger)
116
+ subject.should_not receive(:request_animation_frame)
117
+ subject.move
118
+ end
119
+ end
120
+
121
+ describe '#off' do
122
+ it 'should remove events' do
123
+ subject.body.should receive(:off).at_least(2).times
124
+ subject.off
125
+ end
126
+ end
127
+
128
+ describe '#position' do
129
+ it 'should return the current position' do
130
+ pos = subject.position event
131
+ pos.should be_a Fron::Point
132
+ pos.x.should eq 0
133
+ pos.y.should eq 0
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+ require 'fron/utils/keyboard'
3
+
4
+ # Test Keyboard Class
5
+ class TestKeyboard < Fron::Keyboard
6
+ sc 'ctrl+up'
7
+ end
8
+
9
+ describe TestKeyboard do
10
+ let(:event) { DOM::Event.new `{ctrlKey: true, altKey: true, shiftKey: true, keyCode: 38}` }
11
+
12
+ describe Fron::Keyboard do
13
+ it 'should work on its own' do
14
+ Fron::Keyboard.new.should be_a Fron::Keyboard
15
+ end
16
+ end
17
+
18
+ describe 'DSL' do
19
+ subject { described_class }
20
+
21
+ describe '#sc' do
22
+ it 'should define a shortcut with action' do
23
+ subject.sc 'ctrl+down', :test
24
+ subject.shortcuts.last.should eq(
25
+ parts: %w(ctrl down),
26
+ action: :test,
27
+ block: nil
28
+ )
29
+ end
30
+
31
+ it 'should define a shortcut with block' do
32
+ sc = subject.shortcuts.first
33
+ sc[:parts].should eq %w(ctrl up)
34
+ sc[:action].should eq nil
35
+ end
36
+ end
37
+ end
38
+
39
+ describe 'Events' do
40
+ it 'should handle keydown' do
41
+ subject.should receive(:keydown)
42
+ DOM::Document.body.listeners[:keydown].count.should eq 1
43
+ DOM::Document.body.listeners[:keydown][0].call {}
44
+ end
45
+ end
46
+
47
+ describe '#keydown' do
48
+ let(:shortcut) { { parts: %w(ctrl alt shift up) } }
49
+
50
+ it 'should match shortcuts to the combo' do
51
+ described_class.instance_variable_set('@shortcuts', [{ parts: [] }, shortcut])
52
+ subject.should receive(:handle_shortcut).with shortcut
53
+ event.should receive(:stop)
54
+ subject.keydown event
55
+ end
56
+ end
57
+
58
+ describe 'handle_shortcut' do
59
+ it 'should run block if block given' do
60
+ sc = { block: proc {} }
61
+ subject.should receive(:instance_exec)
62
+ subject.handle_shortcut sc
63
+ end
64
+
65
+ it 'should call action method if given' do
66
+ subject.should receive(:test)
67
+ subject.handle_shortcut action: :test
68
+ end
69
+
70
+ it 'should warn if method is not exists' do
71
+ subject.should receive(:warn)
72
+ subject.handle_shortcut action: :test2, parts: %w(a b)
73
+ end
74
+ end
75
+ end