vedeu 0.2.12 → 0.3.0

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 (305) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Guardfile +13 -0
  4. data/README.md +11 -9
  5. data/Rakefile +10 -1
  6. data/bin/vedeu_test +14 -0
  7. data/config/cucumber.yml +8 -0
  8. data/docs/api.md +45 -16
  9. data/docs/events.md +21 -9
  10. data/docs/getting_started.md +16 -0
  11. data/docs/views.md +158 -0
  12. data/examples/borders_app.rb +236 -110
  13. data/examples/colour_support.sh +98 -0
  14. data/examples/colours_app.rb +41 -0
  15. data/examples/configuration_app.rb +11 -6
  16. data/examples/cursor_app.rb +60 -61
  17. data/examples/focus_app.rb +72 -34
  18. data/examples/hello_world.rb +13 -8
  19. data/examples/lines_app.rb +37 -28
  20. data/features/start_stop.feature +27 -0
  21. data/features/support/env.rb +14 -0
  22. data/lib/vedeu/all.rb +29 -0
  23. data/lib/vedeu/api.rb +39 -0
  24. data/lib/vedeu/application.rb +15 -7
  25. data/lib/vedeu/bindings.rb +121 -0
  26. data/lib/vedeu/buffers/all.rb +10 -0
  27. data/lib/vedeu/{repositories/models → buffers}/buffer.rb +47 -64
  28. data/lib/vedeu/buffers/display_buffer.rb +118 -0
  29. data/lib/vedeu/configuration/all.rb +6 -0
  30. data/lib/vedeu/configuration/api.rb +3 -1
  31. data/lib/vedeu/configuration/cli.rb +3 -1
  32. data/lib/vedeu/configuration/configuration.rb +23 -2
  33. data/lib/vedeu/cursor/all.rb +23 -0
  34. data/lib/vedeu/cursor/cursor.rb +116 -0
  35. data/lib/vedeu/cursor/move_cursor.rb +137 -0
  36. data/lib/vedeu/cursor/toggle_cursor.rb +53 -0
  37. data/lib/vedeu/dsl/all.rb +28 -0
  38. data/lib/vedeu/dsl/components/all.rb +7 -0
  39. data/lib/vedeu/dsl/components/border.rb +104 -0
  40. data/lib/vedeu/dsl/components/geometry.rb +153 -0
  41. data/lib/vedeu/dsl/components/keymap.rb +93 -0
  42. data/lib/vedeu/dsl/components/menu.rb +82 -0
  43. data/lib/vedeu/dsl/composition.rb +72 -0
  44. data/lib/vedeu/dsl/interface.rb +210 -0
  45. data/lib/vedeu/dsl/line.rb +135 -0
  46. data/lib/vedeu/dsl/shared/all.rb +7 -0
  47. data/lib/vedeu/dsl/shared/colour.rb +85 -0
  48. data/lib/vedeu/dsl/shared/style.rb +38 -0
  49. data/lib/vedeu/dsl/shared/text.rb +102 -0
  50. data/lib/vedeu/dsl/shared/use.rb +47 -0
  51. data/lib/vedeu/dsl/stream.rb +49 -0
  52. data/lib/vedeu/dsl/view.rb +136 -0
  53. data/lib/vedeu/events/all.rb +10 -0
  54. data/lib/vedeu/{repositories/models → events}/event.rb +97 -8
  55. data/lib/vedeu/events/trigger.rb +58 -0
  56. data/lib/vedeu/exceptions.rb +34 -0
  57. data/lib/vedeu/input/all.rb +29 -0
  58. data/lib/vedeu/input/input.rb +26 -0
  59. data/lib/vedeu/{models → input}/key.rb +21 -11
  60. data/lib/vedeu/input/keymap.rb +130 -0
  61. data/lib/vedeu/input/keys.rb +8 -0
  62. data/lib/vedeu/input/mapper.rb +112 -0
  63. data/lib/vedeu/launcher.rb +7 -4
  64. data/lib/vedeu/models/all.rb +12 -0
  65. data/lib/vedeu/models/collection.rb +71 -0
  66. data/lib/vedeu/{repositories → models}/focus.rb +63 -21
  67. data/lib/vedeu/models/geometry.rb +100 -259
  68. data/lib/vedeu/{repositories/models → models}/group.rb +16 -14
  69. data/lib/vedeu/{repositories/models → models}/menu.rb +85 -22
  70. data/lib/vedeu/models/model.rb +51 -0
  71. data/lib/vedeu/models/view/all.rb +12 -0
  72. data/lib/vedeu/models/view/char.rb +84 -0
  73. data/lib/vedeu/models/view/chars.rb +8 -0
  74. data/lib/vedeu/models/view/composition.rb +101 -0
  75. data/lib/vedeu/models/view/interface.rb +215 -0
  76. data/lib/vedeu/models/view/interfaces.rb +8 -0
  77. data/lib/vedeu/models/view/line.rb +134 -0
  78. data/lib/vedeu/models/view/lines.rb +8 -0
  79. data/lib/vedeu/models/view/stream.rb +144 -0
  80. data/lib/vedeu/models/view/streams.rb +8 -0
  81. data/lib/vedeu/output/all.rb +8 -0
  82. data/lib/vedeu/output/border.rb +387 -0
  83. data/lib/vedeu/output/compositor.rb +41 -30
  84. data/lib/vedeu/output/output.rb +6 -13
  85. data/lib/vedeu/output/viewport.rb +78 -94
  86. data/lib/vedeu/output/writer.rb +29 -0
  87. data/lib/vedeu/presentation/all.rb +9 -0
  88. data/lib/vedeu/{colours → presentation}/background.rb +1 -9
  89. data/lib/vedeu/{colours → presentation}/colour.rb +21 -8
  90. data/lib/vedeu/{colours → presentation}/foreground.rb +5 -9
  91. data/lib/vedeu/presentation/presentation.rb +91 -0
  92. data/lib/vedeu/presentation/style.rb +47 -0
  93. data/lib/vedeu/{colours → presentation}/translator.rb +11 -5
  94. data/lib/vedeu/repositories/all.rb +5 -0
  95. data/lib/vedeu/repositories/menus.rb +5 -42
  96. data/lib/vedeu/{support → repositories}/repository.rb +78 -41
  97. data/lib/vedeu/support/all.rb +22 -0
  98. data/lib/vedeu/support/bounding_area.rb +2 -1
  99. data/lib/vedeu/support/coercions.rb +18 -1
  100. data/lib/vedeu/support/console.rb +73 -0
  101. data/lib/vedeu/support/content_geometry.rb +69 -0
  102. data/lib/vedeu/support/coordinate.rb +246 -0
  103. data/lib/vedeu/support/esc.rb +29 -2
  104. data/lib/vedeu/support/log.rb +36 -2
  105. data/lib/vedeu/support/node.rb +61 -0
  106. data/lib/vedeu/support/position.rb +28 -13
  107. data/lib/vedeu/support/position_validator.rb +79 -0
  108. data/lib/vedeu/support/read.rb +65 -0
  109. data/lib/vedeu/support/refresh.rb +8 -32
  110. data/lib/vedeu/support/terminal.rb +34 -4
  111. data/lib/vedeu/support/text.rb +104 -0
  112. data/lib/vedeu/support/trace.rb +11 -23
  113. data/lib/vedeu/support/visible.rb +75 -0
  114. data/lib/vedeu/support/write.rb +85 -0
  115. data/lib/vedeu/traps.rb +18 -0
  116. data/lib/vedeu.rb +41 -101
  117. data/test/integration/dsl/compositions_test.rb +27 -0
  118. data/test/integration/dsl/interfaces_test.rb +261 -0
  119. data/test/integration/dsl/keymaps_test.rb +42 -0
  120. data/test/integration/dsl/lines_test.rb +146 -0
  121. data/test/integration/dsl/menus_test.rb +59 -0
  122. data/test/integration/dsl/streams_test.rb +129 -0
  123. data/test/integration/dsl/views_test.rb +63 -0
  124. data/test/lib/vedeu/api_test.rb +163 -0
  125. data/test/lib/vedeu/application_test.rb +19 -10
  126. data/test/lib/vedeu/bindings_test.rb +54 -0
  127. data/test/lib/vedeu/buffers/all_test.rb +11 -0
  128. data/test/lib/vedeu/buffers/buffer_test.rb +196 -0
  129. data/test/lib/vedeu/buffers/display_buffer_test.rb +58 -0
  130. data/test/lib/vedeu/configuration/api_test.rb +42 -58
  131. data/test/lib/vedeu/configuration/cli_test.rb +4 -4
  132. data/test/lib/vedeu/configuration/configuration_test.rb +11 -29
  133. data/test/lib/vedeu/cursor/all_test.rb +33 -0
  134. data/test/lib/vedeu/cursor/cursor_test.rb +85 -0
  135. data/test/lib/vedeu/cursor/move_cursor_test.rb +212 -0
  136. data/test/lib/vedeu/cursor/toggle_cursor_test.rb +63 -0
  137. data/test/lib/vedeu/dsl/components/border_test.rb +414 -0
  138. data/test/lib/vedeu/dsl/components/geometry_test.rb +231 -0
  139. data/test/lib/vedeu/dsl/components/keymap_test.rb +80 -0
  140. data/test/lib/vedeu/dsl/components/menu_test.rb +115 -0
  141. data/test/lib/vedeu/dsl/composition_test.rb +41 -0
  142. data/test/lib/vedeu/dsl/interface_test.rb +470 -0
  143. data/test/lib/vedeu/dsl/line_test.rb +60 -0
  144. data/test/lib/vedeu/dsl/shared/colour_test.rb +100 -0
  145. data/test/lib/vedeu/dsl/shared/style_test.rb +22 -0
  146. data/test/lib/vedeu/dsl/shared/text_test.rb +15 -0
  147. data/test/lib/vedeu/dsl/shared/use_test.rb +27 -0
  148. data/test/lib/vedeu/dsl/stream_test.rb +26 -0
  149. data/test/lib/vedeu/dsl/view_test.rb +73 -0
  150. data/test/lib/vedeu/events/all_test.rb +11 -0
  151. data/test/lib/vedeu/events/event_test.rb +109 -0
  152. data/test/lib/vedeu/events/trigger_test.rb +60 -0
  153. data/test/lib/vedeu/input/all_test.rb +11 -0
  154. data/test/lib/vedeu/input/input_test.rb +7 -3
  155. data/test/lib/vedeu/input/key_test.rb +72 -0
  156. data/test/lib/vedeu/input/keymap_test.rb +89 -0
  157. data/test/lib/vedeu/input/mapper_test.rb +94 -0
  158. data/test/lib/vedeu/launcher_test.rb +19 -20
  159. data/test/lib/vedeu/models/collection_test.rb +114 -0
  160. data/test/lib/vedeu/{repositories → models}/focus_test.rb +46 -13
  161. data/test/lib/vedeu/models/geometry_test.rb +35 -39
  162. data/test/lib/vedeu/models/group_test.rb +100 -0
  163. data/test/lib/vedeu/models/menu_test.rb +288 -0
  164. data/test/lib/vedeu/models/model_test.rb +31 -0
  165. data/test/lib/vedeu/models/view/char_test.rb +166 -0
  166. data/test/lib/vedeu/models/view/chars_test.rb +18 -0
  167. data/test/lib/vedeu/models/view/composition_test.rb +41 -0
  168. data/test/lib/vedeu/models/view/interface_test.rb +128 -0
  169. data/test/lib/vedeu/models/view/interfaces_test.rb +18 -0
  170. data/test/lib/vedeu/models/view/line_test.rb +214 -0
  171. data/test/lib/vedeu/models/view/lines_test.rb +18 -0
  172. data/test/lib/vedeu/models/view/stream_test.rb +106 -0
  173. data/test/lib/vedeu/models/view/streams_test.rb +18 -0
  174. data/test/lib/vedeu/output/border_test.rb +357 -0
  175. data/test/lib/vedeu/output/compositor_test.rb +61 -15
  176. data/test/lib/vedeu/output/output_test.rb +25 -84
  177. data/test/lib/vedeu/output/viewport_test.rb +171 -45
  178. data/test/lib/vedeu/output/writer_test.rb +45 -0
  179. data/test/lib/vedeu/{colours → presentation}/background_test.rb +0 -0
  180. data/test/lib/vedeu/{colours → presentation}/colour_test.rb +5 -5
  181. data/test/lib/vedeu/{colours → presentation}/foreground_test.rb +0 -0
  182. data/test/lib/vedeu/presentation/presentation_test.rb +56 -0
  183. data/test/lib/vedeu/presentation/style_test.rb +69 -0
  184. data/test/lib/vedeu/presentation/translator_test.rb +63 -0
  185. data/test/lib/vedeu/repositories/all_test.rb +7 -0
  186. data/test/lib/vedeu/repositories/menus_test.rb +3 -156
  187. data/test/lib/vedeu/repositories/repository_test.rb +271 -0
  188. data/test/lib/vedeu/support/bounding_area_test.rb +3 -3
  189. data/test/lib/vedeu/support/coercions_test.rb +39 -0
  190. data/test/lib/vedeu/support/common_test.rb +31 -16
  191. data/test/lib/vedeu/support/console_test.rb +85 -0
  192. data/test/lib/vedeu/support/content_geometry_test.rb +107 -0
  193. data/test/lib/vedeu/support/coordinate_test.rb +190 -0
  194. data/test/lib/vedeu/support/esc_test.rb +18 -0
  195. data/test/lib/vedeu/support/grid_test.rb +15 -10
  196. data/test/lib/vedeu/support/log_test.rb +3 -0
  197. data/test/lib/vedeu/support/position_test.rb +22 -2
  198. data/test/lib/vedeu/support/position_validator_test.rb +11 -0
  199. data/test/lib/vedeu/support/read_test.rb +88 -0
  200. data/test/lib/vedeu/support/refresh_test.rb +44 -12
  201. data/test/lib/vedeu/support/sentence_test.rb +6 -4
  202. data/test/lib/vedeu/support/terminal_test.rb +81 -70
  203. data/test/lib/vedeu/support/text_test.rb +93 -0
  204. data/test/lib/vedeu/support/trace_test.rb +21 -9
  205. data/test/lib/vedeu/support/visible_test.rb +148 -0
  206. data/test/lib/vedeu/support/write_test.rb +136 -0
  207. data/test/lib/vedeu/traps_test.rb +11 -0
  208. data/test/lib/vedeu_test.rb +2 -0
  209. data/test/support/helpers/all.rb +7 -0
  210. data/test/support/helpers/dsl_model_test_class.rb +25 -0
  211. data/test/support/{test_classes → helpers}/helpers.rb +0 -2
  212. data/test/support/helpers/misc.rb +15 -0
  213. data/test/support/helpers/model_test_class.rb +34 -0
  214. data/test/support/{test_classes → helpers}/presentation.rb +0 -0
  215. data/test/support/{test_classes → helpers}/repositories.rb +3 -3
  216. data/test/support/{test_modules/repository.rb → helpers/repository_test_module.rb} +5 -1
  217. data/test/test_helper.rb +19 -22
  218. data/vedeu.gemspec +11 -6
  219. metadata +322 -181
  220. data/lib/vedeu/api/api.rb +0 -239
  221. data/lib/vedeu/api/composition.rb +0 -38
  222. data/lib/vedeu/api/defined.rb +0 -52
  223. data/lib/vedeu/api/helpers.rb +0 -161
  224. data/lib/vedeu/api/interface.rb +0 -287
  225. data/lib/vedeu/api/keymap.rb +0 -75
  226. data/lib/vedeu/api/line.rb +0 -107
  227. data/lib/vedeu/api/menu.rb +0 -111
  228. data/lib/vedeu/api/stream.rb +0 -96
  229. data/lib/vedeu/models/border.rb +0 -238
  230. data/lib/vedeu/models/char.rb +0 -43
  231. data/lib/vedeu/models/composition.rb +0 -72
  232. data/lib/vedeu/models/line.rb +0 -100
  233. data/lib/vedeu/models/stream.rb +0 -130
  234. data/lib/vedeu/models/style.rb +0 -52
  235. data/lib/vedeu/repositories/buffers.rb +0 -52
  236. data/lib/vedeu/repositories/cursors.rb +0 -64
  237. data/lib/vedeu/repositories/events.rb +0 -147
  238. data/lib/vedeu/repositories/groups.rb +0 -47
  239. data/lib/vedeu/repositories/interfaces.rb +0 -78
  240. data/lib/vedeu/repositories/keymaps.rb +0 -196
  241. data/lib/vedeu/repositories/models/cursor.rb +0 -209
  242. data/lib/vedeu/repositories/models/interface.rb +0 -163
  243. data/lib/vedeu/repositories/models/keymap.rb +0 -111
  244. data/lib/vedeu/repositories/models/offset.rb +0 -91
  245. data/lib/vedeu/repositories/offsets.rb +0 -69
  246. data/lib/vedeu/support/exceptions.rb +0 -34
  247. data/lib/vedeu/support/keymap_validator.rb +0 -100
  248. data/lib/vedeu/support/model.rb +0 -14
  249. data/lib/vedeu/support/presentation.rb +0 -86
  250. data/lib/vedeu/support/registrar.rb +0 -53
  251. data/test/integration/api/api_test.rb +0 -97
  252. data/test/integration/api_dsl/dsl_api_test.rb +0 -4
  253. data/test/integration/api_dsl/dsl_composition_test.rb +0 -4
  254. data/test/integration/api_dsl/dsl_defined_test.rb +0 -4
  255. data/test/integration/api_dsl/dsl_helpers_test.rb +0 -4
  256. data/test/integration/api_dsl/dsl_interface_test.rb +0 -4
  257. data/test/integration/api_dsl/dsl_keymap.rb +0 -4
  258. data/test/integration/api_dsl/dsl_line_test.rb +0 -4
  259. data/test/integration/api_dsl/dsl_menu_test.rb +0 -4
  260. data/test/integration/api_dsl/dsl_stream_test.rb +0 -138
  261. data/test/integration/cursors_test.rb +0 -9
  262. data/test/integration/defining_interfaces_test.rb +0 -26
  263. data/test/integration/run_once_test.rb +0 -26
  264. data/test/integration/views/basic_view_test.rb +0 -807
  265. data/test/lib/vedeu/api/api_test.rb +0 -204
  266. data/test/lib/vedeu/api/composition_test.rb +0 -31
  267. data/test/lib/vedeu/api/defined_test.rb +0 -79
  268. data/test/lib/vedeu/api/helpers_test.rb +0 -111
  269. data/test/lib/vedeu/api/interface_test.rb +0 -410
  270. data/test/lib/vedeu/api/keymap_test.rb +0 -65
  271. data/test/lib/vedeu/api/line_test.rb +0 -83
  272. data/test/lib/vedeu/api/menu_test.rb +0 -85
  273. data/test/lib/vedeu/api/stream_test.rb +0 -59
  274. data/test/lib/vedeu/colours/translator_test.rb +0 -22
  275. data/test/lib/vedeu/models/border_test.rb +0 -197
  276. data/test/lib/vedeu/models/char_test.rb +0 -52
  277. data/test/lib/vedeu/models/composition_test.rb +0 -45
  278. data/test/lib/vedeu/models/key_test.rb +0 -43
  279. data/test/lib/vedeu/models/line_test.rb +0 -123
  280. data/test/lib/vedeu/models/stream_test.rb +0 -233
  281. data/test/lib/vedeu/models/style_test.rb +0 -59
  282. data/test/lib/vedeu/repositories/buffers_test.rb +0 -37
  283. data/test/lib/vedeu/repositories/cursors_test.rb +0 -62
  284. data/test/lib/vedeu/repositories/events_test.rb +0 -57
  285. data/test/lib/vedeu/repositories/groups_test.rb +0 -28
  286. data/test/lib/vedeu/repositories/interfaces_test.rb +0 -51
  287. data/test/lib/vedeu/repositories/keymaps_test.rb +0 -223
  288. data/test/lib/vedeu/repositories/models/buffer_test.rb +0 -174
  289. data/test/lib/vedeu/repositories/models/cursor_test.rb +0 -158
  290. data/test/lib/vedeu/repositories/models/event_test.rb +0 -53
  291. data/test/lib/vedeu/repositories/models/group_test.rb +0 -98
  292. data/test/lib/vedeu/repositories/models/interface_test.rb +0 -130
  293. data/test/lib/vedeu/repositories/models/keymap_test.rb +0 -27
  294. data/test/lib/vedeu/repositories/models/menu_test.rb +0 -246
  295. data/test/lib/vedeu/repositories/models/offset_test.rb +0 -128
  296. data/test/lib/vedeu/repositories/offsets_test.rb +0 -39
  297. data/test/lib/vedeu/support/keymap_validator_test.rb +0 -62
  298. data/test/lib/vedeu/support/model_test.rb +0 -23
  299. data/test/lib/vedeu/support/presentation_test.rb +0 -53
  300. data/test/lib/vedeu/support/registrar_test.rb +0 -94
  301. data/test/lib/vedeu/support/repository_test.rb +0 -208
  302. data/test/support/test_classes/all.rb +0 -5
  303. data/test/support/test_classes/coercions.rb +0 -16
  304. data/test/support/test_classes/model.rb +0 -23
  305. data/test/support/test_modules/all.rb +0 -1
