minidoc 0.0.1 → 1.0.0.rc1

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: bab3513e3711be6f000b2087acd5df2c327ed60f
4
- data.tar.gz: 7cc05456284d80bbdba422cf58c93a829c45592b
3
+ metadata.gz: ca8f2d071dcb6f2ef8e43e9d995e36ef0b1d4c6e
4
+ data.tar.gz: 0b0a1037fa259ab0602d2e21401a368495739803
5
5
  SHA512:
6
- metadata.gz: 4d4c5d33c49a995a7d65186a9da8390aac2a0ae87340ad58c38452288bea0c424ac9e7c1d58c77fc171937ae6e1c14a36620df188586b1d5b8ff8dbad5b0638e
7
- data.tar.gz: 8fbe9a2e11e6c9c37a773f41ec0c832bbe99584170fff167aa423488e01522d8d0ef619798a6185272e763abfb4840dd89f240ed4fc1c5fb44b4b6f0a192a06e
6
+ metadata.gz: d5029b2a00f9427603fe3b3e50270959b1333c0312bd8b50fcd5b8b1d1d9144724a1d893e2bc77f6497435047def4f3fe3f9ce4deaeecc8f14639590f9f66ba4
7
+ data.tar.gz: c398c3570ac71d56aef8a27309ab3c8a4321e172ee829403e8050a64542944288f96a750a1fc24e826f3ecfe5a592df4661c3a528b1bc42f725c5de88b6b7dac
@@ -0,0 +1,16 @@
1
+ ---
2
+ engines:
3
+ duplication:
4
+ enabled: true
5
+ config:
6
+ languages:
7
+ - ruby
8
+ fixme:
9
+ enabled: true
10
+ rubocop:
11
+ enabled: true
12
+ ratings:
13
+ paths:
14
+ - "**.rb"
15
+ exclude_paths:
16
+ - test/
@@ -0,0 +1,152 @@
1
+ ################################################################################
2
+ # Metrics
3
+ ################################################################################
4
+
5
+ Metrics/LineLength:
6
+ Enabled: false
7
+
8
+ Metrics/AbcSize:
9
+ Enabled: false
10
+
11
+ ################################################################################
12
+ # Style
13
+ ################################################################################
14
+
15
+ # Executables are conventionally named bin/foo-bar
16
+ Style/FileName:
17
+ Exclude:
18
+ - bin/**/*
19
+
20
+ # We don't (currently) document our code
21
+ Style/Documentation:
22
+ Enabled: false
23
+
24
+ # Always use double-quotes to keep things simple
25
+ Style/StringLiterals:
26
+ EnforcedStyle: double_quotes
27
+
28
+ Style/StringLiteralsInInterpolation:
29
+ EnforcedStyle: double_quotes
30
+
31
+ # Use a trailing comma to keep diffs clean when elements are inserted or removed
32
+ Style/TrailingCommaInArguments:
33
+ EnforcedStyleForMultiline: comma
34
+
35
+ Style/TrailingCommaInLiteral:
36
+ EnforcedStyleForMultiline: comma
37
+
38
+ # We avoid GuardClause because it can result in "suprise return"
39
+ Style/GuardClause:
40
+ Enabled: false
41
+
42
+ # We avoid IfUnlessModifier because it can result in "suprise if"
43
+ Style/IfUnlessModifier:
44
+ Enabled: false
45
+
46
+ # We don't care about the fail/raise distinction
47
+ Style/SignalException:
48
+ EnforcedStyle: only_raise
49
+
50
+ Style/DotPosition:
51
+ EnforcedStyle: trailing
52
+
53
+ # Common globals we allow
54
+ Style/GlobalVars:
55
+ AllowedVariables:
56
+ - "$statsd"
57
+ - "$mongo"
58
+ - "$rollout"
59
+
60
+ # Using english names requires loading an extra module, which is annoying, so
61
+ # we prefer the perl names for consistency.
62
+ Style/SpecialGlobalVars:
63
+ EnforcedStyle: use_perl_names
64
+
65
+ # We have common cases where has_ and have_ make sense
66
+ Style/PredicateName:
67
+ Enabled: true
68
+ NamePrefixBlacklist:
69
+ - is_
70
+
71
+ # We use %w[ ], not %w( ) because the former looks like an array
72
+ Style/PercentLiteralDelimiters:
73
+ PreferredDelimiters:
74
+ "%i": "[]"
75
+ "%I": "[]"
76
+ "%w": "[]"
77
+ "%W": "[]"
78
+
79
+ # Allow "trivial" accessors when defined as a predicate? method
80
+ Style/TrivialAccessors:
81
+ AllowPredicates: true
82
+
83
+ Style/Next:
84
+ Enabled: false
85
+
86
+ # We think it's OK to use the "extend self" module pattern
87
+ Style/ModuleFunction:
88
+ Enabled: false
89
+
90
+ # Disallow extra spacing for token alignment
91
+ Style/ExtraSpacing:
92
+ AllowForAlignment: false
93
+
94
+ # and/or in conditionals has no meaningful difference (only gotchas), so we
95
+ # disallow them there. When used for control flow, the difference in precedence
96
+ # can make for a less noisy expression, as in:
97
+ #
98
+ # x = find_x or raise XNotFound
99
+ #
100
+ Style/AndOr:
101
+ EnforcedStyle: conditionals
102
+
103
+ Style/AlignParameters:
104
+ EnforcedStyle: with_fixed_indentation
105
+
106
+ Style/MultilineOperationIndentation:
107
+ EnforcedStyle: indented
108
+
109
+ Style/AlignHash:
110
+ EnforcedLastArgumentHashStyle: ignore_implicit
111
+
112
+ # This has the behavior we want, but it has a bug in it which produces a lot of false positives
113
+ # https://github.com/bbatsov/rubocop/issues/3462
114
+ # MultilineMethodCallBraceLayout:
115
+ # EnforcedStyle: new_line
116
+
117
+ ################################################################################
118
+ # Performance
119
+ ################################################################################
120
+
121
+ Performance/RedundantMerge:
122
+ Enabled: false
123
+
124
+ ################################################################################
125
+ # Rails - disable things because we're primarily non-rails
126
+ ################################################################################
127
+
128
+ Rails/Delegate:
129
+ Enabled: false
130
+
131
+ Rails/TimeZone:
132
+ Enabled: false
133
+
134
+ ################################################################################
135
+ # Specs - be more lenient on length checks and block styles
136
+ ################################################################################
137
+
138
+ Metrics/ModuleLength:
139
+ Exclude:
140
+ - spec/**/*
141
+
142
+ Metrics/MethodLength:
143
+ Exclude:
144
+ - spec/**/*
145
+
146
+ Style/ClassAndModuleChildren:
147
+ Exclude:
148
+ - spec/**/*
149
+
150
+ Style/BlockDelimiters:
151
+ Exclude:
152
+ - spec/**/*
@@ -1 +1 @@
1
- 1.9.3-p545
1
+ 2.3.1
@@ -6,3 +6,7 @@ rvm:
6
6
  services: mongodb
