brief 0.0.5 → 1.0.0

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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +71 -55
  4. data/README.md +149 -48
  5. data/Rakefile +15 -5
  6. data/bin/brief +15 -28
  7. data/brief.gemspec +17 -11
  8. data/examples/blog/brief.rb +54 -0
  9. data/examples/blog/docs/an-intro-to-brief.html.md +9 -0
  10. data/lib/.DS_Store +0 -0
  11. data/lib/brief/briefcase.rb +78 -0
  12. data/lib/brief/cli/change.rb +14 -0
  13. data/lib/brief/cli/init.rb +66 -0
  14. data/{spec/fixtures/generated/project_overview.json → lib/brief/cli/publish.rb} +0 -0
  15. data/lib/brief/cli/write.rb +0 -0
  16. data/lib/brief/configuration.rb +19 -115
  17. data/lib/brief/core_ext.rb +11 -0
  18. data/lib/brief/document/content_extractor.rb +33 -0
  19. data/lib/brief/document/front_matter.rb +20 -0
  20. data/lib/brief/document/rendering.rb +37 -0
  21. data/lib/brief/document.rb +43 -38
  22. data/lib/brief/document_mapper.rb +158 -0
  23. data/lib/brief/dsl.rb +42 -0
  24. data/lib/brief/model/definition.rb +117 -0
  25. data/lib/brief/model.rb +177 -0
  26. data/lib/brief/repository.rb +57 -0
  27. data/lib/brief/version.rb +1 -7
  28. data/lib/brief.rb +35 -40
  29. data/spec/fixtures/example/brief.rb +27 -0
  30. data/spec/fixtures/example/docs/concept.html.md +5 -0
  31. data/spec/fixtures/example/docs/epic.html.md +19 -0
  32. data/spec/fixtures/example/docs/persona.html.md +5 -0
  33. data/spec/fixtures/example/docs/release.html.md +7 -0
  34. data/spec/fixtures/example/docs/resource.html.md +5 -0
  35. data/spec/fixtures/example/docs/user_story.html.md +24 -0
  36. data/spec/fixtures/example/docs/wireframe.html.md +5 -0
  37. data/spec/fixtures/example/models/epic.rb +16 -0
  38. data/spec/lib/brief/briefcase_spec.rb +27 -0
  39. data/spec/lib/brief/document_spec.rb +14 -22
  40. data/spec/lib/brief/dsl_spec.rb +4 -15
  41. data/spec/lib/brief/model_spec.rb +84 -0
  42. data/spec/lib/brief/repository_spec.rb +60 -0
  43. data/spec/spec_helper.rb +12 -14
  44. data/spec/support/test_helpers.rb +0 -0
  45. data/tasks/brief/release.rake +0 -0
  46. metadata +120 -110
  47. data/.gitignore +0 -1
  48. data/Guardfile +0 -5
  49. data/examples/project_overview.md +0 -23
  50. data/lib/brief/cli/commands/config.rb +0 -40
  51. data/lib/brief/cli/commands/publish.rb +0 -27
  52. data/lib/brief/cli/commands/write.rb +0 -27
  53. data/lib/brief/formatters/base.rb +0 -12
  54. data/lib/brief/formatters/github_milestone_rollup.rb +0 -52
  55. data/lib/brief/git.rb +0 -19
  56. data/lib/brief/github/wiki.rb +0 -9
  57. data/lib/brief/github.rb +0 -141
  58. data/lib/brief/github_client/authentication.rb +0 -32
  59. data/lib/brief/github_client/client.rb +0 -86
  60. data/lib/brief/github_client/commands.rb +0 -5
  61. data/lib/brief/github_client/issue_labels.rb +0 -65
  62. data/lib/brief/github_client/issues.rb +0 -22
  63. data/lib/brief/github_client/milestone_issues.rb +0 -13
  64. data/lib/brief/github_client/organization_activity.rb +0 -9
  65. data/lib/brief/github_client/organization_issues.rb +0 -13
  66. data/lib/brief/github_client/organization_repositories.rb +0 -20
  67. data/lib/brief/github_client/organization_users.rb +0 -9
  68. data/lib/brief/github_client/repository_events.rb +0 -8
  69. data/lib/brief/github_client/repository_issue_events.rb +0 -9
  70. data/lib/brief/github_client/repository_issues.rb +0 -8
  71. data/lib/brief/github_client/repository_labels.rb +0 -18
  72. data/lib/brief/github_client/repository_milestones.rb +0 -9
  73. data/lib/brief/github_client/request.rb +0 -181
  74. data/lib/brief/github_client/request_wrapper.rb +0 -121
  75. data/lib/brief/github_client/response_object.rb +0 -50
  76. data/lib/brief/github_client/single_repository.rb +0 -9
  77. data/lib/brief/github_client/user_activity.rb +0 -16
  78. data/lib/brief/github_client/user_gists.rb +0 -9
  79. data/lib/brief/github_client/user_info.rb +0 -9
  80. data/lib/brief/github_client/user_issues.rb +0 -13
  81. data/lib/brief/github_client/user_organizations.rb +0 -9
  82. data/lib/brief/github_client/user_repositories.rb +0 -9
  83. data/lib/brief/github_client.rb +0 -43
  84. data/lib/brief/handlers/base.rb +0 -62
  85. data/lib/brief/handlers/github_issue.rb +0 -41
  86. data/lib/brief/handlers/github_milestone.rb +0 -37
  87. data/lib/brief/handlers/github_wiki.rb +0 -11
  88. data/lib/brief/line.rb +0 -69
  89. data/lib/brief/parser.rb +0 -354
  90. data/lib/brief/publisher/handler_manager.rb +0 -47
  91. data/lib/brief/publisher.rb +0 -142
  92. data/lib/brief/tree.rb +0 -43
  93. data/lib/core_ext.rb +0 -37
  94. data/spec/fixtures/front_end_tutorial.md +0 -33
  95. data/spec/fixtures/generator_dsl_example.rb +0 -22
  96. data/spec/fixtures/project_overview.md +0 -48
  97. data/spec/fixtures/sample.md +0 -19
  98. data/spec/lib/brief/line_spec.rb +0 -11
  99. data/spec/lib/brief/parser_spec.rb +0 -12
