akasha 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '09372b1685568c249f091ff1bbbf4915bb574b91'
4
- data.tar.gz: 982ef7993d2087b2bd55f424228ba5bdf31d867a
3
+ metadata.gz: 4078cc01d0c132a3b675ed21de42246880643c49
4
+ data.tar.gz: 0562b5f9607dea81f47720c680d3f5517c5190e0
5
5
  SHA512:
6
- metadata.gz: 59730ad9b8f01e86d5fdfd01945fea0586002972571595f03810d7af600f9d864a5d5c22fc1e7092a68067f6fd310c16f825980b8515d71f7933a05f2362dfc1
7
- data.tar.gz: 1fb02d4091efe00a925af1ec4d15990c0cc0c61aaaf64a1c64de36a63dcc3eea3b73465d5e558880ad46393d90146dfb6a788d5e5544f7afcdf68bda67f38d78
6
+ metadata.gz: 114a107b63f0f25d9e21b5a00c8a4277885ca705ff7d324199a89e54004c41f410380608d7ba994e8d2f0e3dab220c8a09443c56ef36bc69c551f061d23b3366
7
+ data.tar.gz: 4ef66f8424b38a10ac6b8b4095e9a42f985babf00966d5e7d8928cc8fd588768cf1ee45baa516fe094a8b717ee560d44e5f5856028aa6af97eee806b88c3c1ca
@@ -1,6 +1,16 @@
1
1
  Style/FrozenStringLiteralComment:
2
2
  Enabled: false
3
+ Metrics/AbcSize:
4
+ Max: 17
5
+ Metrics/BlockLength:
6
+ Exclude:
7
+ - spec/**/*_spec.rb
8
+ - akasha.gemspec
9
+ Metrics/ClassLength:
10
+ Max: 110
3
11
  Metrics/LineLength:
4
12
  Max: 120
5
13
  Metrics/MethodLength:
6
14
  Max: 15
15
+ Rails/Output:
16
+ Enabled: false
@@ -1,6 +1,10 @@
1
1
  # Enables Travis to use their new container-based infrastructure
2
2
  sudo: false
3
3
 
4
+ # Integration tests are using docker-compose
5
+ services:
6
+ - docker
7
+
4
8
  # Build for Ruby
5
9
  language: ruby
6
10
 
@@ -15,35 +19,23 @@ before_install:
15
19
  - gem update bundler
16
20
 
17
21
  # Specify which ruby versions you wish to run your tests on, each version will be used
18
- rvm:
19
- - 2.2.9
20
- - 2.3.6
21
- - 2.4.3
22
- - 2.5.0
23
-
24
- # Define how to run your tests (defaults to `bundle exec rake` or `rake` depending on whether you have a `Gemfile`)
25
- script: "bundle exec rake"
26
-
27
- # Define tasks to be completed before and after tests run . Will allow folding of content on frontend
28
- #before_script:
29
- # - command_1
30
- # - command_2
31
- #
32
- #after_script:
33
- # - command_1
34
- # - command_2
35
-
36
- # Specify the recipients for email notification
37
- #notifications:
38
- # recipients:
39
- # - email-address-1
40
- # - email-address-2
22
+ matrix:
23
+ include:
24
+ - rvm: 2.3.6
25
+ - rvm: 2.5.1
26
+ - env: INTEGRATION_TESTS=true
27
+
28
+ # Define how to run your tests.
29
+ script:
30
+ - |
31
+ # Run either integration tests or specs.
32
+ case "$INTEGRATION_TESTS" in
33
+ true) bin/integration-tests.sh ;;
34
+ *) bundle exec rspec --tag ~integration ;;
35
+ esac
36
+ # Check if conventions are being followed.
37
+ - bundle exec rake rubocop
41
38
 
42
39
  # Disable email notifications
43
- #notifications:
44
- # disabled: true
45
-
46
- # notifications:
47
- # webhooks:
48
- # urls:
49
- # - https://webhooks.gitter.im/e/c6dbb9323007dfcf81df
40
+ notifications:
41
+ disabled: true
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 0.3.0
4
+
5
+ * Asynchronous event listeners (`AsyncEventRouter`).
6
+ * Simplified initialization of event- and command routers.
7
+ * Remove dependency on the `http_event_store` gem.
8
+ * `Event#metadata` is no longer OpenStruct.
9
+
3
10
  ## Version 0.2.0
4
11
 
5
12
  * Synchronous event listeners (see `examples/sinatra/app.rb`).
