admin_it 1.0.1

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 (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