@@ -1,11 +1,35 @@
1
+ require 'vedeu/exceptions'
2
+ require 'vedeu/models/all'
3
+ require 'vedeu/support/common'
4
+
1
5
  module Vedeu
2
6
 
3
7
  # Provides common methods for accessing the various repositories Vedeu uses.
4
8
  #
9
+ # @example
10
+ # { 'models' => [Model, Model, Model] }
11
+ #
12
+ # { 'models' => [Model] }
13
+ #
5
14
  # @api private
6
- module Repository
15
+ class Repository
7
16
 
8
- include Common
17
+ include Vedeu::Common
18
+ include Enumerable
19
+
20
+ attr_reader :model, :storage
21
+
22
+ def initialize(model = nil, storage = {})
23
+ @model = model
24
+ @storage = storage
25
+ end
26
+
27
+ # Returns log friendly output.
28
+ #
29
+ # @return [String]
30
+ def inspect
31
+ "<#{self.class.name} (#{storage.size})>"
32
+ end
9
33
 
10
34
  # Return the whole repository.
11
35
  #
@@ -14,6 +38,17 @@ module Vedeu
14
38
  storage
15
39
  end
16
40
 
41
+ # Return the model for the interface currently in focus.
42
+ #
43
+ # @return [String|NilClass]
44
+ def current
45
+ find_or_create(Vedeu.focus) if Vedeu.focus
46
+ end
47
+
48
+ def each(&block)
49
+ storage.each(&block)
50
+ end
51
+
17
52
  # Return a boolean indicating whether the storage is empty.