@@ -0,0 +1,117 @@
1
+ module Brief
2
+ class Model::Definition
3
+ attr_accessor :type_alias,
4
+ :name,
5
+ :metadata_schema,
6
+ :content_schema,
7
+ :options,
8
+ :defined_helpers
9
+
10
+ def initialize(name, options={})
11
+ @name = name
12
+ @options = options
13
+ @type_alias = options.fetch(:type_alias) { name.downcase.parameterize.gsub(/-/,'_') }
14
+ @metadata_schema = {}.to_mash
15
+ @content_schema = {attributes:{}}.to_mash
16
+ @model_class = options[:model_class]
17
+ end
18
+
19
+ def valid?
20
+ name.to_s.length > 0 && type_alias.to_s.length > 0
21
+ end
22
+
23
+ def validate!
24
+ definition = self
25
+
26
+ if valid?
27
+ create_model_class.tap do |k|
28
+ k.send(:include, Brief::Model)
29
+
30
+ k.definition = definition
31
+
32
+ k.name ||= name
33
+ k.type_alias ||= type_alias
34
+
35
+ Brief::Model.classes << k
36
+ end
37
+
38
+ apply_config
39
+ end
40
+ end
41
+
42
+ def apply_config
43
+ metadata_schema.values.each do |settings|
44
+ if model_class.nil?
45
+ binding.pry
46
+ end
47
+
48
+ model_class.send(:attribute, *(settings[:args]))
49
+ end
50
+
51
+ Array(self.defined_helpers).each do |mod|
52
+ model_class.send(:include, mod)
53
+ end
54
+ end
55
+
56
+ def create_model_class
57
+ model_namespace.const_set(type_alias.camelize, Class.new) unless model_class
58
+ end
59
+
60
+ def model_class
61
+ @model_class || model_namespace.const_get(type_alias.camelize) rescue nil
62
+ end
63
+
64
+ def model_namespace
65
+ Brief.configuration.model_namespace || Brief::Model
66
+ end
67
+
68
+ def meta(options={}, &block)
69
+ @current = :meta
70
+ instance_eval(&block)
71
+ end
72
+
73
+ def content(options={}, &block)
74
+ @current = :content
75
+ instance_eval(&block)
76
+ end
77
+
78
+ def helpers(&block)
79
+ self.defined_helpers ||= []
80
+
81
+ if block
82
+ mod = Module.new
83
+ mod.module_eval(&block)
84
+
85
+ self.defined_helpers << mod
86
+ end
87
+ end
88
+
89
+ def inside_meta?
90
+ @current == :meta
91
+ end
92
+
93
+ def inside_content?
94
+ @current == :content
95
+ end
96
+
97
+ def method_missing(meth, *args, &block)
98
+ args = args.dup
99
+
100
+ if inside_content?
101
+ if meth.to_s == :define_section
102
+
103
+ end
104
+
105
+ self.content_schema.attributes[meth] = {args: args, block: block}
106
+ elsif inside_meta?
107
+ if args.first.is_a?(Hash)
108
+ args.unshift(String)
109
+ end
110
+ args.unshift(meth)
111
+ self.metadata_schema[meth] = {args: args, block: block}
112
+ else
113
+ super
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,177 @@
1
+ module Brief
2
+ module Model
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ unless defined?(Virtus)
7
+ require 'inflecto'
8
+ require 'virtus'
9
+ end
10
+
11
+ include Virtus.model(finalize: false)
12
+ include Initializers
13
+ include AccessorMethods
14
+ include Persistence
15
+
16
+ class_attribute :models, :after_initialization_hooks, :defined_helpers
17
+
18
+ self.models = Array(self.models).to_set
19
+
20
+ class << self
21
+ include Enumerable
22
+ end
23
+
24
+ attribute :path, Pathname
25
+ attribute :document, Brief::Document
26
+
27
+ Brief::Model.classes << self
28
+ end
29
+
30
+ module AccessorMethods
31
+ def data
32
+ document.data
33
+ end
34
+
35
+ def content
36
+ document.content
37
+ end
38
+
39
+ def extracted
40
+ @extracted ||= Brief::Document::ContentExtractor.new(self.class.type_alias, document)
41
+ end
42
+
43
+ def method_missing(meth, *args, &block)
44
+ if args.empty?
45
+ if document.respond_to?(meth)
46
+ document.send(meth)
47
+ else
48
+ document.data.key?(meth) ? data[meth] : extracted.send(meth)
49
+ end
50
+ else
51
+ super
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.classes
57
+ @classes ||= Set.new
58
+ end
59
+
60
+ def self.table
61
+ classes.inject({}.to_mash) do |memo, klass|
62
+ memo.tap { memo[klass.type_alias] = klass }
63
+ end
64
+ end
65
+
66
+ def self.for_type(type_alias)
67
+ table[type_alias]
68
+ end
69
+
70
+ def self.finalize
71
+ Virtus.finalize
72
+
73
+ classes.each do |klass|
74
+ klass.name ||= klass.to_s.split('::').last.humanize
75
+ klass.type_alias ||= klass.name.parameterize.gsub(/-/,'_')
76
+
77
+ klass.attribute_set.map(&:name).each do |attr|
78
+ klass.define_singleton_method("find_by_#{ attr }") do |value|
79
+ where(attr => value).first
80
+ end
81
+ end
82
+
83
+ klass.definition.apply_config
84
+ end
85
+
86
+ Brief::Repository.define_document_finder_methods
87
+ end
88
+
89
+ def ==(other)
90
+ self.path == other.path
91
+ end
92
+
93
+ def extract_content(options={})
94
+ document.extract_content(options)
95
+ end
96
+
97
+ module ClassMethods
98
+ def where(*args, &block)
99
+ Brief::DocumentMapper::Query.new(self).send(:where, *args)
100
+ end
101
+
102
+ def each(*args, &block)
103
+ Array(self.models).send(:each, *args, &block)
104
+ end
105
+
106
+ def meta(options={}, &block)
107
+ definition.send(:meta, options, &block)
108
+ end
109
+
110
+ def content(options={}, &block)
111
+ definition.send(:content, options, &block)
112
+ end
113
+
114
+ def actions(&block)
115
+ definition.send(:helpers, &block)
116
+ end
117
+
118
+ def after_initialize(&block)
119
+ (self.after_initialization_hooks ||= []).push(block)
120
+ end
121
+
122
+ def name=(value)
123
+ @name = value
124
+ end
125
+
126
+ def name
127
+ @name || to_s.split('::').last.underscore.gsub('_',' ').titlecase
128
+ end
129
+
130
+ def type_alias=(value)
131
+ @type_alias = value
132
+ end
133
+
134
+ def type_alias
135
+ @type_alias || name.parameterize.gsub(/-/,'_')
136
+ end
137
+
138
+ def definition
139
+ @definition ||= Brief::Model::Definition.new(name, type_alias: type_alias, model_class: self)
140
+ end
141
+
142
+ def definition=(value)
143
+ @definition
144
+ end
145
+
146
+ def method_missing(meth, *args, &block)
147
+ if meth.to_s.match(/^on_(.*)_change$/)
148
+ create_change_handler($1, *args, &block)
149
+ else
150
+ super
151
+ end
152
+ end
153
+
154
+ def create_change_handler(attribute, *args, &block)
155
+ block.call(self)
156
+ end
157
+ end
158
+
159
+ module Initializers
160
+ def set_default_attributes
161
+ attribute_set.set_defaults(self)
162
+ send(:after_initialize) if respond_to?(:after_initialize)
163
+ self
164
+ end
165
+
166
+ def after_initialize
167
+ Array(self.class.after_initialization_hooks).each do |hook|
168
+ hook.call(self)
169
+ end
170
+ end
171
+
172
+ def set_slug_from(column=:name)
173
+ self.slug = send(column).to_s.downcase.parameterize if self.slug.to_s.length == 0
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,57 @@
1
+ module Brief
2
+ class Repository
3
+ attr_reader :briefcase, :options
4
+
5
+ include Enumerable
6
+
7
+ # should compare vs yield
8
+ def each(*args, &block)
9
+ documents.send(:each, *args, &block)
10
+ end
11
+
12
+ def initialize(briefcase, options={})
13
+ @briefcase = briefcase
14
+ @options = options
15
+
16
+ load_documents
17
+ end
18
+
19
+ def documents
20
+ return @documents if @documents
21
+ load_documents
22
+ end
23
+
24
+ def where(*args)
25
+ Brief::DocumentMapper::Query.new(self).send(:where, *args)
26
+ end
27
+
28
+ def order_by(*args)
29
+ Brief::DocumentMapper::Query.new(self).send(:order_by, *args)
30
+ end
31
+
32
+ def root
33
+ briefcase.root
34
+ end
35
+
36
+ def load_documents
37
+ @documents = document_paths.map do |path|
38
+ Brief::Document.new(path)
39
+ end
40
+ end
41
+
42
+ def document_paths
43
+ Dir[root.join("**/*.md").to_s]
44
+ end
45
+
46
+ def self.define_document_finder_methods
47
+ # Create a finder method on the repository
48
+ # which lets us find instances of models by their class name
49
+ Brief::Model.table.keys.each do |type|
50
+ define_method(type.to_s.pluralize) do
51
+ Brief::Model.for_type(type).models.to_a
52
+ end
53
+ end
54
+ end
55
+
56
+ end
57
+ end
data/lib/brief/version.rb CHANGED
@@ -1,9 +1,3 @@
1
1
  module Brief
