admin_it 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +5 -0
  5. data/.yardopts +3 -0
  6. data/Gemfile +5 -0
  7. data/README.md +58 -0
  8. data/README_RU.md +52 -0
  9. data/Rakefile +23 -0
  10. data/admin_it.gemspec +38 -0
  11. data/app/assets/fonts/admin_it/FontAwesome.otf +0 -0
  12. data/app/assets/fonts/admin_it/fontawesome-webfont.eot +0 -0
  13. data/app/assets/fonts/admin_it/fontawesome-webfont.svg +414 -0
  14. data/app/assets/fonts/admin_it/fontawesome-webfont.ttf +0 -0
  15. data/app/assets/fonts/admin_it/fontawesome-webfont.woff +0 -0
  16. data/app/assets/fonts/admin_it/glyphicons-halflings-regular.eot +0 -0
  17. data/app/assets/fonts/admin_it/glyphicons-halflings-regular.svg +229 -0
  18. data/app/assets/fonts/admin_it/glyphicons-halflings-regular.ttf +0 -0
  19. data/app/assets/fonts/admin_it/glyphicons-halflings-regular.woff +0 -0
  20. data/app/assets/javascript/admin_it/admin_it.js +89 -0
  21. data/app/assets/javascript/admin_it/bootstrap.min.js +6 -0
  22. data/app/assets/stylesheets/admin_it/admin_it.css +25 -0
  23. data/app/assets/stylesheets/admin_it/bootstrap-theme.min.css +7 -0
  24. data/app/assets/stylesheets/admin_it/bootstrap.min.css +7 -0
  25. data/app/assets/stylesheets/admin_it/font-awesome.min.css +4 -0
  26. data/app/views/admin_it/context/_table.html.slim +38 -0
  27. data/app/views/admin_it/context/_tiles.html.slim +23 -0
  28. data/app/views/admin_it/edit.html.slim +2 -0
  29. data/app/views/admin_it/new.html.slim +2 -0
  30. data/app/views/admin_it/shared/_child.html.slim +15 -0
  31. data/app/views/admin_it/shared/_fields.html.slim +19 -0
  32. data/app/views/admin_it/shared/_filters.html.slim +40 -0
  33. data/app/views/admin_it/shared/_form.html.slim +50 -0
  34. data/app/views/admin_it/shared/_pagination.html.slim +41 -0
  35. data/app/views/admin_it/shared/_toolbar.html.slim +30 -0
  36. data/app/views/admin_it/show.html.slim +6 -0
  37. data/app/views/admin_it/table.html.slim +2 -0
  38. data/app/views/admin_it/tiles.html.slim +2 -0
  39. data/app/views/layouts/admin_it.html.slim +37 -0
  40. data/app/views/layouts/admin_it_dialog.html.slim +8 -0
  41. data/config.ru +7 -0
  42. data/lib/admin_it/config.rb +24 -0
  43. data/lib/admin_it/context/collection_context.rb +239 -0
  44. data/lib/admin_it/context/context.rb +232 -0
  45. data/lib/admin_it/context/show_context.rb +45 -0
  46. data/lib/admin_it/context/single_context.rb +199 -0
  47. data/lib/admin_it/context/table_context.rb +66 -0
  48. data/lib/admin_it/context/tiles_context.rb +31 -0
  49. data/lib/admin_it/context.rb +6 -0
  50. data/lib/admin_it/controller.rb +42 -0
  51. data/lib/admin_it/data/active_record.rb +283 -0
  52. data/lib/admin_it/data/data_behavior.rb +18 -0
  53. data/lib/admin_it/data/hash.rb +27 -0
  54. data/lib/admin_it/data/object.rb +51 -0
  55. data/lib/admin_it/data.rb +24 -0
  56. data/lib/admin_it/definitions.rb +89 -0
  57. data/lib/admin_it/engine.rb +56 -0
  58. data/lib/admin_it/env.rb +37 -0
  59. data/lib/admin_it/errors.rb +5 -0
  60. data/lib/admin_it/field/field.rb +174 -0
  61. data/lib/admin_it/field.rb +1 -0
  62. data/lib/admin_it/filters/entity_filter.rb +4 -0
  63. data/lib/admin_it/filters/field_filter.rb +31 -0
  64. data/lib/admin_it/filters/filter.rb +150 -0
  65. data/lib/admin_it/filters/value_filter.rb +52 -0
  66. data/lib/admin_it/filters.rb +4 -0
  67. data/lib/admin_it/helpers/field.rb +25 -0
  68. data/lib/admin_it/helpers/input.rb +22 -0
  69. data/lib/admin_it/helpers/page.rb +26 -0
  70. data/lib/admin_it/helpers/table.rb +85 -0
  71. data/lib/admin_it/helpers/tiles.rb +17 -0
  72. data/lib/admin_it/helpers/toolbar.rb +40 -0
  73. data/lib/admin_it/helpers/top_menu.rb +39 -0
  74. data/lib/admin_it/helpers.rb +12 -0
  75. data/lib/admin_it/locales/en.yml +14 -0
  76. data/lib/admin_it/locales/ru.yml +14 -0
  77. data/lib/admin_it/renderable.rb +18 -0
  78. data/lib/admin_it/resource.rb +292 -0
  79. data/lib/admin_it/utils.rb +21 -0
  80. data/lib/admin_it/version.rb +5 -0
  81. data/lib/admin_it.rb +19 -0
  82. data/lib/extend_it/array_of.rb +181 -0
  83. data/lib/extend_it/asserts.rb +38 -0
  84. data/lib/extend_it/callbacks.rb +105 -0
  85. data/lib/extend_it/caller.rb +35 -0
  86. data/lib/extend_it/class.rb +47 -0
  87. data/lib/extend_it/dsl.rb +94 -0
  88. data/lib/extend_it/refines.rb +6 -0
  89. data/lib/extend_it/symbolize.rb +39 -0
  90. data/lib/extend_it.rb +5 -0
  91. data/spec/internal/config/database.yml +3 -0
  92. data/spec/internal/config/routes.rb +3 -0
  93. data/spec/internal/db/combustion_test.sqlite +0 -0
  94. data/spec/internal/db/schema.rb +3 -0
  95. data/spec/internal/log/.gitignore +1 -0
  96. data/spec/internal/public/favicon.ico +0 -0
  97. data/spec/lib/context/collection_context_spec.rb +20 -0
  98. data/spec/lib/context/context_spec.rb +28 -0
  99. data/spec/lib/context/single_context_spec.rb +26 -0
  100. data/spec/lib/data/object_spec.rb +29 -0
  101. data/spec/lib/definitions_spec.rb +171 -0
  102. data/spec/lib/field_spec.rb +62 -0
  103. data/spec/lib/resource_spec.rb +39 -0
  104. data/spec/lib/utils_spec.rb +39 -0
  105. data/spec/spec_helper.rb +21 -0
  106. data/spec/support/example_groups/context_example_group.rb +50 -0
  107. data/spec/support/shared_examples/context.rb +2 -0
  108. metadata +337 -0