18
53
  #
19
54
  # @return [Boolean]
@@ -24,22 +59,29 @@ module Vedeu
24
59
  # Find the model attributes by name.
25
60
  #
26
61
  # @param name [String]
62
+ # @raise [ModelNotFound] When the model cannot be found with this name.
27
63
  # @return [Hash]
28
64
  def find(name)
29
- storage.fetch(name) { not_found(name) }
65
+ storage.fetch(name) do
66
+ fail ModelNotFound, "Cannot find model by name: '#{name}'"
67
+ end
30
68
  end
31
69
 
32
70
  # Find a model by name, registers the model by name if not found.
33
71
  #
34
72
  # @param name [String]
35
- # @return [Cursor|Offset]
73
+ # @return []
36
74
  def find_or_create(name)
37
- storage.fetch(name) do
75
+ if registered?(name)
76
+ find(name)
77
+
78
+ else
38
79
  Vedeu.log("Model (#{model}) not found, registering: '#{name}'")
39
80
 
40
- model.new({ name: name }).store
81
+ model.new(name).store
41
82
  end
42
83
  end
84
+ alias_method :by_name, :find_or_create
43
85
 
44
86
  # Returns a collection of the names of all the registered entities.
45
87
  #
@@ -58,6 +100,7 @@ module Vedeu
58
100
  # @param name [String]