2
- MAJOR = 0
3
- MINOR = 0
4
- REVISION = 1
5
-
6
- Version = "#{ MAJOR }.#{ MINOR }.#{ REVISION }"
7
-
8
- VERSION = Version
2
+ VERSION = "1.0.0"
9
3
  end
data/lib/brief.rb CHANGED
@@ -1,56 +1,51 @@
1
- lib = File.dirname(__FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
1
+ require "pathname"
2
+ require "set"
3
+ require "hashie"
4
+ require "virtus"
5
+ require "inflecto"
6
+ require "active_support"
7
+ require "active_support/core_ext"
8
+ require "redcarpet"
9
+ require "nokogiri"
10
+ require "yaml"
3
11
 
4
12
  module Brief
5
- # Haven't decided if the brief config system should support different profiles or not
6
- def self.profile
7
- configuration
13
+ def self.case= value
14
+ @briefcase = value
8
15
  end
9
16
 
10
- def self.config
11
- configuration
17
+ def self.case
18
+ @briefcase
12
19
  end
13
20
 
14
21
  def self.configuration
15
- @configuration ||= Brief::Configuration.instance
16
- end
17
-
18
- def self.root
19
- Pathname(Dir.pwd())
22
+ Brief::Configuration.instance
20
23
  end
21
24
 
22
25
  def self.gem_root
23
26
  Pathname(File.dirname(__FILE__))
24
27
  end
25
28
 
26
- def self.define publisher_name, &config
27
- Brief::Publisher.define(publisher_name, &config)
29
+ def self.load_commands
30
+ Dir[gem_root.join("brief","cli","**/*.rb")].each {|f| require(f) }
28
31
  end
29
- end
30
-
31
- require 'pathname'
32
- require 'hashie'
33
- require 'digest'
34
- require 'yaml'
35
32
 
36
- require 'active_support'
37
- require 'active_support/core_ext'
38
-
39
- require 'brief/line'
40
- require 'brief/parser'
41
- require 'brief/document'
42
- require 'brief/tree'
43
- require 'brief/version'
44
- require 'brief/configuration'
45
-
46
- require 'brief/publisher'
47
- require 'brief/publisher/handler_manager'
48
- # These should be able to be loaded separately
49
- # some other way, but to help develoment..
50
- require 'brief/handlers/base'
51
- require 'brief/formatters/base'
33
+ def self.load_models(from_folder=nil)
34
+ Brief::Model.load_all(from_folder: from_folder)
35
+ end
36
+ end
52
37
 
53
- # these may be optional one day
54
- require 'brief/github'
55
- require 'brief/git'
56
- require 'brief/github/wiki'
38
+ require "brief/core_ext"
39
+ require "brief/version"
40
+ require "brief/configuration"
41
+ require "brief/document/rendering"
42
+ require "brief/document/front_matter"
43
+ require "brief/document/content_extractor"
44
+ require "brief/document"
45
+ require "brief/document_mapper"
46
+ require "brief/repository"
47
+ require "brief/model"
48
+ require "brief/model/definition"
49
+ require "brief/model/persistence"
50
+ require "brief/dsl"
51
+ require "brief/briefcase"
@@ -0,0 +1,27 @@
1
+ config do
2
+ set(:models => Pathname(File.dirname(__FILE__)).join("models"))
3
+ end
4
+
5
+ define "User Story" do
6
+ meta do
7
+ title
8
+ status :in => %w(draft published)
9
+ epic_title
10
+ end
11
+
12
+ content do
13
+ persona "p strong:first-child"
14
+ behavior "p strong:second-child"
15
+ goal "p strong:third-child"
16
+ end
17
+
18
+ helpers do
19
+ def defined_helper_method
20
+ true
21
+ end
22
+ end
23
+ end
24
+
25
+ action "custom command" do
26
+ $custom_command = true
27
+ end
@@ -0,0 +1,5 @@
1
+ ---
2
+ type: concept
3
+ title: Blueprint Concept Example
4
+ subheading: A key concept to the domain model
5
+ ---
@@ -0,0 +1,19 @@
1
+ ---
2
+ type: epic
3
+ title: Blueprint Epic Example
4
+ subheading: An example of an Epic
5
+ state: active
6
+ ---
7
+
8
+ # Blueprint Epic Example
9
+
10
+ This is an example of an Epic Document. An Epic is a single document
11
+ which contains user stories and such.
12
+
13
+ # User Stories
14
+
15
+ ## A user wants to write epics
16
+
17
+ ## A user wants to annotate wireframes
18
+
19
+ ## A user wants to provide details about domain concepts
@@ -0,0 +1,5 @@
1
+ ---
2
+ type: persona
3
+ title: Blueprint Persona Example
4
+ subheading: A description of a typical user of the software
5
+ ---
@@ -0,0 +1,7 @@
1
+ ---
2
+ type: release
3
+ title: Blueprint Release Example
4
+ subheading: A release milestone for the software
5
+ status: Planned
6
+ date: 2018-12-18
7
+ ---
@@ -0,0 +1,5 @@
1
+ ---
2
+ type: resource
3
+ title: Blueprint Example Resource
4
+ subheading: An example API Resource document
5
+ ---
@@ -0,0 +1,24 @@
1
+ ---
2
+ type: user_story
3
+ title: Blueprint User Story Example
4
+ subheading: A way of describing desired behavior of the software, from the perspective of a persona who has a goal
5
+ epic: Blueprint Epic Example
6
+ release: Blueprint Release Example
7
+ state: active
8
+ title: A Blueprint Persona Example wants this behavior
9
+ ---
10
+
11
+ As a **Blueprint Persona Example** I would like to **do this certain thing in the software** so that I can **accomplish this goal**
12
+
13
+ #### Wireframes
14
+
15
+ - Blueprint Wireframe Example
16
+
17
+ #### Concepts
18
+
19
+ - Blueprint Concept Example
20
+
21
+ #### Resources
22
+
23
+ - Blueprint Example Resource
24
+
@@ -0,0 +1,5 @@
1
+ ---
2
+ type: wireframe
3
+ title: Blueprint Wireframe Example
4
+ subheading: A key concept to the domain model
5
+ ---
@@ -0,0 +1,16 @@
1
+ class Brief::Epic
2
+ include Brief::Model
3
+
4
+ meta do
5
+ title String
6
+ status String, :in => %w(draft published)
7
+ end
8
+
9
+ content do
10
+ title "h1:first-child"
11
+
12
+ define_section "User Stories" do
13
+ has_many :user_stories, "h2" => "title", "p:first-child" => "paragraph"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe "The Briefcase" do
4
+ let(:briefcase) { Brief.example }
5
+
6
+ it "has a root path" do
7
+ expect(briefcase.root).to be_exist
8
+ end
9
+
10
+ it "points to a file repository" do
11
+ expect(briefcase.repository).to be_a(Brief::Repository)
12
+ end
13
+
14
+ context "Model Loading" do
15
+ it "loads the model definitions from the models folder" do
16
+ end
17
+
18
+ it "loads the model definitions from the DSL in the config file" do
19
+ end
20
+ end
21
+
22
+ context "Document Mappings" do
23
+ it "has all of the documents" do
24
+
25
+ end
26
+ end
27
+ end
@@ -1,35 +1,27 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Brief::Document do
4
- let(:path) { Brief.fixtures.join("sample.md") }
5
-
6
- let(:tutorial) do
7
- Brief::Document.new(path: path)
3
+ describe "The Brief Document" do
4
+ let(:sample) do
5
+ path = Brief.example_path.join("docs","epic.html.md")
6
+ Brief::Document.new(path)
8
7
  end
9
8
 
10
- it "should let me pass raw markdown" do
11
- level_one = Brief::Document.new(path.read).tree.level(1)
12
- expect(level_one.first.title).to eq("Heading One")
9
+ it "renders html" do
10
+ expect(sample.to_html).to include("<h1>User Stories</h1>")
13
11
  end
14
12
 
15
- it "should let me pass a markdown file" do
16
- level_one = Brief::Document.new(path).tree.level(1)
17
- expect(level_one.first.title).to eq("Heading One")
13
+ it "parses the html" do
14
+ expect(sample.css("h1").length).to eq(2)
18
15
  end
19
16
 
20
- describe "Parsers and Publishers" do
21
- it "should have a parser" do
22
- expect(tutorial.parser).not_to be_nil
23
- end
24
-
25
- it "should have a publisher" do
26
- expect(tutorial.publisher).not_to be_nil
27
- end
17
+ it "deserializes YAML frontmatter into attributes" do
18
+ expect(sample.frontmatter.type).to eq("epic")
28
19
  end
29
20
 
30
- describe "Finding code blocks by language" do
31
- it "should find the blocks of code and group them by their language" do
32
- expect(tutorial.code_blocks_by_language).not_to be_empty
21
+ context "Content Extraction" do
22
+ it "extracts content from a css selector" do
23
+ extracted = sample.extract_content(:args => ["h1:first-child"])
24
+ expect(extracted).to eq("Blueprint Epic Example")
33
25
  end
34
26
  end
35
27
  end
@@ -1,21 +1,10 @@
1
1
  require "spec_helper"
2
2
 
3
- describe "The Publisher definition DSL" do
4
- before(:all) do
5
- require Brief.fixtures.join("generator_dsl_example.rb")
6
- end
7
-
8
- it "should define a generator called Project Overview" do
9
- expect(Brief::Publisher.fetch("Project Overview")).to be_present
10
- end
11
3
 
12
- it "should find the appropriate Publisher by using an alias" do
13
- expect(Brief::Publisher.fetch("project_overview")).to be_present
14
- end
4
+ describe "The Configuration DSL" do
5
+ let(:briefcase) { Brief.example }
15
6
 
16
- it "should find the appropriate Publisher using a case insensitve search" do
17
- expect(Brief::Publisher.fetch("project overview")).to be_present
7
+ it "can create methods on our models" do
8
+ expect(briefcase.user_stories.first.defined_helper_method).to eq(true)
18
9
  end
19
-
20
-
21
10
  end