Skip to content

Commit c8ebb5d

Browse files
authored
Merge pull request #221 from Tim-Blokdijk/edge
Make ActiveRecord#find work with an id array (on base model or scope) + tests
2 parents 67de79f + adcc68f commit c8ebb5d

File tree

5 files changed

+170
-18
lines changed

5 files changed

+170
-18
lines changed

CONTRIBUTING.md

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ If you're new to Hyperstack but have experience with Ruby (and Rails) and would
55
that way you understand the basic capabilities and lingo of Hyperstack.
66

77
Next would be to start an experimental project that's based on the *edge* Hyperstack codebase.
8-
If you just want to build a website with Hyperstack without contributing to Hyperstack itself you're better of sticking to released versions of Hyperstack.
8+
If you just want to build a project with Hyperstack without contributing to Hyperstack itself you're better of sticking to released versions of Hyperstack.
99
But presuming you do want to contribute you can change you `Gemfile` in the following way to get your project on *edge*.
1010

1111
```ruby
@@ -27,22 +27,45 @@ The *edge* branch is the latest work in progress, where specs (automated tests)
2727
The difference between *edge* and *master*, is that *master* guarantees that all specs across all gems pass, plus *master* is the branch from which new versions are released.
2828

2929
With this configuration you can track development of Hyperstack itself and discuss changes with the other developers.
30-
It's the basic starting point from which you can make different types of contributions listed below under the separate headings.
3130

32-
## If you would like to contribute code to Hyperstack
31+
In the following sections we explain how to make different types of contributions.
32+
- Contributing code to Hyperstack
33+
- Running tests for your code
34+
- Adding your own tests
35+
- Improving the Hyperstack documentation
36+
- If you think you can improve the website
37+
- When you find a possible bug
38+
- Fixing a bug
39+
40+
## Contributing code to Hyperstack
3341

3442
With the `Gemfile` configuration above you can track Hyperstack development. But you can't contribute code.
3543

3644
For that you need to `git clone https://github.com/hyperstack-org/hyperstack.git`
3745
Cd into the directory `cd hyperstack`
3846
And change to the *edge* branch: `git checkout edge` (*edge* is the default branch but just to be sure).
3947