59
101
  # @return [Boolean]
60
102
  def registered?(name)
103
+ return false if name.nil? || name.empty?
61
104
  return false if empty?
62
105
 
63
106
  storage.include?(name)
@@ -87,7 +130,7 @@ module Vedeu
87
130
  #
88
131
  # @return [Array|Hash|Set]
89
132
  def reset
90
- @_storage = in_memory
133
+ @storage = in_memory
91
134
  end
92
135
 
93
136
  # Stores the model instance by name in the repository of the model.
@@ -95,53 +138,47 @@ module Vedeu
95
138
  # @param model [void] A model instance.
96
139
  # @return [void] The model instance which was stored.
97
140
  def store(model)
141
+ fail MissingRequired, "Cannot store model '#{model.class}' without a " \
142
+ "name attribute." unless defined_value?(model.name)
143
+
144
+ Vedeu.log(_log_store(model))
145
+
98
146
  storage[model.name] = model
99
147
  end
148
+ alias_method :register, :store
100
149
 
101
- private
150
+ # Access a model by name.
151
+ #
152
+ # @param name [String]
153
+ # @return [|NilClass]
154
+ def use(name)
155
+ if registered?(name)
156
+ find(name)
102
157
 
103
- # @param method [Symbol]
104
- # @return [String]
105
- def action(method)
106
- return 'Registering' if method == :add
158
+ else
159
+ nil
107
160
 