@@ -0,0 +1,24 @@
1
+ FROM ruby:2.5.1-alpine3.7
2
+ RUN set -eux; \
3
+ apk update; \
4
+ apk add git openssl; \
5
+ apk add build-base libffi-dev
6
+
7
+ ENV DOCKERIZE_VERSION v0.6.1
8
+ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
9
+ && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
10
+ && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz
11
+
12
+ COPY Gemfile /var/akasha/
13
+ COPY Gemfile.lock /var/akasha/
14
+ COPY akasha.gemspec /var/akasha/
15
+ COPY lib/akasha/version.rb /var/akasha/lib/akasha/version.rb
16
+
17
+ RUN set -eux; \
18
+ cd /var/akasha; \
19
+ bundle
20
+
21
+ COPY . /var/akasha/
22
+ WORKDIR /var/akasha/
23
+
24
+ CMD dockerize -wait http://eventstore:2113 bundle exec rspec --tag integration
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Gem's dependencies in akasha.gemspec
6
6
  gemspec
@@ -1,35 +1,46 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- akasha (0.2.0)
5
- http_event_store
4
+ akasha (0.3.0)
5
+ corefines (~> 1.11)
6
+ faraday (~> 0.15)
7
+ faraday_middleware
8
+ rack (~> 2.0)
9
+ retries (~> 0.0)
10
+ typhoeus (~> 1.3)
6
11
 
7
12
  GEM
8
13
  remote: https://rubygems.org/
9
14
  specs:
15
+ ast (2.3.0)
10
16
  byebug (10.0.2)
11
17
  coderay (1.1.2)
18
+ corefines (1.11.0)
12
19
  diff-lcs (1.3)
20
+ ethon (0.11.0)
21
+ ffi (>= 1.3.0)
13
22
  faraday (0.15.2)
14
23
  multipart-post (>= 1.2, < 3)
15
24
  faraday_middleware (0.12.2)
16
25
  faraday (>= 0.7.4, < 1.0)
17
- hashie (3.5.7)
18
- http_event_store (0.2.2)
19
- faraday
20
- faraday_middleware
21
- hashie
22
- json
23
- json (2.1.0)
26
+ ffi (1.9.25)
24
27
  method_source (0.9.0)
25
28
  multipart-post (2.0.0)
29
+ parallel (1.12.0)
30
+ parser (2.4.0.0)
31
+ ast (~> 2.2)
32
+ powerpack (0.1.1)
26
33
  pry (0.11.3)
27
34
  coderay (~> 1.1.0)
28
35
  method_source (~> 0.9.0)
29
36
  pry-byebug (3.6.0)
30
37
  byebug (~> 10.0)
31
38
  pry (~> 0.10)
39
+ rack (2.0.5)
40
+ rainbow (2.2.2)
41
+ rake
32
42
  rake (10.5.0)
43
+ retries (0.0.5)
33
44
  rspec (3.7.0)
34
45
  rspec-core (~> 3.7.0)
35
46
  rspec-expectations (~> 3.7.0)
@@ -43,7 +54,20 @@ GEM
43
54
  diff-lcs (>= 1.2.0, < 2.0)
44
55
  rspec-support (~> 3.7.0)
45
56
  rspec-support (3.7.1)
57
+ rspec-wait (0.0.9)
58
+ rspec (>= 3, < 4)
59
+ rubocop (0.50.0)
60
+ parallel (~> 1.10)
61
+ parser (>= 2.3.3.1, < 3.0)
62
+ powerpack (~> 0.1)
63
+ rainbow (>= 2.2.2, < 3.0)
64
+ ruby-progressbar (~> 1.7)
65
+ unicode-display_width (~> 1.0, >= 1.0.1)
66
+ ruby-progressbar (1.9.0)
46
67
  timecop (0.9.1)
68
+ typhoeus (1.3.0)
69
+ ethon (>= 0.9.0)
70
+ unicode-display_width (1.3.0)
47
71
 
48
72
  PLATFORMS
49
73
  ruby
@@ -54,7 +78,9 @@ DEPENDENCIES
54
78
  pry-byebug
55
79
  rake (~> 10.0)
56
80
  rspec (~> 3.7)
57
- timecop
81
+ rspec-wait (~> 0.0.9)
82
+ rubocop (~> 0.50)
83
+ timecop (~> 0.9)
58
84
 
59
85
  BUNDLED WITH
60
86
  1.16.2