@@ -0,0 +1,171 @@
1
+ require 'spec_helper'
2
+
3
+ describe AdminIt::ResourceDefinition do
4
+ subject { described_class.new(object_resource) }
5
+
6
+ it 'delegates methods to fake context' do
7
+ subject.field :name
8
+ expect(
9
+ subject.instance_variable_get(:@fake).find_field(:name)
10
+ ).to_not be_nil
11
+ end
12
+
13
+ describe '#default_context' do
14
+ it 'returns first single context name by default' do
15
+ subject.contexts(%i(tiles edit table))
16
+ expect(subject.default_context).to eq :edit
17
+ end
18
+
19
+ it 'drops unknown context name' do
20
+ subject.default_context(:test)
21
+ expect(subject.default_context).to eq :show
22
+ end
23
+
24
+ it 'sets known context name' do
25
+ subject.default_context(:table)
26
+ expect(subject.default_context).to eq :table
27
+ end
28
+ end
29
+
30
+ describe '#icon' do
31
+ it 'has nil icon by default' do
32
+ expect(subject.icon).to be_nil
33
+ end
34
+
35
+ it 'sets icon as string' do
36
+ subject.icon :test
37
+ expect(subject.icon).to eq 'test'
38
+ end
39
+ end
40
+
41
+ describe '#single' do
42
+ it { expect(subject.single <= AdminIt::SingleContext).to be_true }
43
+
44
+ it 'copies fields from fake context' do
45
+ subject.field :name
46
+ expect(subject.single.fields[:name]).to_not be_nil
47
+ end
48
+
49
+ it 'yields block in single instance context' do
50
+ expect(subject.single).to receive(:instance_eval)
51
+ subject.single { }
52
+ end
53
+ end
54
+
55
+ describe '#collection' do
56
+ it { expect(subject.collection <= AdminIt::CollectionContext).to be_true }
57
+
58
+ it 'copies fields from single context' do
59
+ subject.field :name
60
+ expect(subject.collection.find_field(:name)).to_not be_nil
61
+ end
62
+
63
+ it 'yields block in collection instance context' do
64
+ expect(subject.collection).to receive(:instance_eval)
65
+ subject.collection { }
66
+ end
67
+ end
68
+
69
+ describe '#context' do
70
+ it 'yields block in context instance context' do
71
+ expect(subject.context(:edit)).to receive(:instance_eval)
72
+ subject.context(:edit) { }
73
+ end
74
+
75
+ it 'creates context on-demand' do
76
+ subject.context :test, context_class: AdminIt::TilesContext
77
+ expect(subject.contexts.map(&:context_name)).to include :test
78
+ expect(subject.context(:test) <= AdminIt::TilesContext).to be_true
79
+ end
80
+
81
+ context 'with some fields' do
82
+ before do
83
+ subject.field :name
84
+ subject.single { field :amount }
85
+ subject.collection { field :size }
86
+ end
87
+
88
+ it 'copies fields from single fake context for singles' do
89
+ subject.context(:edit) { field :title }
90
+ expect(subject.context(:edit).fields[:title]).to_not be_nil
91
+ expect(subject.context(:edit).fields[:name]).to_not be_nil
92
+ expect(subject.context(:edit).fields[:amount]).to_not be_nil
93
+ expect(subject.context(:edit).fields[:size]).to be_nil
94
+ end
95
+
96
+ it 'copies fields from collection fake context for collections' do
97
+ subject.context(:table) { field :rows }
98
+ expect(subject.context(:table).fields[:rows]).to_not be_nil
99
+ expect(subject.context(:table).fields[:amount]).to be_nil
100
+ expect(subject.context(:table).fields[:name]).to_not be_nil
101
+ expect(subject.context(:table).fields[:size]).to_not be_nil
102
+ end
103
+
104
+ it 'copies fields from single fake context for on-demand singles' do
105
+ subject.context :test, context_class: AdminIt::EditContext do
106
+ field :title
107
+ end
108
+ expect(subject.context(:test).fields[:title]).to_not be_nil
109
+ expect(subject.context(:test).fields[:name]).to_not be_nil
110
+ expect(subject.context(:test).fields[:amount]).to_not be_nil
111
+ expect(subject.context(:test).fields[:size]).to be_nil
112
+ end
113
+
114
+ it 'copies fields from col fake context for on-demand collections' do
115
+ subject.context :test, context_class: AdminIt::TableContext do
116
+ field :rows
117
+ end
118
+ expect(subject.context(:test).fields[:rows]).to_not be_nil
119
+ expect(subject.context(:test).fields[:name]).to_not be_nil
120
+ expect(subject.context(:test).fields[:amount]).to be_nil
121
+ expect(subject.context(:test).fields[:size]).to_not be_nil
122
+ end
123
+ end
124
+ end
125
+
126
+ describe '#contexts' do
127
+ it 'yields block in each context instance context' do
128
+ subject.contexts.each { |c| expect(c).to receive(:instance_eval) }
129
+ subject.contexts { }
130
+ end
131
+
132
+ it 'reorders contexts' do
133
+ list = %i(list tiles show table edit new)
134
+ subject.contexts(*list)
135
+ expect(subject.contexts.map(&:context_name)).to eq list
136
+ end
137
+
138
+ it 'reduces contexts' do
139
+ subject.contexts(:tiles, :table)
140
+ expect(subject.contexts.size).to eq 2
141
+ end
142
+ end
143
+
144
+ describe '#exclude_collection' do
145
+ it 'removes all collection contexts' do
146
+ subject.exclude_collection
147
+ expect(subject.contexts.map(&:context_name))
148
+ .to eq described_class::SINGLE
149
+ end
150
+ end
151
+
152
+ describe '#exclude_single' do
153
+ it 'removes all single contexts' do
154
+ subject.exclude_single
155
+ expect(subject.contexts.map(&:context_name))
156
+ .to eq described_class::COLLECTIONS
157
+ end
158
+ end
159
+
160
+ describe '#exclude_context' do
161
+ it 'removes contexts' do
162
+ subject.exclude_context(%i(show edit new table))
163
+ expect(subject.contexts.map(&:context_name)).to eq %i(tiles list)
164
+ end
165
+ end
166
+ end
167
+
168
+ describe AdminIt do
169
+ describe '.resource' do
170
+ end
171
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe AdminIt::Field, type: :context do
4
+ subject { described_class.new(:name, object_class) }
5
+
6
+ it 'has name reader' do
7
+ expect(subject.name).to eq :name
8
+ end
9
+
10
+ it 'converts name to symbol' do
11
+ expect(described_class.new('test', object_class).name).to eq :test
12
+ end
13
+
14
+ it 'has :unknown type by default' do
15
+ expect(subject.type).to eq :unknown
16
+ end
17
+
18
+ it 'has DSL type setter' do
19
+ subject.type :string
20
+ expect(subject.type).to eq :string
21
+ end
22
+
23
+ it 'rejects reads of write-only fields' do
24
+ f = described_class.new(:name, object_class, readable: false)
25
+ expect { f.read(Object.new) }.to raise_error AdminIt::FieldReadError
26
+ end
27
+
28
+ it 'rejects writes to read-only fields' do
29
+ f = described_class.new(:name, object_class, writable: false)
30
+ expect { f.write(Object.new, 1) }.to raise_error AdminIt::FieldWriteError
31
+ end
32
+
33
+ it 'calls DSL defined reader for read value' do
34
+ subject.read { |obj| 10 }
35
+ expect(subject.read(Object.new)).to eq 10
36
+ end
37
+
38
+ it 'calls DSL defined writer for write value' do
39
+ subject.write { |obj, value| obj[:test] = value }
40
+ expect(subject.write({}, 10)).to eq test: 10
41
+ end
42
+
43
+ it 'doesn\'t implements value reading' do
44
+ expect { subject.send(:read_value, Object.new) }
45
+ .to raise_error NotImplementedError
46
+ end
47
+
48
+ it 'doesn\'t implements value writing' do
49
+ expect { subject.send(:write_value, Object.new, 'test') }
50
+ .to raise_error NotImplementedError
51
+ end
52
+
53
+ it 'has #hide' do
54
+ subject.hide
55
+ expect(subject.visible?).to be_false
56
+ end
57
+
58
+ it 'has #show' do
59
+ subject.show
60
+ expect(subject.visible?).to be_true
61
+ end
62
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe AdminIt::Resource do
4
+ subject do
5
+ object_class
6
+ described_class.new(:object_class)
7
+ end
8
+
9
+ it 'resolves entity_class from name' do
10
+ expect(subject.entity_class).to eq ObjectClass
11
+ end
12
+
13
+ it 'makes default display name' do
14
+ expect(subject.display_name).to eq 'Object Classes'
15
+ end
16
+
17
+ describe '#initialize' do
18
+ it 'checks name to be a symbol' do
19
+ object_class
20
+ expect(AdminIt::Utils)
21
+ .to receive(:assert_symbol_arg!)
22
+ .with(:object_class, name: 'name')
23
+ .and_call_original
24
+ described_class.new(:object_class)
25
+ end
26
+ end
27
+
28
+ context 'with single context' do
29
+ before { subject.contexts << single_object_context_class }
30
+
31
+ it 'provides hash-like reader for contexts' do
32
+ expect(subject[:single]).to eq single_object_context_class
33
+ end
34
+
35
+ it 'provides context names' do
36
+ expect(subject.contexts_names).to eq [:single]
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe AdminIt::Utils do
4
+ subject { AdminIt::Utils }
5
+
6
+ describe '.assert_symbol_arg' do
7
+ it 'just passes throw symbol args' do
8
+ expect(subject.assert_symbol_arg(:test)).to eq :test
9
+ end
10
+
11
+ it 'converts string to symbol' do
12
+ expect(subject.assert_symbol_arg('test')).to eq :test
13
+ end
14
+
15
+ it 'calls block if it given for non-symbol args' do
16
+ test = false
17
+ subject.assert_symbol_arg(10) { |value| test = value }
18
+ expect(test).to eq 10
19
+ end
20
+ end
21
+
22
+ describe '.assert_symbol_arg!' do
23
+ def some_method(name)
24
+ subject.assert_symbol_arg!(10, name)
25
+ end
26
+
27
+ it 'calls .assert_symbol_arg' do
28
+ expect(subject).to receive(:assert_symbol_arg).with(:test)
29
+ subject.assert_symbol_arg!(:test, name: 'name')
30
+ end
31
+
32
+ it 'raises ArgumentError for wrong args' do
33
+ expect { some_method('arg') }.to raise_error(
34
+ ArgumentError,
35
+ 'Argument arg for some_method should be a String or Symbol'
36
+ )
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'combustion'
5
+ require 'capybara/rspec'
6
+
7
+ Combustion.initialize! :all
8
+
9
+ require 'rspec/rails'
10
+ require 'capybara/rails'
11
+
12
+ Dir[File.join(File.dirname(__FILE__), 'support', '**', '*.rb')].each do |file|
13
+ require file
14
+ end
15
+
16
+ RSpec.configure do |config|
17
+ config.treat_symbols_as_metadata_keys_with_true_values = true
18
+ config.run_all_when_everything_filtered = true
19
+ config.filter_run :focus
20
+ config.order = 'random'
21
+ end
@@ -0,0 +1,50 @@
1
+ #
2
+ # Helpers for Context testing
3
+ #
4
+ # @author Alexey Ovchinnikov <alexiss@cybernetlab.ru>
5
+ #
6
+ module ContextExampleGroup
7
+ def self.included(base)
8
+ base.instance_eval do
9
+ metadata[:type] = :context
10
+
11
+ after do
12
+ if Object.const_defined?(:ObjectClass)
13
+ Object.send(:remove_const, :ObjectClass)
14
+ end
15
+ end
16
+
17
+ let(:object_class) { Object.const_set(:ObjectClass, Class.new(Object)) }
18
+
19
+ let(:object) { object_class.new }
20
+
21
+ let(:object_resource) do
22
+ object_class
23
+ AdminIt::Resource.new(:object_class)
24
+ end
25
+
26
+ let(:object_context_class) do
27
+ AdminIt::Context.create_class(:object, object_resource)
28
+ end
29
+ let(:object_context) { object_context_class.new }
30
+
31
+ let(:single_object_context_class) do
32
+ AdminIt::SingleContext.create_class(:single, object_resource)
33
+ end
34
+ let(:single_object_context) { single_object_context_class.new }
35
+
36
+ let(:collection_object_context_class) do
37
+ AdminIt::CollectionContext.create_class(:collection, object_resource)
38
+ end
39
+ let(:collection_object_context) { collection_object_context_class.new }
40
+ end
41
+ end
42
+
43
+ RSpec.configure do |config|
44
+ config.include(
45
+ self,
46
+ type: :context,
47
+ example_group: { file_path: %r(spec/lib) }
48
+ )
49
+ end
50
+ end
@@ -0,0 +1,2 @@
1
+ shared_examples 'context' do
2
+ end