108
- 'Updating'
161
+ end
109
162
  end
110
163
 
111
- # @param name [String]
112
- # @raise [ModelNotFound] When the model cannot be found with this name.
113
- # @return [ModelNotFound]
114
- def not_found(name)
115
- fail ModelNotFound, "Cannot find model by name: '#{name}'"
116
- end
164
+ private
117
165
 
118
- # Access to the storage for this repository.
119
- #
120
166
  # @return [Hash]
121
- def storage
122
- @_storage ||= in_memory
167
+ def in_memory
168
+ {}
123
169
  end
124
170
 
125
- # At present, validates that attributes has a `:name` key that is not nil or
126
- # empty.
127
- #
128
- # @param attributes [Hash]
129
- # @return [TrueClass|MissingRequired]
130
- def validate_attributes!(attributes)
131
- return missing_required unless attributes.key?(:name)
132
- return missing_required unless defined_value?(attributes[:name])
171
+ # @return [String]
172
+ def _log_store(model)
173
+ message = "Storing #{model.class.name}: '#{model.name}' "
133
174
 
134
- true
135
- end
175
+ if registered?(model.name)
176
+ message + '(updating)'
136
177
 
137
- # Raises the MissingRequired exception.
138
- #
139
- # @param attr [String] A textual representation of the attribute.
140
- # @raise [MissingRequired] When an attribute, defined by the attr parameter
141
- # is missing.
142
- # @return [MissingRequired]
143
- def missing_required(attr = 'name')
144
- fail MissingRequired, "Cannot store data without a #{attr} attribute."
178
+ else
179
+ message + '(creating)'
180
+
181
+ end
145
182
  end