data/README.md CHANGED
@@ -20,74 +20,81 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- The code below uses Sinatra to demonstrate how to use the library in a web application.
24
- This library makes no assumptions about any web framework, you can use it in any way you see fit.
23
+ There is an example Sinatra app under `examples/sinatra` showing how to use the library in a web application.
24
+ This library itself makes no assumptions about any web framework, you can use it in any way you see fit.
25
25
 
26
- ```ruby
27
- require 'akasha'
28
- require 'sinatra'
29
-
30
- class User < Akasha::Aggregate
31
- def sign_up(email:, password:, admin: false, **)
32
- changeset.append(:user_signed_up, email: email, password: password, admin: admin)
33
- end
34
-
35
- def on_user_signed_up(email:, password:, admin:, **)
36
- @email = email
37
- @password = password
38
- @admin = admin
39
- end
40
- end
41
-
42
-
43
- before do
44
- @router = Akasha::CommandRouter.new
45
-
46
- # Aggregates will load from and save to in-memory storage.
47
- repository = Akasha::Repository.new(Akasha::Storage::MemoryEventStore.new)
48
- Akasha::Aggregate.connect!(repository)
49
-
50
- # This is how you link commands to aggregates.
51
- @router.register_default_route(:sign_up, User)
52
-
53
- # Nearly identital to the default handling above but we're setting the admin
54
- # flag to demo custom command handling.
55
- @router.register_route(:sign_up_admin) do |aggregate_id, **data|
56
- user = User.find_or_create(aggregate_id)
57
- user.sign_up(email: data[:email], password: data[:password], admin: true)
58
- user.save!
59
- end
60
- end
61
-
62
- post '/users/:user_id' do # With CQRS client pass unique aggregate ids.
63
- @router.route!(:sign_up,
64
- params[:user_id],
65
- email: params[:email],
66
- password: params[:password])
67
- 'OK'
68
- end
69
- ```
70
-
71
- > Currently, only memory-based repository is supported.
72
-
73
- ## Next steps
26
+ ## TODO
74
27
 
75
28
  - [x] Command routing (default and user-defined)
76
29
  - [x] Synchronous EventHandler
77
30
  - [x] HTTP Eventstore storage backend
78
- - [ ] Telemetry (Dogstatsd)
79
- - [ ] Event#id for better idempotence (validate this claim)
80
- - [ ] Namespacing for events and aggregates
31
+ - [x] Event#id for better idempotence (validate this claim)
32
+ - [x] Async EventHandlers (storing cursors in Eventstore, configurable durability guarantees)
33
+ - [x] Uniform intetrface for Client -- use Event.
34
+ - [x] Rewrite Client
35
+ - [x] Refactor Client code
36
+ - [x] Take care of created_at/updated_at (saved_at?)
37
+ - [x] Tests for HttpEventStore
38
+ - [x] Projections
39
+ - [x] Test for AsyncEventRouter using events not aggregate
40
+ - [x] BUG: Projection reorders events
41
+ - [x] Simplify AsyncEventRouter init
42
+ - [x] SyncEventRouter => EventRouter
43
+ - [x] Metadata not persisted
44
+ - [x] Refactoring & simplification.
45
+ - [x] Hash-based event and command router
46
+ - [x] Do we need EventListener class? Yes.
47
+ - [x] Assymetry between data and metadata.
48
+ - [x] Faster shutdown.
49
+ - [ ] Namespacing for events and aggregates and the projection
81
50
  - [ ] Version-based concurrency
82
- - [ ] Async EventHandlers (storing cursors in Eventstore, configurable durability guarantees)
51
+ - [ ] Telemetry (Dogstatsd)
83
52
  - [ ] Socket-based Eventstore storage backend
84
53
 
54
+
85
55
  ## Development
86
56
 
87
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
57
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. See Running tests.
58
+
59
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
88
60
 
89
61
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
90
62
 
63
+
64
+ ## Running tests
65
+
66
+ Some tests require Eventstore to be running and available via `eventstore` host name. You can exclude these specs:
67
+
68
+ ```
69
+ rspec --tag ~integration
70
+ ```
71
+
72
+ The easiest way to run integration tests:
73
+
74
+ ```
75
+ /bin/integration-tests.sh
76
+ ```
77
+
78
+ This will use docker-compose to spin up containers containing the dependencies and tests themselves.
79
+
80
+ Because it's pretty slow, you may want to spin up a docker container containing event store:
81
+
82
+ ```
83
+ docker run -e EVENTSTORE_START_STANDARD_PROJECTIONS=true --name akasha-eventstore -it -p 2113:2113 -p 1113:1113 -d eventstore/eventstore
84
+ ```
85
+
86
+ and use RSpec run just integration specs like so:
87
+
88
+ ```
89
+ rspec --tag integration
90
+ ```
91
+
92
+ or run all tests:
93
+
94
+ ```
95
+ rspec
96
+ ```
97
+
91
98
  ## Contributing
