flok 0.0.100 → 0.0.101
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/drivers/chrome/README.md +6 -0
- data/app/drivers/chrome/Rakefile +1 -0
- data/app/drivers/chrome/build_context.rb +1 -0
- data/app/drivers/chrome/config.yml +4 -0
- data/app/drivers/chrome/spec/spec/dlink_spec.js +15 -0
- data/app/drivers/chrome/spec/spec/hook_spec.js +24 -0
- data/app/drivers/chrome/src/dlink.js +28 -0
- data/app/drivers/chrome/src/hook.js +29 -0
- data/app/kern/mod/dlink.js +16 -0
- data/app/kern/mod/event.js +7 -0
- data/app/kern/mod/hook.js +1 -0
- data/app/kern/services/dlink.rb +25 -0
- data/bin/flok +12 -3
- data/docs/compilation.md +1 -1
- data/docs/kernel_api.md +1 -1
- data/docs/kernel_handbook/hooks.md +4 -0
- data/docs/mod/dlink.md +18 -0
- data/docs/mod/hook.md +9 -0
- data/docs/project.md +3 -2
- data/docs/services/dlink.md +8 -0
- data/docs/user_handbook/hooks.md +106 -0
- data/lib/flok.rb +1 -0
- data/lib/flok/hooks_compiler.rb +174 -0
- data/lib/flok/project_template/config/hooks.rb +1 -0
- data/lib/flok/user_compiler.rb +56 -6
- data/lib/flok/user_compiler_templates/ctable.js.erb +4 -0
- data/lib/flok/user_hook_generators/goto.rb +74 -0
- data/lib/flok/user_hook_generators/helpers.rb +46 -0
- data/lib/flok/version.rb +1 -1
- data/spec/env/kern.rb +32 -16
- data/spec/etc/transition_complier_spec.rb +4 -0
- data/spec/iface/driver/hook_spec.rb +33 -0
- data/spec/iface/kern/dlink_spec.rb +25 -0
- data/spec/kern/assets/dlink_service/config0.rb +2 -0
- data/spec/kern/assets/dlink_service/controller0.rb +16 -0
- data/spec/kern/assets/hook_entry_points/controller0.rb +58 -0
- data/spec/kern/assets/hook_entry_points/controller0a.rb +27 -0
- data/spec/kern/dlink_service_spec.rb +50 -0
- data/spec/kern/hook_entry_points_and_manifest_spec.rb +155 -0
- data/spec/kern/hook_user_generators_spec.rb +139 -0
- metadata +36 -3
- data/docs/mod/intercept.md +0 -26
data/lib/flok.rb
CHANGED
@@ -0,0 +1,174 @@
|
|
1
|
+
require_relative './macro.rb'
|
2
|
+
#The hooks compiler is a late-stage (see ./project.md) compiler that takes the almost-fully-compiled
|
3
|
+
#javascript source (which includes the user's javascript controllers by now) and looks for special
|
4
|
+
#comment markers for which it can inject code.
|
5
|
+
module Flok
|
6
|
+
module HooksCompiler
|
7
|
+
#Returns a new copy of the source transformed as described by the manifest
|
8
|
+
def self.compile(src, manifest)
|
9
|
+
new_src = src.split("\n").map{|e| manifest.transform_line(e) }.join("\n")
|
10
|
+
|
11
|
+
#Re-process macros
|
12
|
+
new_src = Flok.macro_process new_src
|
13
|
+
|
14
|
+
|
15
|
+
return new_src
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#A hooks manifest contains all the information needed so that the hooks compiler
|
20
|
+
#can find can change the code
|
21
|
+
class HooksManifest
|
22
|
+
def initialize
|
23
|
+
@manifest_entries = []
|
24
|
+
end
|
25
|
+
|
26
|
+
#Returns a copy of the line with transformations if needed. For example, if a line contains
|
27
|
+
#a hook entry point, like HOOK_ENTRY[my_event] and the manifest contains code that should
|
28
|
+
#be inserted there, this will return the inserted code (which may then be multiple lines)
|
29
|
+
#And will also remove the comment itself
|
30
|
+
def transform_line line
|
31
|
+
#Get all the matched HooksManifestEntry(s)
|
32
|
+
injected_code = @manifest_entries.select{|e| e.does_match? line}.map{|e| e.code_for_line(line)}
|
33
|
+
|
34
|
+
#If there is a match of at least one hook, remove the original line and replace it
|
35
|
+
#with all the newly found code from the HooksManifestEntry(s)
|
36
|
+
return injected_code.join("\n") if injected_code.count > 0
|
37
|
+
|
38
|
+
#Else, nothing was found, keep moving along and don't transform the line
|
39
|
+
return line
|
40
|
+
end
|
41
|
+
|
42
|
+
#Accepts a HooksManifestEntry which can match a line and then return some text
|
43
|
+
#that should be apart of that line. Multiple matching manifest entries
|
44
|
+
#is possible
|
45
|
+
def <<(entry)
|
46
|
+
@manifest_entries << entry
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#When HooksManifest goes line by line, a line is considered matching when this entry
|
51
|
+
#retruns true for its does_match? function. You pass it a name, optional parameter
|
52
|
+
#query and the block to call when the code should be generated for a match. The block
|
53
|
+
#receives a full copy of the parameters for the hook entry (the static ones). The
|
54
|
+
#param query is a lambda that also receives the block and it should return (next) true/false
|
55
|
+
#when a match is considered true. If name is just "*" (string, not symbol), then it matches
|
56
|
+
#all names. Passing multiple param_queries in is allowed, you just pass in multiple arrays.
|
57
|
+
#All of the procs passed must be true for the result to be true
|
58
|
+
#
|
59
|
+
#E.g. - This would match //HOOK_ENTRY[my_event]
|
60
|
+
#>HooksManifestEntry.new("my_event", ->(p){p["actions"].include? "x"}) do |hook_info|
|
61
|
+
# return "console.log(info = #{info["actions"]});"
|
62
|
+
#end
|
63
|
+
class HooksManifestEntry
|
64
|
+
def initialize name, param_queries=->(p){true}, &block
|
65
|
+
#If an array is not passed, make it an array with one element
|
66
|
+
param_queries = [param_queries] if param_queries.class != Array
|
67
|
+
|
68
|
+
@name = name.to_s
|
69
|
+
@param_queries = param_queries
|
70
|
+
@block = block
|
71
|
+
end
|
72
|
+
|
73
|
+
def does_match? line
|
74
|
+
#Unless the matching name is a *, check to see if the hook name matches
|
75
|
+
unless @name == "*"
|
76
|
+
return false unless line =~ /\/\/HOOK_ENTRY\[#{@name}\]/
|
77
|
+
end
|
78
|
+
|
79
|
+
#Now verify with the lambda
|
80
|
+
return @param_queries.reduce(true){|r, e| r &&= e.call(hook_entry_info_from_line(line))}
|
81
|
+
end
|
82
|
+
|
83
|
+
def code_for_line line
|
84
|
+
return @block.call(hook_entry_info_from_line(line))
|
85
|
+
end
|
86
|
+
|
87
|
+
#Each hook entry contains a JSON encoded set of static parameters
|
88
|
+
#for things like the controller name, etc. See docs for a list of
|
89
|
+
#parameters as it depends on the hook entry
|
90
|
+
def hook_entry_info_from_line line
|
91
|
+
json_info = line.split(/\/\/HOOK_ENTRY\[.*?\]/).last.strip
|
92
|
+
begin
|
93
|
+
return JSON.parse(json_info)
|
94
|
+
rescue => e
|
95
|
+
raise "Couldn't parse the hooks entry JSON information, got #{json_info.inspect}: #{e.inspect}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
#This converts all the user hooks into a manifest
|
101
|
+
module UserHooksToManifestOrchestrator
|
102
|
+
$generators = {}
|
103
|
+
|
104
|
+
#Register a user hook generator to be available to the user in their `./config/hooks.rb`
|
105
|
+
#The name is what is used to find the correct generator when a user uses the
|
106
|
+
#hook :name DSL syntax
|
107
|
+
def self.register_hook_gen name, &gen_block
|
108
|
+
$generators[name] = gen_block
|
109
|
+
end
|
110
|
+
|
111
|
+
#Converts the `./config/hooks.rb` of the user into a HooksManifestEntry
|
112
|
+
def self.convert_hooks_to_manifest hooks_rb
|
113
|
+
#Create a new manifest, this will be passed to each generator instance
|
114
|
+
#along with a set of parameters. Each generator will update the
|
115
|
+
#hooks manifest
|
116
|
+
manifest = HooksManifest.new
|
117
|
+
|
118
|
+
#Evaluate the user hooks DSL which will create a listing of all the
|
119
|
+
#user's requests in the accessible :hooks_requests member of the dsl environment
|
120
|
+
hooks_dsl_env = UserHooksDSL.new
|
121
|
+
hooks_dsl_env.instance_eval hooks_rb
|
122
|
+
|
123
|
+
#For each user request, lookup the appropriate generator handler and then
|
124
|
+
#call the generator
|
125
|
+
hook_requests = hooks_dsl_env.hook_requests
|
126
|
+
hook_requests.each do |gen_name, requests|
|
127
|
+
generator = $generators[gen_name]
|
128
|
+
raise "A hook request requested the generator by the name #{gen_name.inspect} but this was not a generator..." unless generator
|
129
|
+
|
130
|
+
requests.each do |r|
|
131
|
+
generator.call(manifest, r)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
return manifest
|
136
|
+
end
|
137
|
+
|
138
|
+
#Interpret `./config/hooks.rb` to call the associated registered hook gen block
|
139
|
+
class UserHooksDSL
|
140
|
+
attr_accessor :hook_requests
|
141
|
+
def initialize
|
142
|
+
#Each user hook call adds a request to this hash
|
143
|
+
#which is then processed by each matching hook generator
|
144
|
+
@hook_requests = {}
|
145
|
+
end
|
146
|
+
|
147
|
+
#Install a hook. Leads to eventually calling the relavent hook generator. The anmes argument
|
148
|
+
#takes one key-value pair e.g. {:goto => :settings_changed}, this would mean the hook generator
|
149
|
+
#named 'goto' and it should create a hook event called 'settings_changed'. The block
|
150
|
+
#is then passed on to each hook generator. See the docs on hooks.md for information on what
|
151
|
+
#each block function takes
|
152
|
+
def hook names, &block
|
153
|
+
|
154
|
+
#The names parameter
|
155
|
+
key = names.keys.first
|
156
|
+
hook_event_name = names.values.first
|
157
|
+
raise "You didn't supply a hook generator name or the event name... Got #{key.inspect} and #{hook_event_name.inspect}. e.g. hook :goto => :changed, {...}" unless key and hook_event_name
|
158
|
+
|
159
|
+
@hook_requests[key] ||= []
|
160
|
+
@hook_requests[key] << {
|
161
|
+
:hook_event_name => hook_event_name,
|
162
|
+
:block => block
|
163
|
+
}
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
#Load all the user hook generators
|
170
|
+
Dir.chdir File.join(File.dirname(__FILE__), "../../") do
|
171
|
+
Dir["./lib/flok/user_hook_generators/*"].each do |f|
|
172
|
+
load f
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
#Hooks stub
|
data/lib/flok/user_compiler.rb
CHANGED
@@ -22,7 +22,7 @@ module Flok
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
#Compiler executes all rb code inside this context
|
25
|
+
#Compiler executes all rb code (ERB) inside this context
|
26
26
|
module Flok
|
27
27
|
class UserCompilerContext
|
28
28
|
attr_accessor :controllers, :actions, :ons
|
@@ -31,6 +31,21 @@ module Flok
|
|
31
31
|
@controllers = []
|
32
32
|
@actions = []
|
33
33
|
@ons = []
|
34
|
+
|
35
|
+
@debug = ENV["FLOK_ENV"] ? true : false
|
36
|
+
end
|
37
|
+
|
38
|
+
#Returns a list of events that this controller 'might' respond to
|
39
|
+
#Used for things like hook event handlers to provide queryable
|
40
|
+
#information.
|
41
|
+
def might_respond_to
|
42
|
+
@actions.map{|e| e.ons}.flatten.map{|e| e[:name]}
|
43
|
+
end
|
44
|
+
|
45
|
+
#actions_responds_to looks like {"action1" => ["event_a", ..."], "action2" => }...
|
46
|
+
#where each action list contains all the events this action responds to
|
47
|
+
def actions_respond_to
|
48
|
+
@actions.map{|e| [e.name.to_s, e.ons.map{|e| e[:name].to_s}]}.to_h
|
34
49
|
end
|
35
50
|
|
36
51
|
def get_binding
|
@@ -85,8 +100,18 @@ module Flok
|
|
85
100
|
|
86
101
|
#Calculate spot index as an offset from the base address using the index of the spot in the spots
|
87
102
|
#address offset
|
88
|
-
res =
|
89
|
-
|
103
|
+
res = ""
|
104
|
+
|
105
|
+
if @debug
|
106
|
+
res += %{
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
res += %{
|
111
|
+
<% if @debug %>
|
112
|
+
if (__base__.constructor !== Number) { throw "Embed for the controller: #{@controller.name} was not given a number for it's __base__ pointer, but of type: " + __base__.constructor + "with the value: " + __base__};
|
113
|
+
<% end %>
|
114
|
+
|
90
115
|
var ptr = _embed("#{vc_name}", __base__+#{spot_index}+1, #{context}, __base__);
|
91
116
|
__info__.embeds[#{spot_index-1}].push(ptr);
|
92
117
|
}
|
@@ -158,6 +183,8 @@ module Flok
|
|
158
183
|
var old_action = __info__.action;
|
159
184
|
__info__.action = "#{action_name}";
|
160
185
|
|
186
|
+
//HOOK_ENTRY[controller_will_goto] #{{"controller_name" => @controller.name, "might_respond_to" => @ctx.might_respond_to, "actions_responds_to" => @ctx.actions_respond_to, "from_action" => @name, "to_action" => action_name}.to_json}
|
187
|
+
|
161
188
|
//Remove all views, we don't have to recurse because removal of a view
|
162
189
|
//is supposed to remove *all* view controllers of that tree as well.
|
163
190
|
var embeds = __info__.embeds;
|
@@ -494,7 +521,7 @@ module Flok
|
|
494
521
|
end
|
495
522
|
|
496
523
|
class UserCompilerAction
|
497
|
-
attr_accessor :controller, :name, :
|
524
|
+
attr_accessor :controller, :name, :every_handlers
|
498
525
|
include UserCompilerMacro
|
499
526
|
|
500
527
|
def initialize controller, name, ctx, &block
|
@@ -502,7 +529,7 @@ module Flok
|
|
502
529
|
@name = name
|
503
530
|
@ctx = ctx
|
504
531
|
@_on_entry_src = ""
|
505
|
-
@
|
532
|
+
@_ons = [] #Event handlers
|
506
533
|
@every_handlers = []
|
507
534
|
|
508
535
|
self.instance_eval(&block)
|
@@ -518,7 +545,30 @@ module Flok
|
|
518
545
|
end
|
519
546
|
|
520
547
|
def on name, js_src
|
521
|
-
|
548
|
+
#We need this guard because we run a two pass compile on the ons. When 'ons' is accessed, it is assumed that we are now
|
549
|
+
#in the compilation phase and we build all the entries. This is because some macros in the ons source code requires
|
550
|
+
#prior-knowledge of controller-level information like all possible events in all actions for hooks
|
551
|
+
raise "Uh oh, you tried to add an event handler but we already assumed that compilation took place so we cached everything..." if @__ons_did_build or @__ons_is_building
|
552
|
+
|
553
|
+
@_ons << {:name => name, :src => js_src}
|
554
|
+
end
|
555
|
+
|
556
|
+
def ons
|
557
|
+
#Return the un-compiled version as some macros access this data and the real ons
|
558
|
+
#would cause infinite recursion
|
559
|
+
return @_ons if @__ons_is_building
|
560
|
+
@__ons_is_building = true
|
561
|
+
|
562
|
+
#We need this guard because we run a two pass compile on the ons. When 'ons' is accessed, it is assumed that we are now
|
563
|
+
#in the compilation phase and we build all the entries. This is because some macros in the ons source code requires
|
564
|
+
#prior-knowledge of controller-level information like all possible events in all actions for hooks
|
565
|
+
unless @__ons_did_build
|
566
|
+
@__ons_did_build = true
|
567
|
+
@__ons = @_ons.map{|e| {:name => e[:name], :src => _macro(e[:src])}}
|
568
|
+
end
|
569
|
+
|
570
|
+
@__ons_is_building = false
|
571
|
+
return @__ons
|
522
572
|
end
|
523
573
|
|
524
574
|
def every seconds, str
|
@@ -69,6 +69,10 @@ ctable = {
|
|
69
69
|
handlers: {
|
70
70
|
<% a.ons.each do |e| %>
|
71
71
|
<%= e[:name] %>: function(__base__, params) {
|
72
|
+
<% if @debug %>
|
73
|
+
if (__base__.constructor !== Number) { throw "on('<%= e[:name] %>') for the controller: <%= c.name %>:<%= a.name %> was not given a number for it's __base__ pointer, but of type: " + __base__.constructor + "with the value: " + __base__};
|
74
|
+
<% end %>
|
75
|
+
|
72
76
|
var __info__ = tel_deref(__base__);
|
73
77
|
var context = __info__.context;
|
74
78
|
var current_action = __info__.action;
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative 'helpers'
|
2
|
+
|
3
|
+
module Flok
|
4
|
+
class GotoHooksDSLEnv
|
5
|
+
attr_accessor :selectors
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@selectors = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def controller name
|
12
|
+
@selectors << ->(p) { p["controller_name"] and p["controller_name"] == name.to_s }
|
13
|
+
end
|
14
|
+
|
15
|
+
#The previous / next action contains an event handler for...
|
16
|
+
#################################################################################
|
17
|
+
def from_action_responds_to? responds
|
18
|
+
@selectors << lambda do |params|
|
19
|
+
from_action = params["from_action"]
|
20
|
+
actions_respond_to = params["actions_responds_to"] #This is a hash that maps all actions to sensetivity lists
|
21
|
+
|
22
|
+
#Get the sensetivity list if possible for this action (this is the list of events this action responds to)
|
23
|
+
if actions_respond_to[from_action]
|
24
|
+
sensetivity_list = actions_respond_to[from_action]
|
25
|
+
|
26
|
+
#Does the sensetivity list include the event we are interested in?
|
27
|
+
next sensetivity_list.include? responds
|
28
|
+
end
|
29
|
+
|
30
|
+
#The action wasn't even listed on the list, i.e. it has no sensetivity list
|
31
|
+
next false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_action_responds_to? responds
|
36
|
+
@selectors << lambda do |params|
|
37
|
+
to_action = params["to_action"]
|
38
|
+
actions_respond_to = params["actions_responds_to"] #This is a hash that maps all actions to sensetivity lists
|
39
|
+
|
40
|
+
#Get the sensetivity list if possible for this action (this is the list of events this action responds to)
|
41
|
+
if actions_respond_to[to_action]
|
42
|
+
sensetivity_list = actions_respond_to[to_action]
|
43
|
+
|
44
|
+
#Does the sensetivity list include the event we are interested in?
|
45
|
+
next sensetivity_list.include? responds
|
46
|
+
end
|
47
|
+
|
48
|
+
#The action wasn't even listed on the list, i.e. it has no sensetivity list
|
49
|
+
next false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
#################################################################################
|
53
|
+
end
|
54
|
+
|
55
|
+
UserHooksToManifestOrchestrator.register_hook_gen :goto do |manifest, params|
|
56
|
+
hook_event_name = params[:hook_event_name]
|
57
|
+
|
58
|
+
#Evaluate User given DSL (params[:block]) which comes from `./confg/hooks.rb`
|
59
|
+
#to retrieve a set of selectors which we will pass the hooks compiler
|
60
|
+
block = params[:block]
|
61
|
+
dsl_env = GotoHooksDSLEnv.new
|
62
|
+
dsl_env.instance_eval(&block)
|
63
|
+
|
64
|
+
#Inject into HOOK_ENTRY[controller_will_goto] that match the given selectors from the DSL
|
65
|
+
#based on the hook entry static parameters
|
66
|
+
entry = HooksManifestEntry.new("controller_will_goto", dsl_env.selectors) do |entry_hook_params|
|
67
|
+
next %{
|
68
|
+
SEND("main", "if_hook_event", "#{hook_event_name}", {});
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
manifest << entry
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Flok
|
2
|
+
#This class helps construct javascript expressions like ((a == 3 || b == 4) && (a == 5 || c == 6))
|
3
|
+
#Usually you have an outer-level JSTermGroup that represents all the things being anded togeather
|
4
|
+
#and then you have multiple inner groups that each represent ored terms. Search POS form on wikipedia
|
5
|
+
#e.g.
|
6
|
+
# #Convert ((a == 3 || b == 4) && (a == 5 || c == 6))
|
7
|
+
#
|
8
|
+
# This will hold the entire result
|
9
|
+
# ands = JSTermGroup.new
|
10
|
+
#
|
11
|
+
# Compute a small section of the result, the group (a == 3 || b == 4) and
|
12
|
+
# then add it as a group of the entire result in || form
|
13
|
+
# ors1 = JSTermGroup.new
|
14
|
+
# ors1 << "a == 3"
|
15
|
+
# ors1 << "b == 4"
|
16
|
+
# ands << ors1.to_or_js
|
17
|
+
#
|
18
|
+
# Same thing but now we compute the second part which is (a == 5 || c == 5)
|
19
|
+
# ors2 = JSTermGroup.new
|
20
|
+
# ors2 << "a == 5"
|
21
|
+
# ors2 << "c == 6"
|
22
|
+
# ands << ors2.to_or_js
|
23
|
+
#
|
24
|
+
# Finally get the result by &&ing all the ||s groups togeather
|
25
|
+
# result = ands.to_and_js
|
26
|
+
class JSTermGroup
|
27
|
+
def initialize
|
28
|
+
@terms = []
|
29
|
+
end
|
30
|
+
|
31
|
+
#Add a javascript expression that evaluates to either true or false. May or may not contain parantheses
|
32
|
+
def << expr
|
33
|
+
@terms << "(#{expr})"
|
34
|
+
end
|
35
|
+
|
36
|
+
#Join expressions via || statements and yield an expression that contains parantheses
|
37
|
+
def to_or_js
|
38
|
+
"(#{[*@terms, "false"].join(" || ")})"
|
39
|
+
end
|
40
|
+
|
41
|
+
#Join expressions via && statements and yield an expression that contains parantheses
|
42
|
+
def to_and_js
|
43
|
+
"(#{[*@terms, "true"].join(" && ")})"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/flok/version.rb
CHANGED
data/spec/env/kern.rb
CHANGED
@@ -69,7 +69,32 @@ shared_context "kern" do
|
|
69
69
|
|
70
70
|
#Create a new flok project, add the given user_file (an .rb file containing controllers, etc.)
|
71
71
|
#and then retrieve a V8 instance from this project's application_user.js
|
72
|
-
def flok_new_user user_controllers_src, service_config=nil, service_src=nil
|
72
|
+
def flok_new_user user_controllers_src, service_config=nil, service_src=nil, hooks_src=nil
|
73
|
+
return flok_new_user_with_src(user_controllers_src, service_config, service_src, hooks_src)[:ctx]
|
74
|
+
end
|
75
|
+
|
76
|
+
#Returns a v8 instance with modifications like handling dispatch of flok
|
77
|
+
#And sets some members (not the greatest)
|
78
|
+
def v8_flok
|
79
|
+
#Execute
|
80
|
+
@driver = FakeDriverContext.new
|
81
|
+
v8 = V8::Context.new(:with => @driver)
|
82
|
+
@ctx = v8
|
83
|
+
@driver.ctx = v8
|
84
|
+
v8.eval %{
|
85
|
+
//We must convert this to JSON because the fake driver will receive
|
86
|
+
//a raw v8 object otherwise
|
87
|
+
function if_dispatch(q) {
|
88
|
+
if_dispatch_json(JSON.stringify(q));
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
return v8
|
93
|
+
end
|
94
|
+
|
95
|
+
#Create a new flok project, add the given user_file (an .rb file containing controllers, etc.)
|
96
|
+
#and then retrieve a V8 instance from this project's application_user.js
|
97
|
+
def flok_new_user_with_src user_controllers_src, service_config=nil, service_src=nil, hooks_src=nil
|
73
98
|
temp_dir = new_temp_dir
|
74
99
|
Dir.chdir temp_dir do
|
75
100
|
flok "new test"
|
@@ -78,31 +103,22 @@ shared_context "kern" do
|
|
78
103
|
File.write './app/controllers/user_controller.rb', user_controllers_src
|
79
104
|
File.write './config/services.rb', service_config if service_config
|
80
105
|
File.write './app/services/service0.rb', service_src if service_src
|
106
|
+
File.write './config/hooks.rb', hooks_src if hooks_src
|
81
107
|
|
82
108
|
#Build
|
83
109
|
unless flok "build" #Will generate drivers/ but we will ignore that
|
84
110
|
raise "Build failed"
|
85
111
|
end
|
86
112
|
|
87
|
-
|
88
|
-
|
89
|
-
v8
|
90
|
-
|
91
|
-
@driver.ctx = v8
|
92
|
-
v8.eval %{
|
93
|
-
//We must convert this to JSON because the fake driver will receive
|
94
|
-
//a raw v8 object otherwise
|
95
|
-
function if_dispatch(q) {
|
96
|
-
if_dispatch_json(JSON.stringify(q));
|
97
|
-
}
|
98
|
-
}
|
99
|
-
|
100
|
-
v8.eval File.read('./products/chrome/application_user.js')
|
101
|
-
return v8
|
113
|
+
v8 = v8_flok
|
114
|
+
src = File.read('./products/chrome/application_user.js')
|
115
|
+
v8.eval src
|
116
|
+
return {:ctx => v8, :src => src}
|
102
117
|
end
|
103
118
|
end
|
104
119
|
end
|
105
120
|
|
121
|
+
|
106
122
|
#This supports if_dispatch interface and allows for sending information back via
|
107
123
|
#int_dispatch to the kernel. It is embededd into the v8 context environment
|
108
124
|
class FakeDriverContext
|