146
183
 
147
184
  end # Repository
@@ -0,0 +1,22 @@
1
+ require 'vedeu/support/bounding_area'
2
+ require 'vedeu/support/coercions'
3
+ require 'vedeu/support/common'
4
+ require 'vedeu/support/console'
5
+ require 'vedeu/support/content_geometry'
6
+ require 'vedeu/support/coordinate'
7
+ require 'vedeu/support/esc'
8
+ require 'vedeu/support/grid'
9
+ require 'vedeu/support/log'
10
+ require 'vedeu/support/position'
11
+ require 'vedeu/support/position_validator'
12
+ require 'vedeu/support/read'
13
+ require 'vedeu/support/refresh'
14
+ require 'vedeu/support/sentence'
15
+ require 'vedeu/support/terminal'
16
+ require 'vedeu/support/text'
17
+ require 'vedeu/support/trace'
18
+ require 'vedeu/support/visible'
19
+ require 'vedeu/support/write'
20
+
21
+ module Vedeu
22
+ end # Vedeu
@@ -2,7 +2,8 @@ module Vedeu
2
2
 
3
3
  class BoundingArea
4
4
 
5
- attr_reader :height, :width
5
+ attr_reader :height,
6
+ :width
6
7
 
7
8
  # Returns an instance of BoundingArea.
8
9
  #
@@ -1,3 +1,5 @@
1
+ require 'vedeu/support/common'
2
+
1
3
  module Vedeu
2
4
 
3
5
  # Provides means to convert attributes into the correct model.
@@ -7,6 +9,21 @@ module Vedeu
7
9
 
8
10
  include Vedeu::Common
9
11
 
12
+ # Produces new objects of the correct class from the value, ignores objects
13
+ # that have already been coerced.
14
+ def coerce(value)
15
+ if value.is_a?(self)
16
+ value
17
+
18
+ elsif value.nil?
19
+ new
20
+
21
+ else
22
+ new(value)
23
+
24
+ end
25
+ end
26
+
10
27
  # Produces new objects of the correct class from attributes hashes,
11
28
  # ignores objects that have already been coerced.
12
29
  #
@@ -20,7 +37,7 @@ module Vedeu
20
37
  value
21
38
 
22
39
  else
23
- self.new(value)
40
+ new(value)
24
41
 
25
42
  end
26
43
  end