40-
Now you're free to fix bugs and create new features.
41-
Reconfigure the `Gemfile` of your website project with a [filesystem path](https://bundler.io/gemfile.html) to create a local development environment.
48+
This gives you a local copy of the Hyperstack codebase on your system.
49+
You will have to reconfigure the `Gemfile` of your own website project with a [filesystem path](https://bundler.io/gemfile.html) so it uses this local Hyperstack copy.
50+
4251
```
43-
TODO: Actually provide an example Gemfile..
52+
gem 'rails-hyperstack', path: '~/path/to/hyperstack/ruby/rails-hyperstack'
53+
gem 'hyper-component', path: '~/path/to/hyperstack/ruby/hyper-component'
54+
gem 'hyper-i18n', path: '~/path/to/hyperstack/ruby/hyper-i18n'
55+
gem 'hyper-model', path: '~/path/to/hyperstack/ruby/hyper-model'
56+
gem 'hyper-operation', path: '~/path/to/hyperstack/ruby/hyper-operation'
57+
gem 'hyper-router', path: '~/path/to/hyperstack/ruby/hyper-router'
58+
gem 'hyper-state', path: '~/path/to/hyperstack/ruby/hyper-state'
59+
gem 'hyperstack-config', path: '~/path/to/hyperstack/ruby/hyperstack-config'
60+
gem 'hyper-trace', path: '~/path/to/hyperstack/ruby/hyper-trace', group: :development
61+
#gem 'hyper-store', path: '~/path/to/hyperstack/ruby/hyper-store' # Extra (legacy?)
4462
```
45-
And if your improvements could be interesting to others then push it to Github and create a pull request.
63+
64+
Or use `bundle config local.GEM_NAME /path/to/hyperstack` as described [here](https://rossta.net/blog/how-to-specify-local-ruby-gems-in-your-gemfile.html). But I would recommend the Gemfile with a local path approach.
65+
Use `bundle config --delete local.GEM_NAME` to remove a `bundle config local` configuration.
66+
67+
This setup provides a local Hyperstack development environment. You're now able to fix bugs and create new features within the Hyperstack code itself.
68+
If your improvements could be interesting to others then push it to Github and create a pull request.
4669
Then keep reminding the existing developers that you would like your code pulled into the Hyperstack repository.
4770
When they find the time to look at it and like your code they will kindly ask you to also write some specs before your code is merged. That's a good thing, your code is considered valuable, but does require those tests.
4871
Please understand that your code can also be rejected because it has security issues, is slow, hard to maintain or buggy (among other things).
@@ -54,7 +77,37 @@ But Hyperstack and Opal are quite happily pushing boundaries, so we might like y
5477

5578
Hyperstack's [license is MIT](https://github.com/hyperstack-org/hyperstack/blob/edge/LICENSE). All code contributions must be under this license. If code is submitted under a different open source license then this must be explicitly stated. Preferably with an explanation why it can't be MIT.
5679

57-
## If you would like to improve the Hyperstack documentation
80+
### Running tests for your code
81+
82+
Hyperstack has a comprehensive automated test system. Changes to code must be accompanied with the necessary tests.
83+
This is how you setup the test environment on your local development system:
84+
85+
- You do the `git clone https://github.com/hyperstack-org/hyperstack.git` as before.
86+
- Now you enter the gem you would like to run the tests for. Lets say you change directory to the hyper-model gem `cd ~/path/to/hyperstack/ruby/hyper-model`
87+
- Optionally but recommended: Create a RVM environment by adding the `.ruby-gemset` and `.ruby-version` files, run `cd .` to reload RVM.
88+
- Install bundler `gem install bundler` then run `bundle install` to pull in the gems needed for testing.
89+
- Then you have to setup the test environment by running `rake spec:prepare`, this creates the test database and tables.
90+
91+
After this call `rspec spec` to run the tests.
92+
93+
If all test pass you know your changes to the Hyperstack code did not break any existing functionality.
94+
Please understand that tests can sometimes be flaky, re-run tests if needed. Sometimes it's just the phase of the moon.
95+
96+
### Adding your own tests
97+
98+
Cleaning up and improving the existing tests is a great and "safe" way to contribute and get experience with the Hyperstack codebase.
99+
100+
**TODO:** Pointers about directory structure.
101+
102+
- Test one thing at a time, don't write one large test.
103+
- Check the before state, call the code you want to test, check if the before state has changed to the expected state.
104+
- Test the interface, the internals of the implementation should keep some flexibility.
105+
- Watch out with testing things that use Date/Time, you don't want your test to fail when it's run on the 29th of February or when run in a different timezone.
106+
- Don't check if `string1.include?(string2)` if string2 can be an empty string, like "". As that would pass.
107+
- Tests are a development tool, flaky or slow tests that don't cover enough have a negative value.
108+
- Test your feature with different types of input (nil, empty string, empty array, false, zero, negative dates). Don't test with every day of the year if it exesersizes the same codepath as with the other dates.
109+
110+
## Improving the Hyperstack documentation
58111

59112
Each page on [the website](https://hyperstack.org) has an ***Improve this page*** button which will allow you to edit the underlying markdown file on Github and create a ***pull request***. This is to make it as easy as possible to contribute to the documentation.
60113
And make small fixes quickly.
@@ -69,19 +122,19 @@ The website's code can be found in [this repository](https://github.com/hypersta
69122
By running `git clone https://github.com/hyperstack-org/website.git` you can check out your own copy.
70123
Please note that this repository does not contain the documentation. The website pulls the most recent markdown files from the *edge* hyperstack repository.
71124

72-
Before you write code to change the website, please create an issue describing your plans and reach out to us in the Gitter chat. Our goal for this site is that it acts as a showcase for all that Hyperstack can do, so your creativity is very welcome.
125+
Before you write code to change the website, please create an issue describing your plans and reach out to us in Slack chat. Our goal for this site is that it acts as a showcase for all that Hyperstack can do, so your creativity is very welcome.
73126

74-
## If you found a possible bug
127+
## When you find a possible bug
75128

76-
You can ask on [gitter chat](https://gitter.im/ruby-hyperloop/chat) if you're making a mistake or actually found a bug.
77-
Also check the GitHub issue list and if you don't find it mentioned there, please create an issue.
129+
You can ask on [Slack chat](https://hyperstack-org.slack.com) if you're making a mistake or actually found a bug. (get a account via the "Join Slack" button on the [homepage](https://hyperstack.org))
130+
Also check the [GitHub issue list](https://github.com/hyperstack-org/hyperstack/issues) and if you don't find it mentioned there, please create an issue.
78131
If you can reproduce the problem in a branch you push to GitHub we will love you even more.
79132

80133
We also have a [feature matrix](https://github.com/hyperstack-org/hyperstack/blob/edge/docs/feature_matrix.md), which is an attempt to list known issues and the current status.
81134
Having people expanding and maintaining this table would be excellent.
82135

83-
## If you would like to fix a bug
136+
## Fixing a bug
84137

85-
Please ask in [gitter chat](https://gitter.im/ruby-hyperloop/chat) if you need pointers. There is always tons to do so we would appreciate the help.
138+
Please ask in [Slack chat](https://hyperstack-org.slack.com) if you need pointers. There is always tons to do so we would appreciate the help.
86139
You can see the list of GitHub issues labelled '[Help Wanted](https://github.com/hyperstack-org/hyperstack/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)'
87140
or look at the [feature matrix](https://github.com/hyperstack-org/hyperstack/blob/edge/docs/feature_matrix.md) for things that have the status 'bugged'.

ruby/hyper-model/lib/reactive_record/active_record/class_methods.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ def __hyperstack_preprocess_attrs(attrs)
5959
attrs.each { |attr, value| dealiased_attrs[_dealias_attribute(attr)] = value }
6060
end
6161

62-
def find(id)
63-
find_by(primary_key => id)
62+
def find(*args)
63+
args = args[0] if args[0].is_a? Array
64+
return args.collect { |id| find(id) } if args.count > 1
65+
find_by(primary_key => args[0])
6466
end
6567

6668
def find_by(attrs = {})

ruby/hyper-model/lib/reactive_record/active_record/reactive_record/collection.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,10 @@ def find_by(attrs)
594594
r.backing_record.sync_attributes(attrs).set_ar_instance!
595595
end
596596

597-
def find(id)
598-
find_by @target_klass.primary_key => id
597+
def find(*args)
598+
args = args[0] if args[0].is_a? Array
599+
return args.collect { |id| find(id) } if args.count > 1
600+
find_by(@target_klass.primary_key => args[0])
599601
end
600602

601603
def _find_by_initializer(scope, attrs)

ruby/hyper-model/spec/batch3/aaa_edge_cases_spec.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class TestComponent77 < HyperComponent
144144
end
145145

146146
describe 'can use finder methods on scopes' do
147+
147148
before(:each) do
148149
isomorphic do
149150
Todo.finder_method :with_title do |title|
@@ -157,6 +158,7 @@ class TestComponent77 < HyperComponent
157158
FactoryBot.create(:todo, title: 'todo 2', completed: false)
158159
FactoryBot.create(:todo, title: 'secret', completed: true)
159160
end
161+
160162
it 'find_by_xxx' do
161163
expect_promise do
162164
Hyperstack::Model.load do
@@ -169,6 +171,7 @@ class TestComponent77 < HyperComponent
169171
end
170172
end.to be_nil
171173
end
174+
172175
it 'find' do
173176
expect_promise do
174177
Hyperstack::Model.load do
@@ -181,6 +184,23 @@ class TestComponent77 < HyperComponent
181184
end
182185
end.to be_nil
183186
end
187+
188+
it 'find with id array' do
189+
expect_promise do
190+
Hyperstack::Model.load do
191+
Todo.completed.find(1,2).map(&:id)
192+
end
193+
end.to eq(Todo.completed.find(1,2).map(&:id))
194+
end
195+
196+
it 'find with id array returns nil values' do
197+
expect_promise do
198+
Hyperstack::Model.load do
199+
Todo.completed.find(2,3,4,5,6).map {|todo| todo.is_a?(Todo) ? todo.id : todo}
200+
end
201+
end.to eq([2,nil,nil,nil,nil])
202+
end
203+
184204
it 'find_by' do
185205
expect_promise do
186206
Hyperstack::Model.load do
@@ -193,6 +213,7 @@ class TestComponent77 < HyperComponent
193213
end
194214
end.to be_nil
195215
end
216+
196217
it "and will return nil unless access is allowed" do
197218
expect_promise do
198219
Hyperstack::Model.load do
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
require 'spec_helper'
2+
require 'test_components'
3+
4+
describe 'ActiveRecord client side basics', js: true do
5+
6+
before(:all) do
7+
require 'pusher'
8+
require 'pusher-fake'
9+
Pusher.app_id = 'MY_TEST_ID'
10+
Pusher.key = 'MY_TEST_KEY'
11+
Pusher.secret = 'MY_TEST_SECRET'
12+
require 'pusher-fake/support/base'
13+
14+
Hyperstack.configuration do |config|
15+
config.transport = :pusher
16+
config.channel_prefix = 'synchromesh'
17+
config.opts = {app_id: Pusher.app_id, key: Pusher.key, secret: Pusher.secret}.merge(PusherFake.configuration.web_options)
18+
end
19+
end
20+
21+
before(:each) do
22+
# spec_helper resets the policy system after each test so we have to setup
23+
# before each test
24+
stub_const 'TestApplication', Class.new
25+
stub_const 'TestApplicationPolicy', Class.new
26+
TestApplicationPolicy.class_eval do
27+
always_allow_connection
28+
regulate_all_broadcasts { |policy| policy.send_all unless policy.obj.is_a?(Todo) && policy.obj.title == 'secret' }
29+
allow_change(to: :all, on: [:create, :update, :destroy]) { true }
30+
end
31+
size_window(:small, :portrait)
32+
end
33+
34+
describe 'finder methods' do
35+
36+
before(:each) do
37+
isomorphic do
38+
Todo.finder_method :with_title do |title|
39+
find_by_title(title)
40+
end
41+
Todo.scope :completed, -> () { where(completed: true) }
42+
end
43+
FactoryBot.create(:todo, title: 'todo 1')
44+
FactoryBot.create(:todo, title: 'todo 2')
45+
FactoryBot.create(:todo, title: 'todo 3')
46+
FactoryBot.create(:todo, title: 'todo 4')
47+
FactoryBot.create(:todo, title: 'todo 5')
48+
end
49+
50+
it 'find with id' do
51+
expect_promise do
52+
Hyperstack::Model.load do
53+
Todo.find(4).id
54+
end
55+
end.to eq(4)
56+
end
57+
58+
it 'find with id array' do
59+
expect_promise do
60+
Hyperstack::Model.load do
61+
Todo.find(1,2,3,4,5).map(&:title)
62+
end
63+
end.to eq(Todo.find(1,2,3,4,5).map(&:title))
64+
end
65+
66+
it 'find with id array returns nil value' do
67+
expect_promise do
68+
Hyperstack::Model.load do
69+
Todo.find(4,5,6).map {|todo| todo.is_a?(Todo) ? todo.title : todo}
70+
end
71+
end.to eq(Todo.find(4,5).map(&:title) + [nil])
72+
end
73+
end
74+
end

0 commit comments

Comments
 (0)