7
7
  before_install:
8
8
  - gem update bundler
9
+ script:
10
+ - rake
11
+ after_script:
12
+ - CODECLIMATE_REPO_TOKEN=787a2f89b15c637323c7340d65ec17e898ac44480706b4b4122ea040c2a88f1d bundle exec codeclimate-test-reporter
@@ -0,0 +1,39 @@
1
+ # Change log
2
+
3
+ ## master (unreleased)
4
+
5
+ ### New features
6
+
7
+ ### Bug fixes
8
+
9
+ ### Changes
10
+
11
+ ## v1.0.0.rc1 (2016-09-29)
12
+
13
+ ### New features
14
+
15
+ * [#24](https://github.com/codeclimate/minidoc/pull/24): Add `Minidoc.all`. ([@pbrisbin][])
16
+ * [#24](https://github.com/codeclimate/minidoc/pull/24): Add `Minidoc.find_one!`. ([@pbrisbin][])
17
+ * [#28](https://github.com/codeclimate/minidoc/pull/28): Add `Minidoc.find_one_or_initialize`. ([@nporteschaikin][])
18
+ * [#32](https://github.com/codeclimate/minidoc/pull/32): Infer class names for associations when not provided. ([@wfleming][])
19
+
20
+ ### Bug fixes
21
+
22
+ * [#26](https://github.com/codeclimate/minidoc/pull/26): Improve performance of `Minidoc.exists?`. ([@wfleming][])
23
+ * [#31](https://github.com/codeclimate/minidoc/pull/31): Fix `save` dropping some attributes. ([@nporteschaikin][])
24
+ * Improve errors when the user has forgotten to provide database connection information. ([@maxjacobson][])
25
+
26
+ ### Changes
27
+
28
+ * [#23](https://github.com/codeclimate/minidoc/pull/23): Remove `ensure_index`. ([@pbrisbin][])
29
+
30
+ ## v0.0.1 (2016-09-28)
31
+
32
+ Minidoc was originally created by [@brynary][] and has been used in production extensively at Code Climate.
33
+ This is the first version released to rubygems.
34
+
35
+ [@brynary]: https://github.com/brynary
36
+ [@maxjacobson]: https://github.com/maxjacobson
37
+ [@nporteschaikin]: https://github.com/nporteschaikin
38
+ [@pbrisbin]: https://github.com/pbrisbin
39
+ [@wfleming]: https://github.com/wfleming
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at hello@codeclimate.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile CHANGED
@@ -1,2 +1,9 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
+
3
+ gem "minitest"
4
+ gem "mocha"
5
+ gem "rake"
6
+ gem "simplecov"
7
+ gem "codeclimate-test-reporter", "1.0.0.pre.rc2"
8
+
2
9
  gemspec
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Bryan Helmkamp
1
+ Copyright (c) 2016 Bryan Helmkamp
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
- [![Code Climate](https://codeclimate.com/github/brynary/minidoc.svg)](https://codeclimate.com/github/brynary/minidoc)
2
- [![Build Status](https://travis-ci.org/brynary/minidoc.svg)](https://travis-ci.org/brynary/minidoc)
1
+ [![Build Status](https://travis-ci.org/codeclimate/minidoc.svg)](https://travis-ci.org/codeclimate/minidoc)
2
+ [![Gem Version](https://badge.fury.io/rb/minidoc.svg)](http://badge.fury.io/rb/minidoc)
3
+ [![Code Climate](https://codeclimate.com/github/codeclimate/minidoc/badges/gpa.svg)](https://codeclimate.com/github/codeclimate/minidoc)
4
+ [![Test Coverage](https://codeclimate.com/github/codeclimate/minidoc/badges/coverage.svg)](https://codeclimate.com/github/codeclimate/minidoc/coverage)
3
5
 
4
6
  # Minidoc
5
7
 
@@ -27,14 +29,41 @@ things as simple as possible.
27
29
  * Custom query API (just use Mongo)
28
30
  * Callbacks (just define a method like save and call super)
29
31
 
32
+ ## Installation
33
+
34
+ Add this line to your application's Gemfile:
35
+
36
+ ```ruby
37
+ gem "minidoc"
38
+ ```
39
+
40
+ And then execute:
41
+
42
+ ```
43
+ $ bundle
44
+ ```
45
+
46
+ Or install it yourself as:
47
+
48
+ ```
49
+ $ gem install minidoc
50
+ ```
51
+
30
52
  ## Usage
31
53
 
32
- gem "minidoc", "~> 0.0.1"
54
+ ### Setup
55
+
56
+ ```ruby
57
+ Minidoc.connection = Mongo::MongoClient.from_uri("mongodb://localhost")
58
+ Minidoc.database_name = "my_great_app_development"
59
+ ```
33
60
 
34
61
  ### Basics
35
62
 
36
63
  ```ruby
37
64
  class User < Minidoc
65
+ include Minidoc::Timestamps
66
+
38
67
  attribute :name, String
39
68
  attribute :language, String
40
69
  timestamps!
@@ -71,6 +100,53 @@ user.valid? # => true
71
100
 
72
101
  ### Value Objects
73
102
 
103
+ ```ruby
104
+ bryan = User.create(name: "Bryan").as_value
105
+ bryan.name #=> "Bryan"
106
+ bryan.name = "Brian" #=> NoMethodError
107
+ ```
108
+
74
109
  ### Associations
75
110
 
111
+ ```ruby
112
+ class Drink < Minidoc
113
+ include Minidoc::Associations
114
+
115
+ attribute :name, String
116
+
117
+ belongs_to :user
118
+ end
119
+
120
+ bryan = User.create(name: "Bryan")
121
+ drink = Drink.create(name: "Paloma", user: bryan)
122
+ drink.user == bryan #=> true
123
+ ```
124
+
76
125
  ### Read-only records
126
+
127
+ ```ruby
128
+ class DrinkEvents < Minidoc::ReadOnly
129
+ include Minidoc::Timestamps
130
+ timestamps!
131
+ end
132
+
133
+ DrinkEvents.count(created_at: { "$gt": 4.days.ago }) #=> 0
134
+ DrinkEvents.create #=> NoMethodError
135
+ ```
136
+
137
+ ## Contributing
138
+
139
+ Bug reports and pull requests are welcome on GitHub at https://github.com/codeclimate/minidoc. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
140
+
141
+ When making a pull request, please update the [changelog](CHANGELOG.md).
142
+
143
+ ## Releasing
144
+
145
+ * Update the changelog to mark the unreleased changes as part of the new release.
146
+ * Update the version.rb with the new version number
147
+ * Commit and push to master
148
+ * `rake release` which will
149
+ * tag the latest commit based on version.rb
150
+ * push to github
151
+ * push to rubygems
152
+ * Copy the relevant changelog entries into a new [GitHub release](https://github.com/codeclimate/minidoc/releases).
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
- require 'rake/testtask'
2
+ require "rake/testtask"
3
3
 
4
4
  Rake::TestTask.new do |t|
5
5
  t.libs.push "lib"
6
6
  t.ruby_opts = %w[-W0]
7
- t.test_files = FileList['test/*_test.rb']
7
+ t.test_files = FileList["test/*_test.rb"]
8
8
  t.verbose = true
9
9
  end
10
10
 
@@ -4,20 +4,18 @@ require "active_model"
4
4
  require "active_support/core_ext"
5
5
 
6
6
  class Minidoc
7
- VERSION = "0.0.1"
8
-
9
7
  require "minidoc/associations"
10
8
  require "minidoc/connection"
11
9
  require "minidoc/counters"
12
10
  require "minidoc/finders"
13
11
  require "minidoc/grid"
14
- require "minidoc/indexes"
15
12
  require "minidoc/read_only"
16
13
  require "minidoc/record_invalid"
17
14
  require "minidoc/duplicate_key"
18
15
  require "minidoc/timestamps"
19
16
  require "minidoc/validations"
20
17
  require "minidoc/value"
18
+ require "minidoc/version"
21
19
 
22
20
  include Connection
23
21
  include Finders
@@ -235,7 +233,7 @@ private
235
233
  end
236
234
 
237
235
  def update
238
- self.class.collection.update({ _id: id }, attributes)
236
+ self.class.collection.update({ _id: id }, { "$set" => attributes.except(:_id) })
239
237
  end
240
238
 
241
239
  if ActiveSupport.respond_to?(:run_load_hooks)
@@ -9,6 +9,8 @@ module Minidoc::Associations
9
9
  end
10
10
 
11
11
  def belongs_to(association_name, options = {})
12
+ options[:class_name] ||= "#{self.parent.name}::#{association_name.to_s.camelize}"
13
+
12
14
  association_name = association_name.to_sym
13
15
  associations[association_name] = options
14
16
 
@@ -8,12 +8,15 @@ module Minidoc::Connection
8
8
  class_attribute :database_name
9
9
  end
10
10
 
11
+ MissingConfiguration = Class.new(StandardError)
12
+
11
13
  module ClassMethods
12
14
  def collection
13
15
  database[collection_name]
14
16
  end
15
17
 
16
18
  def database
19
+ validate_config
17
20
  connection[database_name]
18
21
  end
19
22
 
@@ -24,5 +27,15 @@ module Minidoc::Connection
24
27
  def collection_name
25
28
  @collection_name ||= name.demodulize.underscore.pluralize
26
29
  end
30
+
31
+ private
32
+
33
+ def validate_config
34
+ if connection.nil?
35
+ raise MissingConfiguration, "Make sure to set Minidoc.connection"
36
+ elsif database_name.nil?
37
+ raise MissingConfiguration, "Make sure to set Minidoc.database_name"
38
+ end
39
+ end
27
40
  end
28
41
  end
@@ -3,7 +3,13 @@ require "active_support/concern"
3
3
  module Minidoc::Finders
4
4
  extend ActiveSupport::Concern
5
5
 
6
+ DocumentNotFoundError = Class.new(StandardError)
7
+
6
8
  module ClassMethods
9
+ def all
10
+ find({})
11
+ end
12
+
7
13
  def first
8
14
  find_one({})
9
15
  end
@@ -13,7 +19,7 @@ module Minidoc::Finders
13
19
  end
14
20
 
15
21
  def exists?(selector = {})
16
- count(selector) > 0
22
+ find_one(selector).present?
17
23
  end
18
24
 
19
25
  def find(id_or_selector, options = {})
@@ -31,6 +37,15 @@ module Minidoc::Finders
31
37
  wrap(collection.find_one(selector, options))
32
38
  end
33
39
 
40
+ def find_one!(query, options = {})
41
+ find_one(query, options) or raise DocumentNotFoundError
42
+ end
43
+
44
+ def find_one_or_initialize(attributes, options = {})
45
+ raise ArgumentError unless attributes.is_a?(Hash)
46
+ find_one(attributes, options) || new(attributes)
47
+ end
48
+
34
49
  def from_db(attrs)
35
50
  doc = new(attrs)
36
51
  doc.instance_variable_set("@new_record", false)
@@ -0,0 +1,3 @@
1
+ class Minidoc
2
+ VERSION = "1.0.0.rc1"
3
+ end
@@ -1,23 +1,24 @@
1
1
  # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "minidoc/version"
5
+
2
6
  Gem::Specification.new do |spec|
3
- spec.name = "minidoc"
4
- spec.version = "0.0.1"
5
- spec.authors = ["Bryan Helmkamp"]
6
- spec.email = ["bryan@brynary.com"]
7
- spec.summary = %q{Lightweight wrapper for MongoDB documents}
8
- spec.homepage = "https://github.com/brynary/minidoc"
9
- spec.license = "MIT"
7
+ spec.name = "minidoc"
8
+ spec.version = Minidoc::VERSION
9
+ spec.authors = ["Bryan Helmkamp", "Code Climate"]
10
+ spec.email = ["bryan@brynary.com", "hello@codeclimate.com"]
11
+ spec.summary = %q{Lightweight wrapper for MongoDB documents}
12
+ spec.homepage = "https://github.com/codeclimate/minidoc"
13
+ spec.license = "MIT"
10
14
 
11
- spec.files = `git ls-files`.split($/)
12
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
13
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
18
  spec.require_paths = ["lib"]
15
19
 
16
- spec.add_dependency "activesupport", ">= 3.0.0"
17
- spec.add_dependency "activemodel", ">= 3.0.0"
18
- spec.add_dependency "virtus", "~> 1.0.0"
20
+ spec.add_dependency "activesupport", ">= 3.0.0", "< 5"
21
+ spec.add_dependency "activemodel", ">= 3.0.0", "< 5"
22
+ spec.add_dependency "virtus", "~> 1.0", ">= 1.0.0"
19
23
  spec.add_dependency "mongo", "~> 1"
20
- spec.add_development_dependency "minitest"
21
- spec.add_development_dependency "mocha"
22
- spec.add_development_dependency "rake"
23
24
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class ActiveModelTest < Minidoc::TestCase
4
4
  def test_model_name
@@ -12,13 +12,13 @@ class ActiveModelTest < Minidoc::TestCase
12
12
 
13
13
  def test_to_key
14
14
  user = User.new
15
- user.id = BSON::ObjectId('52955618f9f6a52444000001')
15
+ user.id = BSON::ObjectId("52955618f9f6a52444000001")
16
16
  assert_equal ["52955618f9f6a52444000001"], user.to_key
17
17
  end
18
18
 
19
19
  def test_to_param
20
20
  user = User.new
21
- user.id = BSON::ObjectId('52955618f9f6a52444000001')
21
+ user.id = BSON::ObjectId("52955618f9f6a52444000001")
22
22
  assert_equal "52955618f9f6a52444000001", user.to_param
23
23
  end
24
24
 
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class BelongsToTest < Minidoc::TestCase
4
4
  class Cat < Minidoc
@@ -6,9 +6,24 @@ class BelongsToTest < Minidoc::TestCase
6
6
  belongs_to :owner, class_name: "User"
7
7
  end
8
8
 
9
+ class ::Dog < Minidoc
10
+ include Minidoc::Associations
11
+ belongs_to :user
12
+ end
13
+
9
14
  class User < ::User
10
15
  end
11
16
 
17
+ module Animal
18
+ class Armadillo < Minidoc
19
+ include Minidoc::Associations
20
+ belongs_to :predator
21
+ end
22
+
23
+ class Predator < Minidoc
24
+ end
25
+ end
26
+
12
27
  def test_loading
13
28
  assert_nil Cat.new.owner
14
29
  user = User.create
@@ -46,4 +61,22 @@ class BelongsToTest < Minidoc::TestCase
46
61
  cat.owner_id = user.id
47
62
  assert_equal "Noah", cat.owner.name # changes
48
63
  end
64
+
65
+ def test_top_level_inferred_class_name
66
+ assert_nil Dog.new.user
67
+ user = User.create
68
+ sam = Dog.new(user_id: user.id)
69
+ assert_equal user.id, sam.user.id
70
+ sam.save
71
+ assert_equal user.id, sam.user.id
72
+ end
73
+
74
+ def test_nested_inferred_class_name
75
+ assert_nil Animal::Armadillo.new.predator
76
+ predator = Animal::Predator.create
77
+ arnie = Animal::Armadillo.new(predator_id: predator.id)
78
+ assert_equal predator.id, arnie.predator.id
79
+ arnie.save
80
+ assert_equal predator.id, arnie.predator.id
81
+ end
49
82
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class ConnectionTest < Minidoc::TestCase
4
4
  class Company < Minidoc
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class CountersTest < Minidoc::TestCase
4
4
  class SimpleCounter < Minidoc
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class DuplicateKeyTest < Minidoc::TestCase
4
4
  def test_rescue_duplicate_key_errors_result
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../helper', __FILE__)
3
+
4
+ class FirstRunTest < Minidoc::TestCase
5
+ def test_missing_setup_values
6
+ with_alternative_configuration do
7
+ Minidoc.connection = nil
8
+ Minidoc.database_name = nil
9
+
10
+ ex =
11
+ assert_raises Minidoc::MissingConfiguration do
12
+ User.create(name: "Kären")
13
+ end
14
+ assert_equal ex.message, "Make sure to set Minidoc.connection"
15
+ end
16
+ end
17
+
18
+ def test_missing_database_name_only
19
+ with_alternative_configuration do
20
+ Minidoc.database_name = nil
21
+
22
+ ex =
23
+ assert_raises Minidoc::MissingConfiguration do
24
+ User.create(name: "Kären")
25
+ end
26
+ assert_equal ex.message, "Make sure to set Minidoc.database_name"
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def with_alternative_configuration
33
+ original_connection = Minidoc.connection
34
+ original_database_name = Minidoc.database_name
35
+ yield
36
+ ensure
37
+ Minidoc.connection = original_connection
38
+ Minidoc.database_name = original_database_name
39
+ end
40
+ end
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class GridTest < Minidoc::TestCase
4
4
 
@@ -1,16 +1,29 @@
1
- require 'minidoc'
2
- require 'minidoc/test_helpers'
3
- require 'minitest/autorun'
4
- require 'mocha/mini_test'
1
+ require "simplecov"
2
+ SimpleCov.start do
3
+ add_filter "/test/"
4
+ end
5
+
6
+ require "minidoc"
7
+ require "minidoc/test_helpers"
8
+ require "minitest/autorun"
9
+ require "mocha/mini_test"
5
10
 
6
11
  I18n.enforce_available_locales = false
7
12
  I18n.load_path << File.expand_path("../locale/en.yml", __FILE__)
8
13
 
9
14
  class User < Minidoc
15
+ self.collection_name = "users"
16
+
10
17
  attribute :name, String
11
18
  attribute :age, Integer
12
19
  end
13
20
 
21
+ class SecondUser < Minidoc
22
+ self.collection_name = "users"
23
+
24
+ attribute :age, Integer
25
+ end
26
+
14
27
  $mongo = Mongo::MongoClient.from_uri(ENV["MONGODB_URI"] || "mongodb://localhost")
15
28
  Minidoc.connection = $mongo
16
29
  Minidoc.database_name = "minidoc_test"
@@ -1,15 +1,15 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class PersistenceTest < Minidoc::TestCase
4
4
  def test_ids
5
5
  user = User.new
6
6
  assert_equal BSON::ObjectId, user.id.class
7
7
 
8
- user = User.new(_id: BSON::ObjectId('52955cc5f9f6a538a9000001'))
9
- assert_equal BSON::ObjectId('52955cc5f9f6a538a9000001'), user.id
8
+ user = User.new(_id: BSON::ObjectId("52955cc5f9f6a538a9000001"))
9
+ assert_equal BSON::ObjectId("52955cc5f9f6a538a9000001"), user.id
10
10
 
11
- user = User.new("_id" => BSON::ObjectId('52955cc5f9f6a538a9000001'))
12
- assert_equal BSON::ObjectId('52955cc5f9f6a538a9000001'), user.id
11
+ user = User.new("_id" => BSON::ObjectId("52955cc5f9f6a538a9000001"))
12
+ assert_equal BSON::ObjectId("52955cc5f9f6a538a9000001"), user.id
13
13
  end
14
14
 
15
15
  def test_new_record
@@ -22,7 +22,7 @@ class PersistenceTest < Minidoc::TestCase
22
22
  def test_raises_duplicate_key_where_appropriate
23
23
  mock_collection = mock()
24
24
  User.stubs(:collection).returns(mock_collection)
25
- mock_collection.stubs(:<<).raises(Mongo::OperationFailure.new('Duplicate key exception', Minidoc::DuplicateKey::DUPLICATE_KEY_ERROR_CODE))
25
+ mock_collection.stubs(:<<).raises(Mongo::OperationFailure.new("Duplicate key exception", Minidoc::DuplicateKey::DUPLICATE_KEY_ERROR_CODE))
26
26
 
27
27
  user = User.new
28
28
  assert_raises(Minidoc::DuplicateKey) { user.save }
@@ -72,6 +72,21 @@ class PersistenceTest < Minidoc::TestCase
72
72
  assert_equal "Noah", user.reload.name
73
73
  end
74
74
 
75
+ def test_update_same_collection
76
+ user = User.create(name: "Bryan", age: 20)
77
+ user.name = "Noah"
78
+ assert_equal "Noah", user.name
79
+ user.save
80
+ assert_equal "Noah", user.reload.name
81
+ second_user = SecondUser.find_one(age: 20)
82
+ assert_equal second_user.id, user.id
83
+ second_user.age = 21
84
+ assert_equal 21, second_user.age
85
+ second_user.save
86
+ assert_equal 21, second_user.reload.age
87
+ assert_equal "Noah", user.reload.name
88
+ end
89
+
75
90
  def test_destroy
76
91
  user = User.create(name: "Bryan")
77
92
  assert_equal false, user.destroyed?
@@ -1,6 +1,13 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class QueryTest < Minidoc::TestCase
4
+ def test_all
5
+ User.collection << { name: "Joe" }
6
+ User.collection << { name: "Bryan" }
7
+ users = User.all
8
+ assert_equal %w[Bryan Joe], users.map(&:name).sort
9
+ end
10
+
4
11
  def test_count_all
5
12
  User.collection << { name: "Joe" }
6
13
  User.collection << { name: "Bryan" }
@@ -37,4 +44,21 @@ class QueryTest < Minidoc::TestCase
37
44
  assert_equal user, User.find_one({})
38
45
  assert_equal nil, User.find_one(name: "Noah")
39
46
  end
47
+
48
+ def test_find_one!
49
+ user = User.create(name: "Bryan")
50
+ assert_equal user, User.find_one!(name: "Bryan")
51
+ assert_raises(Minidoc::DocumentNotFoundError) { User.find_one!(name: "Noah") }
52
+ end
53
+
54
+ def test_find_one_or_initialize
55
+ user = User.create(name: "Bryan", age: 1)
56
+ assert user == User.find_one_or_initialize(name: "Bryan")
57
+ assert User.find_one_or_initialize(name: "Noah").is_a?(User)
58
+ assert User.find_one_or_initialize(name: "Noah").new_record?
59
+ user = User.create(name: "Noah", age: 1)
60
+ assert user == User.find_one_or_initialize({ age: 1 }, { sort: { name: -1 } })
61
+ assert_raises(ArgumentError) { User.find_one_or_initialize("foo") }
62
+ end
63
+
40
64
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class ReadOnlyTest < Minidoc::TestCase
4
4
  class ReadOnlyUser < Minidoc::ReadOnly
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class TimestampsTest < Minidoc::TestCase
4
4
  class User < ::User
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class UniquenessValidatorTest < Minidoc::TestCase
4
4
  class User < ::User
@@ -1,4 +1,4 @@
1
- require File.expand_path('../helper', __FILE__)
1
+ require File.expand_path("../helper", __FILE__)
2
2
 
3
3
  class ValidationsTest < Minidoc::TestCase
4
4
  class User < ::User
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minidoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Helmkamp
8
+ - Code Climate
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2016-09-28 00:00:00.000000000 Z
12
+ date: 2016-09-29 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: activesupport
@@ -17,6 +18,9 @@ dependencies:
17
18
  - - ">="
18
19
  - !ruby/object:Gem::Version
19
20
  version: 3.0.0
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '5'
20
24
  type: :runtime
21
25
  prerelease: false
22
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +28,9 @@ dependencies:
24
28
  - - ">="
25
29
  - !ruby/object:Gem::Version
26
30
  version: 3.0.0
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '5'
27
34
  - !ruby/object:Gem::Dependency
28
35
  name: activemodel
29
36
  requirement: !ruby/object:Gem::Requirement
@@ -31,6 +38,9 @@ dependencies:
31
38
  - - ">="
32
39
  - !ruby/object:Gem::Version
33
40
  version: 3.0.0
41
+ - - "<"
42
+ - !ruby/object:Gem::Version
43
+ version: '5'
34
44
  type: :runtime
35
45
  prerelease: false
36
46
  version_requirements: !ruby/object:Gem::Requirement
@@ -38,11 +48,17 @@ dependencies:
38
48
  - - ">="
39
49
  - !ruby/object:Gem::Version
40
50
  version: 3.0.0
51
+ - - "<"
52
+ - !ruby/object:Gem::Version
53
+ version: '5'
41
54
  - !ruby/object:Gem::Dependency
42
55
  name: virtus
43
56
  requirement: !ruby/object:Gem::Requirement
44
57
  requirements:
45
58
  - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.0'
61
+ - - ">="
46
62
  - !ruby/object:Gem::Version
47
63
  version: 1.0.0
48
64
  type: :runtime
@@ -50,6 +66,9 @@ dependencies:
50
66
  version_requirements: !ruby/object:Gem::Requirement
51
67
  requirements:
52
68
  - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: '1.0'
71
+ - - ">="
53
72
  - !ruby/object:Gem::Version
54
73
  version: 1.0.0
55
74
  - !ruby/object:Gem::Dependency
@@ -66,58 +85,21 @@ dependencies:
66
85
  - - "~>"
67
86
  - !ruby/object:Gem::Version
68
87
  version: '1'
69
- - !ruby/object:Gem::Dependency
70
- name: minitest
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: mocha
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rake
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
88
  description:
112
89
  email:
113
90
  - bryan@brynary.com
91
+ - hello@codeclimate.com
114
92
  executables: []
115
93
  extensions: []
116
94
  extra_rdoc_files: []
117
95
  files:
96
+ - ".codeclimate.yml"
118
97
  - ".gitignore"
98
+ - ".rubocop.yml"
119
99
  - ".ruby-version"
120
100
  - ".travis.yml"
101
+ - CHANGELOG.md
102
+ - CODE_OF_CONDUCT.md
121
103
  - Gemfile
122
104
  - LICENSE.txt
123
105
  - README.md
@@ -130,22 +112,22 @@ files:
130
112
  - lib/minidoc/duplicate_key.rb
131
113
  - lib/minidoc/finders.rb
132
114
  - lib/minidoc/grid.rb
133
- - lib/minidoc/indexes.rb
134
115
  - lib/minidoc/read_only.rb
135
116
  - lib/minidoc/record_invalid.rb
136
117
  - lib/minidoc/test_helpers.rb
137
118
  - lib/minidoc/timestamps.rb
138
119
  - lib/minidoc/validations.rb
139
120
  - lib/minidoc/value.rb
121
+ - lib/minidoc/version.rb
140
122
  - minidoc.gemspec
141
123
  - test/activemodel_test.rb
142
124
  - test/belongs_to_test.rb
143
125
  - test/connection_test.rb
144
126
  - test/counters_test.rb
145
127
  - test/duplicate_key_test.rb
128
+ - test/first_run_test.rb
146
129
  - test/grid_test.rb
147
130
  - test/helper.rb
148
- - test/indexes_test.rb
149
131
  - test/locale/en.yml
150
132
  - test/persistence_test.rb
151
133
  - test/query_test.rb
@@ -153,7 +135,7 @@ files:
153
135
  - test/timestamps_test.rb
154
136
  - test/uniqueness_validator_test.rb
155
137
  - test/validations_test.rb
156
- homepage: https://github.com/brynary/minidoc
138
+ homepage: https://github.com/codeclimate/minidoc
157
139
  licenses:
158
140
  - MIT
159
141
  metadata: {}
@@ -168,9 +150,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
168
150
  version: '0'
169
151
  required_rubygems_version: !ruby/object:Gem::Requirement
170
152
  requirements:
171
- - - ">="
153
+ - - ">"
172
154
  - !ruby/object:Gem::Version
173
- version: '0'
155
+ version: 1.3.1
174
156
  requirements: []
175
157
  rubyforge_project:
176
158
  rubygems_version: 2.5.1
@@ -183,9 +165,9 @@ test_files:
183
165
  - test/connection_test.rb
184
166
  - test/counters_test.rb
185
167
  - test/duplicate_key_test.rb
168
+ - test/first_run_test.rb
186
169
  - test/grid_test.rb
187
170
  - test/helper.rb
188
- - test/indexes_test.rb
189
171
  - test/locale/en.yml
190
172
  - test/persistence_test.rb
191
173
  - test/query_test.rb
@@ -193,4 +175,3 @@ test_files:
193
175
  - test/timestamps_test.rb
194
176
  - test/uniqueness_validator_test.rb
195
177
  - test/validations_test.rb
196
- has_rdoc:
@@ -1,31 +0,0 @@
1
- require "active_support/concern"
2
-
3
- module Minidoc::Indexes
4
- extend ActiveSupport::Concern
5
-
6
- module ClassMethods
7
- MONGO_DUPLICATE_KEY_ERROR_CODE = 11000
8
-
9
- def ensure_index(key_or_keys, options = {})
10
- indexes = Array(key_or_keys).map { |key| { key => 1 } }.reduce(:merge)
11
-
12
- collection.ensure_index(indexes, options)
13
- end
14
-
15
- # Rescue a <tt>Mongo::OperationFailure</tt> exception which originated from
16
- # duplicate key error (error code 11000) in the given block.
17
- #
18
- # Returns the status of the operation in the given block, or +false+ if the
19
- # exception was raised.
20
- def rescue_duplicate_key_errors
21
- yield
22
- rescue Mongo::OperationFailure => exception
23
- if exception.respond_to?(:error_code) &&
24
- exception.error_code == MONGO_DUPLICATE_KEY_ERROR_CODE
25
- return false
26
- else
27
- raise
28
- end
29
- end
30
- end
31
- end
@@ -1,52 +0,0 @@
1
- require File.expand_path('../helper', __FILE__)
2
-
3
- class IndexesTest < Minidoc::TestCase
4
- class Company < Minidoc
5
- self.collection_name = "accounts"
6
-
7
- include Minidoc::Indexes
8
-
9
- attribute :name
10
- attribute :title
11
- attribute :description
12
- end
13
-
14
- def test_ensure_index_single
15
- Company.ensure_index(:name)
16
-
17
- assert_equal %w( name ), indexed_keys(Company, "name_1")
18
- end
19
-
20
- def test_ensure_index_multiple
21
- Company.ensure_index([:name, :title])
22
-
23
- assert_equal %w( name title ), indexed_keys(Company, "name_1_title_1")
24
- end
25
-
26
- def test_ensure_index_options
27
- Company.ensure_index(:name, unique: true)
28
-
29
- assert index_info(Company, "name_1")["unique"]
30
- end
31
-
32
- def test_rescue_duplicate_key_errors_not_raising_exception
33
- Company.ensure_index(:name, unique: true)
34
-
35
- Company.rescue_duplicate_key_errors do
36
- Company.create!(name: "CodeClimate")
37
- Company.create!(name: "CodeClimate")
38
- end
39
- end
40
-
41
- private
42
-
43
- def index_info(klass, name)
44
- klass.collection.index_information[name] || {}
45
- end
46
-
47
- def indexed_keys(klass, name)
48
- key_info = index_info(klass, name)["key"] || {}
49
- key_info.keys
50
- end
51
-
52
- end