@@ -0,0 +1,73 @@
1
+ require 'vedeu/support/read'
2
+ require 'vedeu/support/write'
3
+
4
+ module Vedeu
5
+
6
+ class Console
7
+
8
+ attr_reader :height,
9
+ :width
10
+
11
+ alias_method :yn, :height
12
+ alias_method :xn, :width
13
+
14
+ # @param height [Fixnum]
15
+ # @param width [Fixnum]
16
+ def initialize(height = 25, width = 80)
17
+ @height = height || 25
18
+ @width = width || 80
19
+ end
20
+
21
+ # @param data [String|NilClass]
22
+ # @return [String]
23
+ def input(data = nil)
24
+ Vedeu::Read.from(self, data)
25
+ end
26
+ alias_method :read, :input
27
+
28
+ # @param data [Array<Array<Char>>|Array<String>|String|NilClass]
29
+ # @return [Array]
30
+ def output(data = nil)
31
+ Vedeu::Write.to(self, data)
32
+ end
33
+ alias_method :write, :output
34
+
35
+ # Returns a coordinate tuple of the format [y, x], where `y` is the row/line
36
+ # and `x` is the column/character.
37
+ #
38
+ # @return [Array]
39
+ def centre
40
+ [(height / 2), (width / 2)]
41
+ end
42
+
43
+ # Returns the `y` (row/line) component of the coordinate tuple provided by
44
+ # {Vedeu::Terminal.centre}
45
+ #
46
+ # @return [Fixnum]
47
+ def centre_y
48
+ centre.first
49
+ end
50
+
51
+ # Returns the `x` (column/character) component of the coodinate tuple
52
+ # provided by {Vedeu::Terminal.centre}
53
+ #
54
+ # @return [Fixnum]
55
+ def centre_x
56
+ centre.last
57
+ end
58
+
59
+ # @return [Fixnum]
60
+ def origin
61
+ 1
62
+ end
63
+ alias_method :x, :origin
64
+ alias_method :y, :origin
65
+
66
+ # @return [Array]
67
+ def size
68
+ [height, width]
69
+ end
70
+
71
+ end # Console
72
+
73
+ end # Vedeu
@@ -0,0 +1,69 @@
1
+ module Vedeu
2
+
3
+ class ContentGeometry
4
+
5
+ extend Forwardable
6
+
7
+ def_delegators :interface,
8
+ :lines?,
9
+ :lines,
10
+ :geometry
11
+
12
+ def_delegators :geometry,
13
+ :height,
14
+ :width,
15
+ :x,
16
+ :y
17
+
18
+ def initialize(interface)
19
+ @interface = interface
20
+ end
21
+
22
+ # Returns log friendly output.
23
+ #
24
+ # @return [String]
25
+ def inspect
26
+ "<#{self.class.name} (y:#{y} x:#{x} yn:#{yn} xn:#{xn})>"
27
+ end
28
+
29
+ # Returns the height of the content, or when no content, the visible height
30
+ # of the interface.
31
+ #
32
+ # @return [Fixnum]
33
+ def yn
34
+ [rows, height].max
35
+ end
36
+
37
+ # Returns the width of the content, or when no content, the visible width of
38
+ # the interface.
39
+ #
40
+ # @return [Fixnum]
41
+ def xn
42
+ [columns, width].max
43
+ end
44
+
45
+ private
46
+
47
+ attr_reader :interface
48
+
49
+ # Returns the number of lines of content for this interface.
50
+ #
51
+ # @return [Fixnum]
52
+ def rows
53
+ return height unless lines?
54
+
55
+ lines.size
56
+ end
57
+
58
+ # Returns the character length of the longest line for this interface.
59
+ #
60
+ # @return [Fixnum]
61
+ def columns
62
+ return width unless lines?
63
+
64
+ lines.map { |line| line.size }.max
65
+ end
66
+
67
+ end # ContentGeometry
68
+
69
+ end # Vedeu
@@ -0,0 +1,246 @@
1
+ module Vedeu
2
+
3
+ # Crudely corrects out of range values.
4
+ class Coordinate
5
+
6
+ attr_reader :height,
7
+ :width,
8
+ :x,
9
+ :y
10
+
11
+ def initialize(height, width, x, y)
12
+ @height = height
13
+ @width = width
14
+ @x = x
15
+ @y = y
16
+ end
17
+
18
+ # Returns log friendly output.
19
+ #
20
+ # @return [String]
21
+ def inspect
22
+ "<#{self.class.name} ( " \
23
+ "height:#{height} " \
24
+ "width:#{width} " \
25
+ "x:#{x} " \
26
+ "xn:#{xn} " \
27
+ "y:#{y} " \
28
+ "yn:#{yn} " \
29
+ ")>"
30
+ end
31
+
32
+ # Returns the maximum y coordinate for an area.
33
+ #
34
+ # @example
35
+ # # y = 2
36
+ # # height = 4
37
+ # yn # => 6
38
+ #
39
+ # @return [Fixnum]
40
+ def yn
41
+ if height <= 0
42
+ 0
43
+
44
+ else
45
+ y + height
46
+
47
+ end
48
+ end
49
+
50
+ # Returns the maximum x coordinate for an area.
51
+ #
52
+ # @example
53
+ # # x = 5
54
+ # # width = 20
55
+ # xn # => 25
56
+ #
57
+ # @return [Fixnum]
58
+ def xn
59
+ if width <= 0
60
+ 0
61
+
62
+ else
63
+ x + width
64
+
65
+ end
66
+ end
67
+
68
+ # Returns the index for a given y position.
69
+ #
70
+ # @example
71
+ # # y_range = [7, 8, 9, 10]
72
+ # # y = 8
73
+ # y_index # => 1 # because (y_range[1] = 8)
74
+ # y_index(10) # => 3
75
+ # y_index(5) # => 0
76
+ # y_index(15) # => 3
77
+ #
78
+ # @param position [Fixnum]
79
+ # @return [Fixnum]
80
+ def y_index(position = y)
81
+ if height <= 0 || position <= y
82
+ 0
83
+
84
+ elsif position >= yn
85
+ yn_index
86
+
87
+ else
88
+ y_range.index(position)
89
+
90
+ end
91
+ end
92
+
93
+ # Returns the index for a given x position.
94
+ #
95
+ # @example
96
+ # # x_range = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
97
+ # # x = 8
98
+ # x_index # => 4 # because (x_range[4] = 8)
99
+ # x_index(11) # => 7
100
+ # x_index(2) # => 0
101
+ # x_index(15) # => 9
102
+ #
103
+ # @param position [Fixnum]
104
+ # @return [Fixnum]
105
+ def x_index(position = x)
106
+ if width <= 0 || position <= x
107
+ 0
108
+
109
+ elsif position >= xn
110
+ xn_index
111
+
112
+ else
113
+ x_range.index(position)
114
+
115
+ end
116
+ end
117
+
118
+ # Returns the y coordinate for a given index.
119
+ #
120
+ # @example
121
+ # # y_range = [7, 8, 9, 10, 11]
122
+ # y_position # => 7
123
+ # y_position(-2) # => 7
124
+ # y_position(2) # => 9
125
+ # y_position(7) # => 11
126
+ #
127
+ # @param index [Fixnum]
128
+ # @return [Fixnum]
129
+ def y_position(index = 0)
130
+ if index <= 0
131
+ y
132
+
133
+ elsif index > yn_index
134
+ yn
135
+
136
+ else
137
+ y_range[index]
138
+
139
+ end
140
+ end
141
+
142
+ # Returns the x coordinate for a given index.
143
+ #
144
+ # @example
145
+ # # x_range = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
146
+ # x_position # => 4
147
+ # x_position(-2) # => 4
148
+ # x_position(2) # => 6
149
+ # x_position(15) # => 13
150
+ #
151
+ # @param index [Fixnum]
152
+ # @return [Fixnum]
153
+ def x_position(index = 0)
154
+ if index <= 0
155
+ x
156
+
157
+ elsif index > xn_index
158
+ xn
159
+
160
+ else
161
+ x_range[index]
162
+
163
+ end
164
+ end
165
+
166
+ private
167
+
168
+ attr_reader :height, :width
169
+
170
+ # Returns the maximum y index for an area.
171
+ #
172
+ # @example
173
+ # # height = 3
174
+ # yn_index # => 2
175
+ #
176
+ # @return [Fixnum]
177
+ def yn_index
178
+ return 0 if y_indices.empty?
179
+
180
+ y_indices.last
181
+ end
182
+
183
+ # Returns the maximum x index for an area.
184
+ #
185
+ # @example
186
+ # # width = 6
187
+ # xn_index # => 5
188
+ #
189
+ # @return [Fixnum]
190
+ def xn_index
191
+ return 0 if x_indices.empty?
192
+
193
+ x_indices.last
194
+ end
195
+
196
+ # Returns the same as #y_range, except as indices of an array.
197
+ #
198
+ # @example
199
+ # # height = 4
200
+ # y_indices # => [0, 1, 2, 3]
201
+ #
202
+ # @return [Array]
203
+ def y_indices
204
+ (0...height).to_a
205
+ end
206
+
207
+ # Returns the same as #x_range, except as indices of an array.
208
+ #
209
+ # @example
210
+ # # width = 10
211
+ # x_indices # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
212
+ #
213
+ # @return [Array]
214
+ def x_indices
215
+ (0...width).to_a
216
+ end
217
+
218
+ # Returns an array with all coordinates from x to xn.
219
+ #
220
+ # @example
221
+ # # width = 10
222
+ # # x = 4
223
+ # # xn = 14
224
+ # x_range # => [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
225
+ #
226
+ # @return [Array]
227
+ def x_range
228
+ (x...xn).to_a
229
+ end
230
+
231
+ # Returns an array with all coordinates from y to yn.
232
+ #
233
+ # @example
234
+ # # height = 4
235
+ # # y = 7
236
+ # # yn = 11
237
+ # y_range # => [7, 8, 9, 10]
238
+ #
239
+ # @return [Array]
240
+ def y_range
241
+ (y...yn).to_a
242
+ end
243
+
244
+ end # Coordinate
245
+
246
+ end # Vedeu
@@ -8,6 +8,8 @@ module Vedeu
8
8
 