92
99
 
93
100
  Bug reports and pull requests are welcome on GitHub at https://github.com/bilus/akasha.
data/Rakefile CHANGED
@@ -1,6 +1,11 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RuboCop::RakeTask.new(:rubocop) do |task|
6
+ task.options = ['--rails', '--display-cop-names']
7
+ end
3
8
 
4
9
  RSpec::Core::RakeTask.new(:spec)
5
10
 
6
- task :default => :spec
11
+ task default: :spec
@@ -9,9 +9,9 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Marcin Bilski']
10
10
  spec.email = ['marcin@tooploox.com']
11
11
 
12
- spec.summary = %q{CQRS library for Ruby}
13
- spec.description = %q{A simple CQRS library for Ruby.}
14
- spec.homepage = "https://github.com/bilus/akasha"
12
+ spec.summary = 'CQRS library for Ruby'
13
+ spec.description = 'A simple CQRS library for Ruby.'
14
+ spec.homepage = 'https://github.com/bilus/akasha'
15
15
  spec.license = 'MIT'
16
16
 
17
17
  # Specify which files should be added to the gem when it is released.
@@ -23,11 +23,18 @@ Gem::Specification.new do |spec|
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
24
  spec.require_paths = ['lib']
25
25
 
26
- spec.add_dependency 'http_event_store'
26
+ spec.add_dependency 'faraday', '~> 0.15'
27
+ spec.add_dependency 'faraday_middleware'
28
+ spec.add_dependency 'typhoeus', '~> 1.3'
29
+ spec.add_dependency 'rack', '~> 2.0'
30
+ spec.add_dependency 'retries', '~> 0.0'
31
+ spec.add_dependency 'corefines', '~>1.11'
27
32
 
28
33
  spec.add_development_dependency 'bundler', '~> 1.16'
34
+ spec.add_development_dependency 'pry-byebug'
29
35
  spec.add_development_dependency 'rake', '~> 10.0'
30
36
  spec.add_development_dependency 'rspec', '~> 3.7'
31
- spec.add_development_dependency 'timecop'
32
- spec.add_development_dependency 'pry-byebug'
37
+ spec.add_development_dependency 'rspec-wait', '~> 0.0.9'
38
+ spec.add_development_dependency 'rubocop', '~> 0.50'
39
+ spec.add_development_dependency 'timecop', '~> 0.9'
33
40
  end
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "akasha"
3
+ require 'bundler/setup'
4
+ require 'akasha'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "akasha"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start(__FILE__)
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # define some colors to use for output
4
+ RED='\033[0;31m'
5
+ GREEN='\033[0;32m'
6
+ NC='\033[0m'
7
+
8
+ PROJECT=ci
9
+
10
+ # kill and remove any running containers
11
+ cleanup () {
12
+ docker-compose -p $PROJECT down
13
+ }
14
+ # catch unexpected failures, do cleanup and output an error message
15
+ trap 'cleanup ; printf "${RED}Tests Failed For Unexpected Reasons${NC}\n"'\
16
+ HUP INT QUIT PIPE TERM
17
+ cd docker
18
+ echo "Starting tests"
19
+ # build and run the composed services
20
+ docker-compose -p $PROJECT up -d --build
21
+ if [ $? -ne 0 ] ; then
22
+ printf "${RED}Docker Compose Failed${NC}\n"
23
+ exit -1
24
+ fi
25
+ echo "Waiting for tests to finish"
26
+ # wait for the test service to complete and grab the exit code
27
+ TEST_EXIT_CODE=`docker wait ${PROJECT}_tests_1`
28
+ echo "Listing docker logs"
29
+ # output the logs for the test (for clarity)
30
+ docker logs ${PROJECT}_tests_1
31
+ # inspect the output of the test and display respective message
32
+ if [ -z ${TEST_EXIT_CODE+x} ] || [ "$TEST_EXIT_CODE" -ne 0 ] ; then
33
+ printf "${RED}Tests Failed${NC} - Exit Code: $TEST_EXIT_CODE\n"
34
+ else
35
+ printf "${GREEN}Tests Passed${NC}\n"
36
+ fi
37
+ # call the cleanup fuction
38
+ cleanup
39
+ # exit the script with the same code as the test service code
40
+ exit $TEST_EXIT_CODE