Skip to content

Commit 8a0fb4e

Browse files
authored
Merge pull request #5 from neuronlabs/develop
Fixes #1. Checking subclasses max values.
2 parents 900b5eb + 9535ebe commit 8a0fb4e

File tree

5 files changed

+77
-29
lines changed

5 files changed

+77
-29
lines changed

README.md

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Errors [![Go Report Card](https://goreportcard.com/badge/github.com/neuronlabs/errors)](https://goreportcard.com/report/github.com/neuronlabs/errors) [![GoDoc](https://godoc.org/github.com/neuronlabs/errors?status.svg)](https://godoc.org/github.com/neuronlabs/errors) [![Build Status](https://travis-ci.com/neuronlabs/errors.svg?branch=master)](https://travis-ci.com/neuronlabs/errors) [![Coverage Status](https://coveralls.io/repos/github/neuronlabs/errors/badge.svg?branch=master)](https://coveralls.io/github/neuronlabs/errors?branch=master) ![License](https://img.shields.io/github/license/neuronlabs/errors.svg)
44

5-
Package errors contains simple golang error handling and classification primitives.
5+
Package errors provides simple golang error and classification primitives.
66

77
* [Class](#class)
88
* [Interfaces](#interfaces)
@@ -32,7 +32,7 @@ with the same logic but different messages.
3232
A class might be composed in three different ways:
3333

3434
* Major only - the class is Major singleton.
35-
* Major, Minor only - classes that doesn't need triple subclassification divison.
35+
* Major, Minor only - classes that don't need triple subclassification divison.
3636
* Major, Minor, Index - classes that decomposes
3737

3838
Use `NewMajor` or `MustNewMajor` functions to create `Major`, `NewMinor` or `MustNewMinor` for new `Minor` and `NewIndex` or `MustNewIndex` for new `Index`.
@@ -116,6 +116,7 @@ In order to create detailed error use the `NewDet` or `NewDetf` functions.
116116
import (
117117
"fmt"
118118
"os"
119+
119120
"github.com/neuronlabs/errors"
120121
)
121122

@@ -129,7 +130,7 @@ func init() {
129130
}
130131

131132
func initClasses() {
132-
inputMjr := errors.NewMajor()
133+
inputMjr := errors.MustNewMajor()
133134
invalidValueMnr := errors.MustNewMinor(inputMjr)
134135
ClInputInvalidValue = errors.MustNewMinorClass(inputMjr, invalidValueMnr)
135136

@@ -140,25 +141,27 @@ func initClasses() {
140141

141142
func main() {
142143
input, err := getInput()
143-
if err != nil {
144-
classed, ok := err.(errors.ClassError)
145-
if ok {
146-
if classed.Class() == ClInputNotProvided {
147-
fmt.Println("No required integer arguments provided.")
148-
}
144+
if err == nil {
145+
// Everything is fine.
146+
os.Exit(0)
147+
}
148+
149+
if classed, ok := err.(errors.ClassError); ok {
150+
if classed.Class() == ClInputNotProvided {
151+
fmt.Println("No required integer arguments provided.")
149152
os.Exit(1)
150153
}
154+
}
151155

152-
var details string
153-
detailed, ok := err.(errors.DetailedError)
154-
if ok {
155-
details = detailed.Details()
156-
} else {
157-
details = err.Error()
158-
}
159-
fmt.Printf("Invalid input value provided: '%s'\n", details)
160-
os.Exit(1)
156+
var details string
157+
detailed, ok := err.(errors.DetailedError)
158+
if ok {
159+
details = detailed.Details()
160+
} else {
161+
details = err.Error()
161162
}
163+
fmt.Printf("Invalid input value provided: '%s'\n", details)
164+
os.Exit(1)
162165
}
163166

164167

@@ -202,4 +205,4 @@ func getInput() (int, error) {
202205
## Links
203206

204207
* [Neuron-Core](https://github.com/neuronlabs/neuron-core)
205-
* [Docs](https://docs.neuronlabs.io)
208+
* [Docs](https://docs.neuronlabs.io/errors)

class.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func init() {
1414
}
1515

1616
func initClasses() {
17-
internalMajor := container.newMajor()
17+
internalMajor, _ := container.newMajor()
1818

1919
invalidMajor, _ := container.newMinor(internalMajor)
2020
ClInvalidMajor = MustNewMinorClass(internalMajor, invalidMajor)

class_test.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ import (
66
"testing"
77
)
88

9-
// TestNewSubclass tests creation of the `Major` subclassification.
9+
// TestClass tests creation of the `Major` subclassification.
1010
func TestClass(t *testing.T) {
1111
t.Run("Major", func(t *testing.T) {
1212
resetEmptyContainer()
1313

14-
firstMjr := NewMajor()
14+
firstMjr, err := NewMajor()
15+
require.NoError(t, err)
1516
assert.Equal(t, 1, int(firstMjr))
1617

17-
secondMjr := NewMajor()
18+
var secondMjr Major
19+
assert.NotPanics(t, func() { secondMjr = MustNewMajor() })
1820
assert.Equal(t, 2, int(secondMjr))
1921

2022
firstClass, err := NewMajorClass(firstMjr)
@@ -33,17 +35,28 @@ func TestClass(t *testing.T) {
3335
indexesLen := len(container.indexes)
3436
topMjr := container.major
3537
for i := 0; i < 20; i++ {
36-
NewMajor()
38+
_, err := NewMajor()
39+
require.NoError(t, err)
3740
}
3841
assert.NotEqual(t, minorsLen, len(container.minors))
3942
assert.NotEqual(t, indexesLen, len(container.indexes))
4043
assert.Equal(t, topMjr+20, container.major)
44+
45+
// on testing purpose change top major to max uint8 value.
46+
maxMajor := Major((2 << 7) - 1)
47+
container.major = maxMajor
48+
49+
_, err = NewMajor()
50+
require.Error(t, err)
51+
52+
assert.Panics(t, func() { MustNewMajor() })
4153
})
4254

4355
t.Run("Minor", func(t *testing.T) {
4456
resetEmptyContainer()
4557

46-
mjr := NewMajor()
58+
mjr, err := NewMajor()
59+
require.NoError(t, err)
4760
assert.Equal(t, 1, int(mjr))
4861

4962
mnr1, err := NewMinor(mjr)
@@ -92,12 +105,18 @@ func TestClass(t *testing.T) {
92105

93106
assert.NotEqual(t, initLen, len(container.indexes[mjr]))
94107

108+
container.minors[mjr] = maxMinorValue
109+
_, err = NewMinor(mjr)
110+
require.Error(t, err)
111+
112+
assert.Panics(t, func() { MustNewMinor(mjr) })
95113
})
96114

97115
t.Run("Index", func(t *testing.T) {
98116
resetEmptyContainer()
99117

100-
mjr := NewMajor()
118+
mjr, err := NewMajor()
119+
require.NoError(t, err)
101120
assert.True(t, mjr.Valid())
102121

103122
mnr, err := NewMinor(mjr)
@@ -169,6 +188,12 @@ func TestClass(t *testing.T) {
169188
assert.Error(t, err)
170189

171190
assert.Panics(t, func() { MustNewClassWIndex(invMjr, mnr) })
191+
192+
container.indexes[mjr][mnr] = maxIndexValue
193+
_, err = NewIndex(mjr, mnr)
194+
195+
require.Error(t, err)
196+
assert.Panics(t, func() { MustNewIndex(mjr, mnr) })
172197
})
173198
}
174199

container.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@ type classContainer struct {
1515
indexes [][]Index
1616
}
1717

18-
func (c *classContainer) newMajor() Major {
18+
func (c *classContainer) newMajor() (Major, error) {
1919
c.Lock()
2020
defer c.Unlock()
2121

22+
if c.major+1 == 0 {
23+
return 0, New(ClInvalidMajor, "reached maximum number of 'Major' classes")
24+
}
2225
c.major++
2326

2427
c.resizeMinors(c.major)
2528
c.resizeIndexesMajor(c.major)
26-
return c.major
29+
return c.major, nil
2730
}
2831

2932
func (c *classContainer) newMinor(mjr Major) (Minor, error) {
@@ -36,7 +39,11 @@ func (c *classContainer) newMinor(mjr Major) (Minor, error) {
3639

3740
c.resizeMinors(mjr)
3841

42+
if c.minors[mjr] == maxMinorValue {
43+
return 0, Newf(ClInvalidMinor, "created maximum number of minors for major: '%d'", mjr)
44+
}
3945
c.minors[mjr]++
46+
4047
c.resizeIndexesMinors(mjr, c.minors[mjr])
4148
return c.minors[mjr], nil
4249
}
@@ -56,6 +63,9 @@ func (c *classContainer) newIndex(mjr Major, mnr Minor) (Index, error) {
5663
c.resizeIndexesMajor(mjr)
5764
c.resizeIndexesMinors(mjr, mnr)
5865

66+
if c.indexes[mjr][mnr] == maxIndexValue {
67+
return 0, Newf(ClInvalidIndex, "reached maximum index subclass number for mjr: '%d', mnr: '%d'", mjr, mnr)
68+
}
5969
c.indexes[mjr][mnr]++
6070
return c.indexes[mjr][mnr], nil
6171
}

subclass.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,20 @@ func (m Major) Valid() bool {
1111
}
1212

1313
// NewMajor creates new Major classification.
14-
func NewMajor() Major {
14+
func NewMajor() (Major, error) {
1515
return container.newMajor()
1616
}
1717

18+
// MustNewMajor creates new major error classification.
19+
// Panics if reached maximum number of possible majors.
20+
func MustNewMajor() Major {
21+
mjr, err := container.newMajor()
22+
if err != nil {
23+
panic(err)
24+
}
25+
return mjr
26+
}
27+
1828
// Minor is mid level error subclassification.
1929
// It is a 10 bit long value, which give 2^10 - 1024 - combinations
2030
// for each major.

0 commit comments

Comments
 (0)