flok 0.0.100 → 0.0.101
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 +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
|