9
9
  extend self
10
10
 
11
+ # Produces the foreground named colour escape sequence hash.
12
+ #
11
13
  # @return [Hash]
12
14
  def codes
13
15
  {
@@ -22,6 +24,15 @@ module Vedeu
22
24
  default: 39,
23
25
  }
24
26
  end
27
+ alias_method :foreground_codes, :codes
28
+
29
+ # Produces the background named colour escape sequence hash from the
30
+ # foreground escape sequence hash.
31
+ #
32
+ # @return [Hash]
33
+ def background_codes
34
+ Esc.codes.inject({}) { |h, (k, v)| h.merge(k => v + 10) }
35
+ end
25
36
 
26
37
  # Dynamically creates methods for each terminal named colour. When a block
27
38
  # is given, then the colour is reset to 'default' once the block is called.
@@ -36,15 +47,31 @@ module Vedeu
36
47
  # Esc.on_blue { 'some text' } # => "\e[44msome text\e[49m"
37
48
  #
38
49
  # @return [String]
39
- codes.each do |key, code|
50
+ foreground_codes.each do |key, code|
40
51
  define_method(key) do |&blk|
41
52
  "\e[#{code}m" + (blk ? blk.call + "\e[39m" : '')
42
53
  end
54
+ end
55
+
56
+ background_codes.each do |key, code|
43
57
  define_method('on_' + key.to_s) do |&blk|
44
- "\e[#{code + 10}m" + (blk ? blk.call + "\e[49m" : '')
58
+ "\e[#{code}m" + (blk ? blk.call + "\e[49m" : '')
45
59
  end
46
60
  end
47
61
 
62
+ # Return the stream with the escape sequences escaped so that they can be
63
+ # printed to the terminal instead of being interpreted by the terminal which
64
+ # will render them. This way we can see what escape sequences are being sent
65
+ # along with the content.
66
+ #
67
+ # @param stream [String]
68
+ # @return [String]
69
+ def escape(stream = '')
70
+ return stream if stream.nil? || stream.empty?
71
+
72
+ stream.gsub(/\e/, '\\e')
73
+ end
74
+
48
75
  # Return the escape sequence required to position the cursor at a particular
49
76
  # point on the screen. When passed a block, will do the aforementioned,
50
77
  # call the block and then reposition to this location.